LCOV - code coverage report
Current view: top level - crtools/include - util.h (source / functions) Hit Total Coverage
Test: crtools.info Lines: 17 23 73.9 %
Date: 2012-12-28 Functions: 3 3 100.0 %
Branches: 23 32 71.9 %

           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__ */

Generated by: LCOV version 1.9