1 | /* |
2 | * Copyright (c) 2019 Alexey Dobriyan <adobriyan@gmail.com> |
3 | * |
4 | * Permission to use, copy, modify, and distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above |
6 | * copyright notice and this permission notice appear in all copies. |
7 | * |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ |
16 | /* Test that open(O_TMPFILE), linkat() doesn't screw accounting. */ |
17 | #include <errno.h> |
18 | #include <sched.h> |
19 | #include <stdio.h> |
20 | #include <sys/types.h> |
21 | #include <sys/stat.h> |
22 | #include <fcntl.h> |
23 | #include <sys/mount.h> |
24 | #include <unistd.h> |
25 | |
26 | int main(void) |
27 | { |
28 | int fd; |
29 | |
30 | if (unshare(CLONE_NEWNS) == -1) { |
31 | if (errno == ENOSYS || errno == EPERM) { |
32 | fprintf(stderr, "error: unshare, errno %d\n" , errno); |
33 | return 4; |
34 | } |
35 | fprintf(stderr, "error: unshare, errno %d\n" , errno); |
36 | return 1; |
37 | } |
38 | if (mount(NULL, "/" , NULL, MS_PRIVATE|MS_REC, NULL) == -1) { |
39 | fprintf(stderr, "error: mount '/', errno %d\n" , errno); |
40 | return 1; |
41 | } |
42 | |
43 | /* Our heroes: 1 root inode, 1 O_TMPFILE inode, 1 permanent inode. */ |
44 | if (mount(NULL, "/tmp" , "tmpfs" , 0, "nr_inodes=3" ) == -1) { |
45 | fprintf(stderr, "error: mount tmpfs, errno %d\n" , errno); |
46 | return 1; |
47 | } |
48 | |
49 | fd = openat(AT_FDCWD, "/tmp" , O_WRONLY|O_TMPFILE, 0600); |
50 | if (fd == -1) { |
51 | fprintf(stderr, "error: open 1, errno %d\n" , errno); |
52 | return 1; |
53 | } |
54 | if (linkat(fd, "" , AT_FDCWD, "/tmp/1" , AT_EMPTY_PATH) == -1) { |
55 | fprintf(stderr, "error: linkat, errno %d\n" , errno); |
56 | return 1; |
57 | } |
58 | close(fd); |
59 | |
60 | fd = openat(AT_FDCWD, "/tmp" , O_WRONLY|O_TMPFILE, 0600); |
61 | if (fd == -1) { |
62 | fprintf(stderr, "error: open 2, errno %d\n" , errno); |
63 | return 1; |
64 | } |
65 | |
66 | return 0; |
67 | } |
68 | |