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 "asm/types.h"
17 : : #include "xmalloc.h"
18 : : #include "bug.h"
19 : : #include "log.h"
20 : : #include "err.h"
21 : :
22 : : #include "protobuf/vma.pb-c.h"
23 : :
24 : : #define PREF_SHIFT_OP(pref, op, size) ((size) op (pref ##BYTES_SHIFT))
25 : : #define KBYTES_SHIFT 10
26 : : #define MBYTES_SHIFT 20
27 : : #define GBYTES_SHIFT 30
28 : :
29 : : #define KBYTES(size) PREF_SHIFT_OP(K, >>, size)
30 : : #define MBYTES(size) PREF_SHIFT_OP(M, >>, size)
31 : : #define GBYTES(size) PREF_SHIFT_OP(G, >>, size)
32 : :
33 : : #define KILO(size) PREF_SHIFT_OP(K, <<, size)
34 : : #define MEGA(size) PREF_SHIFT_OP(K, <<, size)
35 : : #define GIGA(size) PREF_SHIFT_OP(K, <<, size)
36 : :
37 : : /*
38 : : * Write buffer @ptr of @size bytes into @fd file
39 : : * Returns
40 : : * 0 on success
41 : : * -1 on error (error message is printed)
42 : : */
43 : 31754 : static inline int write_img_buf(int fd, const void *ptr, int size)
44 : : {
45 : : int ret;
46 : 31754 : ret = write(fd, ptr, size);
47 [ - + ]: 31754 : if (ret == size)
48 : : return 0;
49 : :
50 [ # # ]: 0 : if (ret < 0)
51 : 0 : pr_perror("Can't write img file");
52 : : else
53 : 0 : pr_err("Img trimmed %d/%d\n", ret, size);
54 : : return -1;
55 : : }
56 : :
57 : : #define write_img(fd, ptr) write_img_buf((fd), (ptr), sizeof(*(ptr)))
58 : :
59 : : /*
60 : : * Read buffer @ptr of @size bytes from @fd file
61 : : * Returns
62 : : * 1 on success
63 : : * 0 on EOF (silently)
64 : : * -1 on error (error message is printed)
65 : : */
66 : 28768 : static inline int read_img_buf_eof(int fd, void *ptr, int size)
67 : : {
68 : : int ret;
69 : 57536 : ret = read(fd, ptr, size);
70 [ - + ]: 28768 : if (ret == size)
71 : : return 1;
72 [ # # ]: 0 : if (ret == 0)
73 : : return 0;
74 : :
75 [ # # ]: 0 : if (ret < 0)
76 : 0 : pr_perror("Can't read img file");
77 : : else
78 : 0 : pr_err("Img trimmed %d/%d\n", ret, size);
79 : : return -1;
80 : : }
81 : :
82 : : #define read_img_eof(fd, ptr) read_img_buf_eof((fd), (ptr), sizeof(*(ptr)))
83 : :
84 : : /*
85 : : * Read buffer @ptr of @size bytes from @fd file
86 : : * Returns
87 : : * 1 on success
88 : : * -1 on error or EOF (error message is printed)
89 : : */
90 : 28768 : static inline int read_img_buf(int fd, void *ptr, int size)
91 : : {
92 : : int ret;
93 : :
94 : 28768 : ret = read_img_buf_eof(fd, ptr, size);
95 [ - + ]: 28768 : if (ret == 0) {
96 : 0 : pr_err("Unexpected EOF\n");
97 : : ret = -1;
98 : : }
99 : :
100 : 28768 : return ret;
101 : : }
102 : :
103 : : #define read_img(fd, ptr) read_img_buf((fd), (ptr), sizeof(*(ptr)))
104 : :
105 : : struct vma_area;
106 : : struct list_head;
107 : :
108 : : extern void pr_vma(unsigned int loglevel, const struct vma_area *vma_area);
109 : :
110 : : #define pr_info_vma(vma_area) pr_vma(LOG_INFO, vma_area)
111 : : #define pr_msg_vma(vma_area) pr_vma(LOG_MSG, vma_area)
112 : :
113 : : #define pr_vma_list(level, head) \
114 : : do { \
115 : : struct vma_area *vma; \
116 : : list_for_each_entry(vma, head, list) \
117 : : pr_vma(level, vma); \
118 : : } while (0)
119 : : #define pr_info_vma_list(head) pr_vma_list(LOG_INFO, head)
120 : :
121 : : extern int move_img_fd(int *img_fd, int want_fd);
122 : : extern int close_safe(int *fd);
123 : :
124 : : extern int reopen_fd_as_safe(char *file, int line, int new_fd, int old_fd, bool allow_reuse_fd);
125 : : #define reopen_fd_as(new_fd, old_fd) reopen_fd_as_safe(__FILE__, __LINE__, new_fd, old_fd, false)
126 : : #define reopen_fd_as_nocheck(new_fd, old_fd) reopen_fd_as_safe(__FILE__, __LINE__, new_fd, old_fd, true)
127 : :
128 : : extern void close_proc(void);
129 : : extern int open_pid_proc(pid_t pid);
130 : : extern int close_pid_proc(void);
131 : : extern int set_proc_fd(int fd);
132 : :
133 : : extern int do_open_proc(pid_t pid, int flags, const char *fmt, ...);
134 : :
135 : : #define __open_proc(pid, flags, fmt, ...) \
136 : : ({ \
137 : : int __fd = do_open_proc(pid, flags, \
138 : : fmt, ##__VA_ARGS__); \
139 : : if (__fd < 0) \
140 : : pr_perror("Can't open /proc/%d/" fmt, \
141 : : pid, ##__VA_ARGS__); \
142 : : \
143 : : __fd; \
144 : : })
145 : :
146 : : /* int open_proc(pid_t pid, const char *fmt, ...); */
147 : : #define open_proc(pid, fmt, ...) \
148 : : __open_proc(pid, O_RDONLY, fmt, ##__VA_ARGS__)
149 : :
150 : : /* int open_proc_rw(pid_t pid, const char *fmt, ...); */
151 : : #define open_proc_rw(pid, fmt, ...) \
152 : : __open_proc(pid, O_RDWR, fmt, ##__VA_ARGS__)
153 : :
154 : : /* DIR *opendir_proc(pid_t pid, const char *fmt, ...); */
155 : : #define opendir_proc(pid, fmt, ...) \
156 : : ({ \
157 : : int __fd = open_proc(pid, fmt, ##__VA_ARGS__); \
158 : : DIR *__d = NULL; \
159 : : \
160 : : if (__fd >= 0) { \
161 : : __d = fdopendir(__fd); \
162 : : if (__d == NULL) \
163 : : pr_perror("Can't fdopendir %d " \
164 : : "(/proc/%d/" fmt ")", \
165 : : __fd, pid, ##__VA_ARGS__); \
166 : : } \
167 : : __d; \
168 : : })
169 : :
170 : : /* FILE *fopen_proc(pid_t pid, const char *fmt, ...); */
171 : : #define fopen_proc(pid, fmt, ...) \
172 : : ({ \
173 : : int __fd = open_proc(pid, fmt, ##__VA_ARGS__); \
174 : : FILE *__f = NULL; \
175 : : \
176 : : if (__fd >= 0) { \
177 : : __f = fdopen(__fd, "r"); \
178 : : if (__f == NULL) \
179 : : pr_perror("Can't fdopen %d " \
180 : : "(/proc/%d/" fmt ")", \
181 : : __fd, pid, ##__VA_ARGS__); \
182 : : } \
183 : : __f; \
184 : : })
185 : :
186 : : #define pr_img_head(type, ...) pr_msg("\n"#type __VA_ARGS__ "\n----------------\n")
187 : : #define pr_img_tail(type) pr_msg("----------------\n")
188 : :
189 : : #define DEVZERO (makedev(1, 5))
190 : :
191 : : #define KDEV_MINORBITS 20
192 : : #define KDEV_MINORMASK ((1UL << KDEV_MINORBITS) - 1)
193 : : #define MKKDEV(ma, mi) (((ma) << KDEV_MINORBITS) | (mi))
194 : :
195 : : static inline u32 kdev_major(u32 kdev)
196 : : {
197 : 18831 : return kdev >> KDEV_MINORBITS;
198 : : }
199 : :
200 : : static inline u32 kdev_minor(u32 kdev)
201 : : {
202 : : return kdev & KDEV_MINORMASK;
203 : : }
204 : :
205 : : static inline dev_t kdev_to_odev(u32 kdev)
206 : : {
207 : : /*
208 : : * New kernels encode devices in a new form.
209 : : * See kernel's fs/stat.c for details, there
210 : : * choose_32_64 helpers which are the key.
211 : : */
212 : : unsigned major = kdev_major(kdev);
213 : : unsigned minor = kdev_minor(kdev);
214 : : #if BITS_PER_LONG == 32
215 : : return (major << 8) | minor;
216 : : #else
217 : 18825 : return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
218 : : #endif
219 : : }
220 : :
221 : : extern int copy_file(int fd_in, int fd_out, size_t bytes);
222 : : extern int is_anon_link_type(char *link, char *type);
223 : :
224 : : #define is_hex_digit(c) \
225 : : (((c) >= '0' && (c) <= '9') || \
226 : : ((c) >= 'a' && (c) <= 'f') || \
227 : : ((c) >= 'A' && (c) <= 'F'))
228 : :
229 : : /*
230 : : * read_img_str -- same as read_img_buf, but allocates memory for
231 : : * the buffer and puts the '\0' at the end
232 : : */
233 : :
234 : : static inline int read_img_str(int fd, char **pstr, int size)
235 : : {
236 : : int ret;
237 : : char *str;
238 : :
239 : : str = xmalloc(size + 1);
240 : : if (!str)
241 : : return -1;
242 : :
243 : : ret = read_img_buf(fd, str, size);
244 : : if (ret < 0) {
245 : : xfree(str);
246 : : return -1;
247 : : }
248 : :
249 : : str[size] = '\0';
250 : : *pstr = str;
251 : : return 0;
252 : : }
253 : :
254 : : extern void *shmalloc(size_t bytes);
255 : : extern void shfree_last(void *ptr);
256 : : extern int run_scripts(char *action);
257 : :
258 : : extern int cr_system(int in, int out, int err, char *cmd, char *const argv[]);
259 : : extern int cr_daemon(int nochdir, int noclose);
260 : : extern int is_root_user(void);
261 : :
262 : : static inline bool dir_dots(struct dirent *de)
263 : : {
264 [ + + ][ + + ]: 54121 : return !strcmp(de->d_name, ".") || !strcmp(de->d_name, "..");
[ + + ][ + - ]
[ + + ][ + + ]
[ + + ][ + + ]
[ + - ][ + + ]
265 : : }
266 : :
267 : : /*
268 : : * Size of buffer to carry the worst case or /proc/self/fd/N
269 : : * path. Since fd is an integer, we can easily estimate one :)
270 : : */
271 : : #define PSFDS (sizeof("/proc/self/fd/2147483647"))
272 : :
273 : : extern int read_fd_link(int lfd, char *buf, size_t size);
274 : :
275 : : #define USEC_PER_SEC 1000000L
276 : : #define NSEC_PER_SEC 1000000000L
277 : :
278 : : int vaddr_to_pfn(unsigned long vaddr, u64 *pfn);
279 : :
280 : : #endif /* __CR_UTIL_H__ */
|