LCOV - code coverage report
Current view: top level - home/snorch/criu - plugin.c (source / functions) Hit Total Coverage
Test: coverage3.info Lines: 49 73 67.1 %
Date: 2014-04-22 Functions: 6 10 60.0 %
Branches: 42 126 33.3 %

           Branch data     Line data    Source code
       1                 :            : #include <stdlib.h>
       2                 :            : #include <string.h>
       3                 :            : #include <dirent.h>
       4                 :            : #include <errno.h>
       5                 :            : #include <stdio.h>
       6                 :            : #include <dlfcn.h>
       7                 :            : #include <unistd.h>
       8                 :            : 
       9                 :            : #include "cr_options.h"
      10                 :            : #include "plugin.h"
      11                 :            : #include "log.h"
      12                 :            : #include "xmalloc.h"
      13                 :            : 
      14                 :            : struct cr_plugin_entry {
      15                 :            :         union {
      16                 :            :                 cr_plugin_fini_t                *cr_fini;
      17                 :            : 
      18                 :            :                 cr_plugin_dump_unix_sk_t        *cr_plugin_dump_unix_sk;
      19                 :            :                 cr_plugin_restore_unix_sk_t     *cr_plugin_restore_unix_sk;
      20                 :            :                 cr_plugin_dump_file_t           *cr_plugin_dump_file;
      21                 :            :                 cr_plugin_restore_file_t        *cr_plugin_restore_file;
      22                 :            :                 cr_plugin_dump_ext_mount_t      *cr_plugin_dump_ext_mount;
      23                 :            :                 cr_plugin_restore_ext_mount_t   *cr_plugin_restore_ext_mount;
      24                 :            :                 cr_plugin_dump_ext_link_t       *cr_plugin_dump_ext_link;
      25                 :            :         };
      26                 :            : 
      27                 :            :         struct cr_plugin_entry *next;
      28                 :            : };
      29                 :            : 
      30                 :            : struct cr_plugins {
      31                 :            :         struct cr_plugin_entry *cr_fini;
      32                 :            : 
      33                 :            :         struct cr_plugin_entry *cr_plugin_dump_unix_sk;
      34                 :            :         struct cr_plugin_entry *cr_plugin_restore_unix_sk;
      35                 :            :         struct cr_plugin_entry *cr_plugin_dump_file;
      36                 :            :         struct cr_plugin_entry *cr_plugin_restore_file;
      37                 :            :         struct cr_plugin_entry *cr_plugin_dump_ext_mount;
      38                 :            :         struct cr_plugin_entry *cr_plugin_restore_ext_mount;
      39                 :            :         struct cr_plugin_entry *cr_plugin_dump_ext_link;
      40                 :            : };
      41                 :            : 
      42                 :            : struct cr_plugins cr_plugins;
      43                 :            : 
      44                 :            : #define add_plugin_func(name)                                           \
      45                 :            :         do {                                                            \
      46                 :            :                 name ## _t *name;                                       \
      47                 :            :                 name = dlsym(h, #name);                                 \
      48                 :            :                 if (name) {                                             \
      49                 :            :                         struct cr_plugin_entry *__ce;                   \
      50                 :            :                         __ce = xmalloc(sizeof(*__ce));                  \
      51                 :            :                         if (__ce == NULL)                               \
      52                 :            :                                 goto nomem;                             \
      53                 :            :                         __ce->name = name;                           \
      54                 :            :                         __ce->next = cr_plugins.name;                        \
      55                 :            :                         cr_plugins.name = __ce;                         \
      56                 :            :                 }                                                       \
      57                 :            :         } while (0)
      58                 :            : 
      59                 :            : #define run_plugin_funcs(name, ...) ({                                  \
      60                 :            :                 struct cr_plugin_entry *__ce = cr_plugins.name;         \
      61                 :            :                 int __ret = -ENOTSUP;                                   \
      62                 :            :                                                                         \
      63                 :            :                 while (__ce) {                                          \
      64                 :            :                         __ret = __ce->name(__VA_ARGS__);             \
      65                 :            :                         if (__ret == -ENOTSUP) {                        \
      66                 :            :                                 __ce = __ce->next;                   \
      67                 :            :                                 continue;                               \
      68                 :            :                         }                                               \
      69                 :            :                         break;                                          \
      70                 :            :                 }                                                       \
      71                 :            :                                                                         \
      72                 :            :                 __ret;                                                  \
      73                 :            :         })                                                              \
      74                 :            : 
      75                 :          2 : int cr_plugin_dump_unix_sk(int fd, int id)
      76                 :            : {
      77 [ #  # ][ -  + ]:          2 :         return run_plugin_funcs(cr_plugin_dump_unix_sk, fd, id);
      78                 :            : }
      79                 :            : 
      80                 :          0 : int cr_plugin_restore_unix_sk(int id)
      81                 :            : {
      82 [ #  # ][ #  # ]:          0 :         return run_plugin_funcs(cr_plugin_restore_unix_sk, id);
      83                 :            : }
      84                 :            : 
      85                 :          4 : int cr_plugin_dump_file(int fd, int id)
      86                 :            : {
      87 [ -  + ][ +  - ]:          4 :         return run_plugin_funcs(cr_plugin_dump_file, fd, id);
      88                 :            : }
      89                 :            : 
      90                 :          2 : int cr_plugin_restore_file(int id)
      91                 :            : {
      92 [ -  + ][ +  - ]:          2 :         return run_plugin_funcs(cr_plugin_restore_file, id);
      93                 :            : }
      94                 :            : 
      95                 :          0 : int cr_plugin_dump_ext_mount(char *mountpoint, int id)
      96                 :            : {
      97 [ #  # ][ #  # ]:          0 :         return run_plugin_funcs(cr_plugin_dump_ext_mount, mountpoint, id);
      98                 :            : }
      99                 :            : 
     100                 :          0 : int cr_plugin_restore_ext_mount(int id, char *mountpoint, char *old_root, int *is_file)
     101                 :            : {
     102 [ #  # ][ #  # ]:          0 :         return run_plugin_funcs(cr_plugin_restore_ext_mount, id, mountpoint, old_root, is_file);
     103                 :            : }
     104                 :            : 
     105                 :          0 : int cr_plugin_dump_ext_link(int index, int type, char *kind)
     106                 :            : {
     107 [ #  # ][ #  # ]:          0 :         return run_plugin_funcs(cr_plugin_dump_ext_link, index, type, kind);
     108                 :            : }
     109                 :            : 
     110                 :         12 : static int cr_lib_load(char *path)
     111                 :            : {
     112                 :            :         struct cr_plugin_entry *ce;
     113                 :            :         cr_plugin_init_t *f_init;
     114                 :            :         cr_plugin_fini_t *f_fini;
     115                 :            :         void *h;
     116                 :            : 
     117                 :         12 :         h = dlopen(path, RTLD_LAZY);
     118         [ -  + ]:         12 :         if (h == NULL) {
     119                 :          0 :                 pr_err("Unable to load %s: %s", path, dlerror());
     120                 :          0 :                 return -1;
     121                 :            :         }
     122                 :            : 
     123 [ -  + ][ #  # ]:         12 :         add_plugin_func(cr_plugin_dump_unix_sk);
                 [ #  # ]
     124 [ -  + ][ #  # ]:         12 :         add_plugin_func(cr_plugin_restore_unix_sk);
                 [ #  # ]
     125                 :            : 
     126 [ +  - ][ -  + ]:         12 :         add_plugin_func(cr_plugin_dump_file);
                 [ +  - ]
     127 [ +  - ][ -  + ]:         12 :         add_plugin_func(cr_plugin_restore_file);
                 [ +  - ]
     128                 :            : 
     129 [ -  + ][ #  # ]:         12 :         add_plugin_func(cr_plugin_dump_ext_mount);
                 [ #  # ]
     130 [ -  + ][ #  # ]:         12 :         add_plugin_func(cr_plugin_restore_ext_mount);
                 [ #  # ]
     131                 :            : 
     132 [ -  + ][ #  # ]:         12 :         add_plugin_func(cr_plugin_dump_ext_link);
                 [ #  # ]
     133                 :            : 
     134                 :            :         ce = NULL;
     135                 :         12 :         f_fini = dlsym(h, "cr_plugin_fini");
     136         [ -  + ]:         12 :         if (f_fini) {
     137         [ #  # ]:          0 :                 ce = xmalloc(sizeof(*ce));
     138         [ #  # ]:          0 :                 if (ce == NULL)
     139                 :            :                         goto nomem;
     140                 :          0 :                 ce->cr_fini = f_fini;
     141                 :            :         }
     142                 :            : 
     143                 :         12 :         f_init = dlsym(h, "cr_plugin_init");
     144 [ -  + ][ #  # ]:         12 :         if (f_init && f_init()) {
     145         [ #  # ]:          0 :                 xfree(ce);
     146                 :            :                 return -1;
     147                 :            :         }
     148                 :            : 
     149         [ -  + ]:         12 :         if (ce) {
     150                 :          0 :                 ce->next = cr_plugins.cr_fini;
     151                 :          0 :                 cr_plugins.cr_fini = ce;
     152                 :            :         }
     153                 :            : 
     154                 :            :         return 0;
     155                 :            : 
     156                 :            : nomem:
     157                 :            :         return -1;
     158                 :            : }
     159                 :            : 
     160                 :            : #define cr_plugin_free(name) do {                               \
     161                 :            :         while (cr_plugins.name) {                               \
     162                 :            :                 ce = cr_plugins.name;                           \
     163                 :            :                 cr_plugins.name = cr_plugins.name->next;     \
     164                 :            :                 xfree(ce);                                      \
     165                 :            :         }                                                       \
     166                 :            : } while (0)                                                     \
     167                 :            : 
     168                 :        896 : void cr_plugin_fini(void)
     169                 :            : {
     170                 :            :         struct cr_plugin_entry *ce;
     171                 :            : 
     172 [ #  # ][ -  + ]:        896 :         cr_plugin_free(cr_plugin_dump_unix_sk);
     173 [ #  # ][ -  + ]:        896 :         cr_plugin_free(cr_plugin_restore_unix_sk);
     174                 :            : 
     175 [ -  + ][ +  + ]:        904 :         cr_plugin_free(cr_plugin_dump_file);
     176 [ -  + ][ +  + ]:        904 :         cr_plugin_free(cr_plugin_restore_file);
     177                 :            : 
     178         [ -  + ]:        896 :         while (cr_plugins.cr_fini) {
     179                 :            :                 ce = cr_plugins.cr_fini;
     180                 :          0 :                 cr_plugins.cr_fini = cr_plugins.cr_fini->next;
     181                 :            : 
     182                 :          0 :                 ce->cr_fini();
     183         [ #  # ]:        896 :                 xfree(ce);
     184                 :            :         }
     185                 :        896 : }
     186                 :            : 
     187                 :       1461 : int cr_plugin_init(void)
     188                 :            : {
     189                 :            :         int exit_code = -1;
     190                 :            :         char *path;
     191                 :            :         DIR *d;
     192                 :            : 
     193                 :            :         memset(&cr_plugins, 0, sizeof(cr_plugins));
     194                 :            : 
     195         [ +  + ]:       1461 :         if (opts.libdir == NULL) {
     196                 :       1449 :                 path = getenv("CRIU_LIBS_DIR");
     197         [ -  + ]:       1449 :                 if (path)
     198                 :          0 :                         opts.libdir = path;
     199                 :            :                 else {
     200         [ -  + ]:       1449 :                         if (access(CR_PLUGIN_DEFAULT, F_OK))
     201                 :            :                                 return 0;
     202                 :            : 
     203                 :          0 :                         opts.libdir = CR_PLUGIN_DEFAULT;
     204                 :            :                 }
     205                 :            :         }
     206                 :            : 
     207                 :         12 :         d = opendir(opts.libdir);
     208         [ +  - ]:         12 :         if (d == NULL) {
     209                 :          0 :                 pr_perror("Unable to open directory %s", opts.libdir);
     210                 :         36 :                 return -1;
     211                 :            :         }
     212                 :            : 
     213                 :            :         while (1) {
     214                 :            :                 char path[PATH_MAX];
     215                 :            :                 struct dirent *de;
     216                 :            :                 int len;
     217                 :            : 
     218                 :         48 :                 errno = 0;
     219                 :         48 :                 de = readdir(d);
     220         [ +  + ]:         48 :                 if (de == NULL) {
     221         [ -  + ]:         12 :                         if (errno == 0)
     222                 :            :                                 break;
     223                 :          0 :                         pr_perror("Unable to read the libraries directory");
     224                 :          0 :                         goto err;
     225                 :            :                 }
     226                 :            : 
     227                 :         36 :                 len = strlen(de->d_name);
     228                 :            : 
     229 [ +  + ][ -  + ]:         36 :                 if (len < 3 || strncmp(de->d_name + len - 3, ".so", 3))
     230                 :         24 :                         continue;
     231                 :            : 
     232                 :         12 :                 snprintf(path, sizeof(path), "%s/%s", opts.libdir, de->d_name);
     233                 :            : 
     234         [ +  - ]:         24 :                 if (cr_lib_load(path))
     235                 :            :                         goto err;
     236                 :            :         }
     237                 :            : 
     238                 :            :         exit_code = 0;
     239                 :            : err:
     240                 :         12 :         closedir(d);
     241                 :            : 
     242         [ -  + ]:         12 :         if (exit_code)
     243                 :          0 :                 cr_plugin_fini();
     244                 :            : 
     245                 :         12 :         return exit_code;
     246                 :            : }

Generated by: LCOV version 1.9