btrfs: test btrfs filesystem usage command on missing seed device
[xfstests-dev.git] / src / idmapped-mounts / utils.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #ifndef __IDMAP_UTILS_H
4 #define __IDMAP_UTILS_H
5
6 #ifndef _GNU_SOURCE
7 #define _GNU_SOURCE
8 #endif
9 #include <errno.h>
10 #include <linux/types.h>
11 #include <sched.h>
12 #include <signal.h>
13 #include <stdbool.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <syscall.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20
21 #include "missing.h"
22
23 /* Maximum number of nested user namespaces in the kernel. */
24 #define MAX_USERNS_LEVEL 32
25
26 /* A few helpful macros. */
27 #define STRLITERALLEN(x) (sizeof(""x"") - 1)
28
29 #define INTTYPE_TO_STRLEN(type)             \
30         (2 + (sizeof(type) <= 1             \
31                   ? 3                       \
32                   : sizeof(type) <= 2       \
33                         ? 5                 \
34                         : sizeof(type) <= 4 \
35                               ? 10          \
36                               : sizeof(type) <= 8 ? 20 : sizeof(int[-2 * (sizeof(type) > 8)])))
37
38 #define syserror(format, ...)                           \
39         ({                                              \
40                 fprintf(stderr, "%m - " format "\n", ##__VA_ARGS__); \
41                 (-errno);                               \
42         })
43
44 #define syserror_set(__ret__, format, ...)                    \
45         ({                                                    \
46                 typeof(__ret__) __internal_ret__ = (__ret__); \
47                 errno = labs(__ret__);                        \
48                 fprintf(stderr, "%m - " format "\n", ##__VA_ARGS__);       \
49                 __internal_ret__;                             \
50         })
51
52 typedef enum idmap_type_t {
53         ID_TYPE_UID,
54         ID_TYPE_GID
55 } idmap_type_t;
56
57 struct id_map {
58         idmap_type_t map_type;
59         __u32 nsid;
60         __u32 hostid;
61         __u32 range;
62 };
63
64 struct list {
65         void *elem;
66         struct list *next;
67         struct list *prev;
68 };
69
70 struct userns_hierarchy {
71         int fd_userns;
72         int fd_event;
73         unsigned int level;
74         struct list id_map;
75 };
76
77 #define list_for_each(__iterator, __list) \
78         for (__iterator = (__list)->next; __iterator != __list; __iterator = __iterator->next)
79
80 #define list_for_each_safe(__iterator, __list, __next)               \
81         for (__iterator = (__list)->next, __next = __iterator->next; \
82              __iterator != __list; __iterator = __next, __next = __next->next)
83
84 static inline void list_init(struct list *list)
85 {
86         list->elem = NULL;
87         list->next = list->prev = list;
88 }
89
90 static inline int list_empty(const struct list *list)
91 {
92         return list == list->next;
93 }
94
95 static inline void __list_add(struct list *new, struct list *prev, struct list *next)
96 {
97         next->prev = new;
98         new->next = next;
99         new->prev = prev;
100         prev->next = new;
101 }
102
103 static inline void list_add_tail(struct list *head, struct list *list)
104 {
105         __list_add(list, head->prev, head);
106 }
107
108 static inline void list_del(struct list *list)
109 {
110         struct list *next, *prev;
111
112         next = list->next;
113         prev = list->prev;
114         next->prev = prev;
115         prev->next = next;
116 }
117
118 extern pid_t do_clone(int (*fn)(void *), void *arg, int flags);
119 extern int get_userns_fd(unsigned long nsid, unsigned long hostid,
120                          unsigned long range);
121 extern int get_userns_fd_from_idmap(struct list *idmap);
122 extern ssize_t read_nointr(int fd, void *buf, size_t count);
123 extern int wait_for_pid(pid_t pid);
124 extern ssize_t write_nointr(int fd, const void *buf, size_t count);
125 extern bool switch_ids(uid_t uid, gid_t gid);
126 extern int create_userns_hierarchy(struct userns_hierarchy *h);
127 extern int add_map_entry(struct list *head, __u32 id_host, __u32 id_ns,
128                          __u32 range, idmap_type_t map_type);
129
130 #endif /* __IDMAP_UTILS_H */