Branch data Line data Source code
1 : : #ifndef __CR_UTIL_H__
2 : : #define __CR_UTIL_H__
3 : :
4 : : /*
5 : : * Some bits are stolen from perf and kvm tools
6 : : */
7 : : #include <signal.h>
8 : : #include <stdio.h>
9 : : #include <errno.h>
10 : : #include <string.h>
11 : : #include <sys/types.h>
12 : : #include <sys/statfs.h>
13 : : #include <dirent.h>
14 : :
15 : : #include "compiler.h"
16 : : #include "types.h"
17 : : #include "log.h"
18 : :
19 : : #include "../protobuf/vma.pb-c.h"
20 : :
21 : : #define PREF_SHIFT_OP(pref, op, size) ((size) op (pref ##BYTES_SHIFT))
22 : : #define KBYTES_SHIFT 10
23 : : #define MBYTES_SHIFT 20
24 : : #define GBYTES_SHIFT 30
25 : :
26 : : #define KBYTES(size) PREF_SHIFT_OP(K, >>, size)
27 : : #define MBYTES(size) PREF_SHIFT_OP(M, >>, size)
28 : : #define GBYTES(size) PREF_SHIFT_OP(G, >>, size)
29 : :
30 : : #define KILO(size) PREF_SHIFT_OP(K, <<, size)
31 : : #define MEGA(size) PREF_SHIFT_OP(K, <<, size)
32 : : #define GIGA(size) PREF_SHIFT_OP(K, <<, size)
33 : :
34 : : #ifndef BUG_ON_HANDLER
35 : :
36 : : #ifdef CR_NOGLIBC
37 : :
38 : : #define BUG_ON_HANDLER(condition) \
39 : : do { \
40 : : if ((condition)) { \
41 : : pr_err("BUG at %s:%d\n", __FILE__, __LINE__); \
42 : : *(volatile unsigned long *)NULL = 0xdead0000 + __LINE__; \
43 : : } \
44 : : } while (0)
45 : :
46 : : #else /* CR_NOGLIBC */
47 : :
48 : : # define BUG_ON_HANDLER(condition) \
49 : : do { \
50 : : if ((condition)) { \
51 : : pr_err("BUG at %s:%d\n", __FILE__, __LINE__); \
52 : : raise(SIGABRT); \
53 : : *(volatile unsigned long *)NULL = 0xdead0000 + __LINE__; \
54 : : } \
55 : : } while (0)
56 : :
57 : : #endif /* CR_NOGLIBC */
58 : :
59 : : #endif /* BUG_ON_HANDLER */
60 : :
61 : : #define BUG_ON(condition) BUG_ON_HANDLER((condition))
62 : : #define BUG() BUG_ON(true)
63 : :
64 : : /*
65 : : * Write buffer @ptr of @size bytes into @fd file
66 : : * Returns
67 : : * 0 on success
68 : : * -1 on error (error message is printed)
69 : : */
70 : 8140 : static inline int write_img_buf(int fd, const void *ptr, int size)
71 : : {
72 : : int ret;
73 : 8140 : ret = write(fd, ptr, size);
74 [ - + ]: 8140 : if (ret == size)
75 : : return 0;
76 : :
77 [ # # ]: 0 : if (ret < 0)
78 : 0 : pr_perror("Can't write img file");
79 : : else
80 : 8140 : pr_err("Img trimmed %d/%d\n", ret, size);
81 : : return -1;
82 : : }
83 : :
84 : : #define write_img(fd, ptr) write_img_buf((fd), (ptr), sizeof(*(ptr)))
85 : :
86 : : /*
87 : : * Read buffer @ptr of @size bytes from @fd file
88 : : * Returns
89 : : * 1 on success
90 : : * 0 on EOF (silently)
91 : : * -1 on error (error message is printed)
92 : : */
93 : 15008 : static inline int read_img_buf_eof(int fd, void *ptr, int size)
94 : : {
95 : : int ret;
96 : 15008 : ret = read(fd, ptr, size);
97 [ + + ]: 15008 : if (ret == size)
98 : : return 1;
99 [ - + ]: 19 : if (ret == 0)
100 : : return 0;
101 : :
102 [ # # ]: 0 : if (ret < 0)
103 : 0 : pr_perror("Can't read img file");
104 : : else
105 : 15008 : pr_err("Img trimmed %d/%d\n", ret, size);
106 : : return -1;
107 : : }
108 : :
109 : : #define read_img_eof(fd, ptr) read_img_buf_eof((fd), (ptr), sizeof(*(ptr)))
110 : :
111 : : /*
112 : : * Read buffer @ptr of @size bytes from @fd file
113 : : * Returns
114 : : * 1 on success
115 : : * -1 on error or EOF (error message is printed)
116 : : */
117 : 14968 : static inline int read_img_buf(int fd, void *ptr, int size)
118 : : {
119 : : int ret;
120 : :
121 : 14968 : ret = read_img_buf_eof(fd, ptr, size);
122 [ - + ]: 14968 : if (ret == 0) {
123 : 0 : pr_err("Unexpected EOF\n");
124 : 0 : ret = -1;
125 : : }
126 : :
127 : 14968 : return ret;
128 : : }
129 : :
130 : : #define read_img(fd, ptr) read_img_buf((fd), (ptr), sizeof(*(ptr)))
131 : :
132 : : #define memzero_p(p) memset(p, 0, sizeof(*p))
133 : : #define memzero(p, size) memset(p, 0, size)
134 : :
135 : : struct vma_area;
136 : : struct list_head;
137 : :
138 : : extern void pr_vma(unsigned int loglevel, const struct vma_area *vma_area);
139 : :
140 : : #define pr_info_vma(vma_area) pr_vma(LOG_INFO, vma_area)
141 : : #define pr_msg_vma(vma_area) pr_vma(LOG_MSG, vma_area)
142 : :
143 : : #define pr_vma_list(level, head) \
144 : : do { \
145 : : struct vma_area *vma; \
146 : : list_for_each_entry(vma, head, list) \
147 : : pr_vma(level, vma); \
148 : : } while (0)
149 : : #define pr_info_vma_list(head) pr_vma_list(LOG_INFO, head)
150 : :
151 : : /*
152 : : * Note since VMA_AREA_NONE = 0 we can skip assignment
153 : : * here and simply rely on xzalloc
154 : : */
155 : : #define alloc_vma_area() \
156 : : ({ \
157 : : struct vma_area *p__ = xzalloc(sizeof(*p__)); \
158 : : if (p__) { \
159 : : vma_entry__init(&p__->vma); \
160 : : p__->vm_file_fd = -1; \
161 : : p__->vma.fd = -1; \
162 : : } \
163 : : p__; \
164 : : })
165 : :
166 : : extern void mark_stack_vma(unsigned long sp, struct list_head *vma_area_list);
167 : :
168 : : extern int move_img_fd(int *img_fd, int want_fd);
169 : : extern int close_safe(int *fd);
170 : :
171 : : extern int reopen_fd_as_safe(char *file, int line, int new_fd, int old_fd, bool allow_reuse_fd);
172 : : #define reopen_fd_as(new_fd, old_fd) reopen_fd_as_safe(__FILE__, __LINE__, new_fd, old_fd, false)
173 : : #define reopen_fd_as_nocheck(new_fd, old_fd) reopen_fd_as_safe(__FILE__, __LINE__, new_fd, old_fd, true)
174 : :
175 : : int set_proc_mountpoint(char *path);
176 : : void close_proc(void);
177 : : int open_pid_proc(pid_t pid);
178 : : int close_pid_proc(void);
179 : : int set_proc_fd(int fd);
180 : :
181 : : int do_open_proc(pid_t pid, int flags, const char *fmt, ...);
182 : :
183 : : #define __open_proc(pid, flags, fmt, ...) \
184 : : ({ \
185 : : int __fd = do_open_proc(pid, flags, \
186 : : fmt, ##__VA_ARGS__); \
187 : : if (__fd < 0) \
188 : : pr_perror("Can't open /proc/%d/" fmt, \
189 : : pid, ##__VA_ARGS__); \
190 : : \
191 : : __fd; \
192 : : })
193 : :
194 : : /* int open_proc(pid_t pid, const char *fmt, ...); */
195 : : #define open_proc(pid, fmt, ...) \
196 : : __open_proc(pid, O_RDONLY, fmt, ##__VA_ARGS__)
197 : :
198 : : /* int open_proc_rw(pid_t pid, const char *fmt, ...); */
199 : : #define open_proc_rw(pid, fmt, ...) \
200 : : __open_proc(pid, O_RDWR, fmt, ##__VA_ARGS__)
201 : :
202 : : /* DIR *opendir_proc(pid_t pid, const char *fmt, ...); */
203 : : #define opendir_proc(pid, fmt, ...) \
204 : : ({ \
205 : : int __fd = open_proc(pid, fmt, ##__VA_ARGS__); \
206 : : DIR *__d = NULL; \
207 : : \
208 : : if (__fd >= 0) \
209 : : __d = fdopendir(__fd); \
210 : : if (__d == NULL) \
211 : : pr_perror("Can't fdopendir %d " \
212 : : "(/proc/%d/" fmt ")", \
213 : : __fd, pid, ##__VA_ARGS__); \
214 : : \
215 : : __d; \
216 : : })
217 : :
218 : : /* FILE *fopen_proc(pid_t pid, const char *fmt, ...); */
219 : : #define fopen_proc(pid, fmt, ...) \
220 : : ({ \
221 : : int __fd = open_proc(pid, fmt, ##__VA_ARGS__); \
222 : : FILE *__f = NULL; \
223 : : \
224 : : if (__fd >= 0) \
225 : : __f = fdopen(__fd, "r"); \
226 : : if (__f == NULL) \
227 : : pr_perror("Can't fdopen %d " \
228 : : "(/proc/%d/" fmt ")", \
229 : : __fd, pid, ##__VA_ARGS__); \
230 : : \
231 : : __f; \
232 : : })
233 : :
234 : : #define __xalloc(op, size, ...) \
235 : : ({ \
236 : : void *___p = op( __VA_ARGS__ ); \
237 : : if (!___p) \
238 : : pr_err("%s: Can't allocate %li bytes\n", \
239 : : __func__, (long)(size)); \
240 : : ___p; \
241 : : })
242 : :
243 : : #include <stdlib.h>
244 : :
245 : : #define xstrdup(str) __xalloc(strdup, strlen(str) + 1, str)
246 : : #define xmalloc(size) __xalloc(malloc, size, size)
247 : : #define xzalloc(size) __xalloc(calloc, size, 1, size)
248 : : #define xrealloc(p, size) __xalloc(realloc, size, p, size)
249 : :
250 : : #define xfree(p) do { if (p) free(p); } while (0)
251 : :
252 : : #define xrealloc_safe(pptr, size) \
253 : : ({ \
254 : : int __ret = -1; \
255 : : void *new = xrealloc(*pptr, size); \
256 : : if (new) { \
257 : : *pptr = new; \
258 : : __ret = 0; \
259 : : } \
260 : : __ret; \
261 : : })
262 : :
263 : : #define pr_img_head(type, ...) pr_msg("\n"#type __VA_ARGS__ "\n----------------\n")
264 : : #define pr_img_tail(type) pr_msg("----------------\n")
265 : :
266 : : #define KDEV_MINORBITS 20
267 : : #define KDEV_MINORMASK ((1UL << KDEV_MINORBITS) - 1)
268 : : #define MKKDEV(ma, mi) (((ma) << KDEV_MINORBITS) | (mi))
269 : :
270 : : static inline u32 kdev_major(u32 kdev)
271 : : {
272 : 2520 : return kdev >> KDEV_MINORBITS;
273 : : }
274 : :
275 : : static inline u32 kdev_minor(u32 kdev)
276 : : {
277 : 2081 : return kdev & KDEV_MINORMASK;
278 : : }
279 : :
280 : : static inline dev_t kdev_to_odev(u32 kdev)
281 : : {
282 : : /*
283 : : * New kernels envcode devices in a new form
284 : : */
285 : 4162 : return (kdev_major(kdev) << 8) | kdev_minor(kdev);
286 : : }
287 : :
288 : : int copy_file(int fd_in, int fd_out, size_t bytes);
289 : : bool is_anon_inode(struct statfs *statfs);
290 : : int is_anon_link_type(int lfd, char *type);
291 : :
292 : : #define is_hex_digit(c) \
293 : : (((c) >= '0' && (c) <= '9') || \
294 : : ((c) >= 'a' && (c) <= 'f') || \
295 : : ((c) >= 'A' && (c) <= 'F'))
296 : :
297 : : /*
298 : : * read_img_str -- same as read_img_buf, but allocates memory for
299 : : * the buffer and puts the '\0' at the end
300 : : */
301 : :
302 : : static inline int read_img_str(int fd, char **pstr, int size)
303 : : {
304 : : int ret;
305 : : char *str;
306 : :
307 : : str = xmalloc(size + 1);
308 : : if (!str)
309 : : return -1;
310 : :
311 : : ret = read_img_buf(fd, str, size);
312 : : if (ret < 0) {
313 : : xfree(str);
314 : : return -1;
315 : : }
316 : :
317 : : str[size] = '\0';
318 : : *pstr = str;
319 : : return 0;
320 : : }
321 : :
322 : : extern void *shmalloc(size_t bytes);
323 : : extern void shfree_last(void *ptr);
324 : : extern int run_scripts(char *action);
325 : :
326 : : extern int cr_system(int in, int out, int err, char *cmd, char *const argv[]);
327 : :
328 : : static inline bool dir_dots(struct dirent *de)
329 : : {
330 [ + + ][ + + ]: 8847 : return !strcmp(de->d_name, ".") || !strcmp(de->d_name, "..");
[ + + ][ + - ]
[ + + ][ + + ]
[ + + ][ + + ]
[ + - ][ + + ]
331 : : }
332 : :
333 : : #endif /* __CR_UTIL_H__ */
|