LCOV - code coverage report
Current view: top level - import - import.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 20 170 11.8 %
Date: 2019-08-23 13:36:53 Functions: 4 10 40.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 6 137 4.4 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <getopt.h>
       4                 :            : #include <locale.h>
       5                 :            : 
       6                 :            : #include "sd-event.h"
       7                 :            : #include "sd-id128.h"
       8                 :            : 
       9                 :            : #include "alloc-util.h"
      10                 :            : #include "fd-util.h"
      11                 :            : #include "fs-util.h"
      12                 :            : #include "hostname-util.h"
      13                 :            : #include "import-raw.h"
      14                 :            : #include "import-tar.h"
      15                 :            : #include "import-util.h"
      16                 :            : #include "machine-image.h"
      17                 :            : #include "main-func.h"
      18                 :            : #include "signal-util.h"
      19                 :            : #include "string-util.h"
      20                 :            : #include "verbs.h"
      21                 :            : 
      22                 :            : static bool arg_force = false;
      23                 :            : static bool arg_read_only = false;
      24                 :            : static const char *arg_image_root = "/var/lib/machines";
      25                 :            : 
      26                 :          0 : static int interrupt_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
      27         [ #  # ]:          0 :         log_notice("Transfer aborted.");
      28                 :          0 :         sd_event_exit(sd_event_source_get_event(s), EINTR);
      29                 :          0 :         return 0;
      30                 :            : }
      31                 :            : 
      32                 :          0 : static void on_tar_finished(TarImport *import, int error, void *userdata) {
      33                 :          0 :         sd_event *event = userdata;
      34         [ #  # ]:          0 :         assert(import);
      35                 :            : 
      36         [ #  # ]:          0 :         if (error == 0)
      37         [ #  # ]:          0 :                 log_info("Operation completed successfully.");
      38                 :            : 
      39                 :          0 :         sd_event_exit(event, abs(error));
      40                 :          0 : }
      41                 :            : 
      42                 :          0 : static int import_tar(int argc, char *argv[], void *userdata) {
      43                 :          0 :         _cleanup_(tar_import_unrefp) TarImport *import = NULL;
      44                 :          0 :         _cleanup_(sd_event_unrefp) sd_event *event = NULL;
      45                 :          0 :         const char *path = NULL, *local = NULL;
      46                 :          0 :         _cleanup_free_ char *ll = NULL;
      47                 :          0 :         _cleanup_close_ int open_fd = -1;
      48                 :            :         int r, fd;
      49                 :            : 
      50         [ #  # ]:          0 :         if (argc >= 2)
      51                 :          0 :                 path = argv[1];
      52                 :          0 :         path = empty_or_dash_to_null(path);
      53                 :            : 
      54         [ #  # ]:          0 :         if (argc >= 3)
      55                 :          0 :                 local = argv[2];
      56         [ #  # ]:          0 :         else if (path)
      57                 :          0 :                 local = basename(path);
      58                 :          0 :         local = empty_or_dash_to_null(local);
      59                 :            : 
      60         [ #  # ]:          0 :         if (local) {
      61                 :          0 :                 r = tar_strip_suffixes(local, &ll);
      62         [ #  # ]:          0 :                 if (r < 0)
      63                 :          0 :                         return log_oom();
      64                 :            : 
      65                 :          0 :                 local = ll;
      66                 :            : 
      67         [ #  # ]:          0 :                 if (!machine_name_is_valid(local)) {
      68         [ #  # ]:          0 :                         log_error("Local image name '%s' is not valid.", local);
      69                 :          0 :                         return -EINVAL;
      70                 :            :                 }
      71                 :            : 
      72         [ #  # ]:          0 :                 if (!arg_force) {
      73                 :          0 :                         r = image_find(IMAGE_MACHINE, local, NULL);
      74         [ #  # ]:          0 :                         if (r < 0) {
      75         [ #  # ]:          0 :                                 if (r != -ENOENT)
      76         [ #  # ]:          0 :                                         return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
      77                 :            :                         } else {
      78         [ #  # ]:          0 :                                 log_error("Image '%s' already exists.", local);
      79                 :          0 :                                 return -EEXIST;
      80                 :            :                         }
      81                 :            :                 }
      82                 :            :         } else
      83                 :          0 :                 local = "imported";
      84                 :            : 
      85         [ #  # ]:          0 :         if (path) {
      86                 :          0 :                 open_fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
      87         [ #  # ]:          0 :                 if (open_fd < 0)
      88         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to open tar image to import: %m");
      89                 :            : 
      90                 :          0 :                 fd = open_fd;
      91                 :            : 
      92         [ #  # ]:          0 :                 log_info("Importing '%s', saving as '%s'.", path, local);
      93                 :            :         } else {
      94                 :          0 :                 _cleanup_free_ char *pretty = NULL;
      95                 :            : 
      96                 :          0 :                 fd = STDIN_FILENO;
      97                 :            : 
      98                 :          0 :                 (void) fd_get_path(fd, &pretty);
      99         [ #  # ]:          0 :                 log_info("Importing '%s', saving as '%s'.", strna(pretty), local);
     100                 :            :         }
     101                 :            : 
     102                 :          0 :         r = sd_event_default(&event);
     103         [ #  # ]:          0 :         if (r < 0)
     104         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to allocate event loop: %m");
     105                 :            : 
     106         [ #  # ]:          0 :         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
     107                 :          0 :         (void) sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler,  NULL);
     108                 :          0 :         (void) sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
     109                 :            : 
     110                 :          0 :         r = tar_import_new(&import, event, arg_image_root, on_tar_finished, event);
     111         [ #  # ]:          0 :         if (r < 0)
     112         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to allocate importer: %m");
     113                 :            : 
     114                 :          0 :         r = tar_import_start(import, fd, local, arg_force, arg_read_only);
     115         [ #  # ]:          0 :         if (r < 0)
     116         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to import image: %m");
     117                 :            : 
     118                 :          0 :         r = sd_event_loop(event);
     119         [ #  # ]:          0 :         if (r < 0)
     120         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to run event loop: %m");
     121                 :            : 
     122         [ #  # ]:          0 :         log_info("Exiting.");
     123                 :          0 :         return -r;
     124                 :            : }
     125                 :            : 
     126                 :          0 : static void on_raw_finished(RawImport *import, int error, void *userdata) {
     127                 :          0 :         sd_event *event = userdata;
     128         [ #  # ]:          0 :         assert(import);
     129                 :            : 
     130         [ #  # ]:          0 :         if (error == 0)
     131         [ #  # ]:          0 :                 log_info("Operation completed successfully.");
     132                 :            : 
     133                 :          0 :         sd_event_exit(event, abs(error));
     134                 :          0 : }
     135                 :            : 
     136                 :          0 : static int import_raw(int argc, char *argv[], void *userdata) {
     137                 :          0 :         _cleanup_(raw_import_unrefp) RawImport *import = NULL;
     138                 :          0 :         _cleanup_(sd_event_unrefp) sd_event *event = NULL;
     139                 :          0 :         const char *path = NULL, *local = NULL;
     140                 :          0 :         _cleanup_free_ char *ll = NULL;
     141                 :          0 :         _cleanup_close_ int open_fd = -1;
     142                 :            :         int r, fd;
     143                 :            : 
     144         [ #  # ]:          0 :         if (argc >= 2)
     145                 :          0 :                 path = argv[1];
     146                 :          0 :         path = empty_or_dash_to_null(path);
     147                 :            : 
     148         [ #  # ]:          0 :         if (argc >= 3)
     149                 :          0 :                 local = argv[2];
     150         [ #  # ]:          0 :         else if (path)
     151                 :          0 :                 local = basename(path);
     152                 :          0 :         local = empty_or_dash_to_null(local);
     153                 :            : 
     154         [ #  # ]:          0 :         if (local) {
     155                 :          0 :                 r = raw_strip_suffixes(local, &ll);
     156         [ #  # ]:          0 :                 if (r < 0)
     157                 :          0 :                         return log_oom();
     158                 :            : 
     159                 :          0 :                 local = ll;
     160                 :            : 
     161         [ #  # ]:          0 :                 if (!machine_name_is_valid(local)) {
     162         [ #  # ]:          0 :                         log_error("Local image name '%s' is not valid.", local);
     163                 :          0 :                         return -EINVAL;
     164                 :            :                 }
     165                 :            : 
     166         [ #  # ]:          0 :                 if (!arg_force) {
     167                 :          0 :                         r = image_find(IMAGE_MACHINE, local, NULL);
     168         [ #  # ]:          0 :                         if (r < 0) {
     169         [ #  # ]:          0 :                                 if (r != -ENOENT)
     170         [ #  # ]:          0 :                                         return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
     171                 :            :                         } else {
     172         [ #  # ]:          0 :                                 log_error("Image '%s' already exists.", local);
     173                 :          0 :                                 return -EEXIST;
     174                 :            :                         }
     175                 :            :                 }
     176                 :            :         } else
     177                 :          0 :                 local = "imported";
     178                 :            : 
     179         [ #  # ]:          0 :         if (path) {
     180                 :          0 :                 open_fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
     181         [ #  # ]:          0 :                 if (open_fd < 0)
     182         [ #  # ]:          0 :                         return log_error_errno(errno, "Failed to open raw image to import: %m");
     183                 :            : 
     184                 :          0 :                 fd = open_fd;
     185                 :            : 
     186         [ #  # ]:          0 :                 log_info("Importing '%s', saving as '%s'.", path, local);
     187                 :            :         } else {
     188                 :          0 :                 _cleanup_free_ char *pretty = NULL;
     189                 :            : 
     190                 :          0 :                 fd = STDIN_FILENO;
     191                 :            : 
     192                 :          0 :                 (void) fd_get_path(fd, &pretty);
     193         [ #  # ]:          0 :                 log_info("Importing '%s', saving as '%s'.", strempty(pretty), local);
     194                 :            :         }
     195                 :            : 
     196                 :          0 :         r = sd_event_default(&event);
     197         [ #  # ]:          0 :         if (r < 0)
     198         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to allocate event loop: %m");
     199                 :            : 
     200         [ #  # ]:          0 :         assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
     201                 :          0 :         (void) sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler,  NULL);
     202                 :          0 :         (void) sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
     203                 :            : 
     204                 :          0 :         r = raw_import_new(&import, event, arg_image_root, on_raw_finished, event);
     205         [ #  # ]:          0 :         if (r < 0)
     206         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to allocate importer: %m");
     207                 :            : 
     208                 :          0 :         r = raw_import_start(import, fd, local, arg_force, arg_read_only);
     209         [ #  # ]:          0 :         if (r < 0)
     210         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to import image: %m");
     211                 :            : 
     212                 :          0 :         r = sd_event_loop(event);
     213         [ #  # ]:          0 :         if (r < 0)
     214         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to run event loop: %m");
     215                 :            : 
     216         [ #  # ]:          0 :         log_info("Exiting.");
     217                 :          0 :         return -r;
     218                 :            : }
     219                 :            : 
     220                 :         12 : static int help(int argc, char *argv[], void *userdata) {
     221                 :            : 
     222                 :         12 :         printf("%s [OPTIONS...] {COMMAND} ...\n\n"
     223                 :            :                "Import container or virtual machine images.\n\n"
     224                 :            :                "  -h --help                   Show this help\n"
     225                 :            :                "     --version                Show package version\n"
     226                 :            :                "     --force                  Force creation of image\n"
     227                 :            :                "     --image-root=PATH        Image root directory\n"
     228                 :            :                "     --read-only              Create a read-only image\n\n"
     229                 :            :                "Commands:\n"
     230                 :            :                "  tar FILE [NAME]             Import a TAR image\n"
     231                 :            :                "  raw FILE [NAME]             Import a RAW image\n",
     232                 :            :                program_invocation_short_name);
     233                 :            : 
     234                 :         12 :         return 0;
     235                 :            : }
     236                 :            : 
     237                 :         16 : static int parse_argv(int argc, char *argv[]) {
     238                 :            : 
     239                 :            :         enum {
     240                 :            :                 ARG_VERSION = 0x100,
     241                 :            :                 ARG_FORCE,
     242                 :            :                 ARG_IMAGE_ROOT,
     243                 :            :                 ARG_READ_ONLY,
     244                 :            :         };
     245                 :            : 
     246                 :            :         static const struct option options[] = {
     247                 :            :                 { "help",            no_argument,       NULL, 'h'                 },
     248                 :            :                 { "version",         no_argument,       NULL, ARG_VERSION         },
     249                 :            :                 { "force",           no_argument,       NULL, ARG_FORCE           },
     250                 :            :                 { "image-root",      required_argument, NULL, ARG_IMAGE_ROOT      },
     251                 :            :                 { "read-only",       no_argument,       NULL, ARG_READ_ONLY       },
     252                 :            :                 {}
     253                 :            :         };
     254                 :            : 
     255                 :            :         int c;
     256                 :            : 
     257         [ -  + ]:         16 :         assert(argc >= 0);
     258         [ -  + ]:         16 :         assert(argv);
     259                 :            : 
     260         [ +  - ]:         16 :         while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
     261                 :            : 
     262   [ +  -  -  -  :         16 :                 switch (c) {
                -  +  - ]
     263                 :            : 
     264                 :         12 :                 case 'h':
     265                 :         12 :                         return help(0, NULL, NULL);
     266                 :            : 
     267                 :          0 :                 case ARG_VERSION:
     268                 :          0 :                         return version();
     269                 :            : 
     270                 :          0 :                 case ARG_FORCE:
     271                 :          0 :                         arg_force = true;
     272                 :          0 :                         break;
     273                 :            : 
     274                 :          0 :                 case ARG_IMAGE_ROOT:
     275                 :          0 :                         arg_image_root = optarg;
     276                 :          0 :                         break;
     277                 :            : 
     278                 :          0 :                 case ARG_READ_ONLY:
     279                 :          0 :                         arg_read_only = true;
     280                 :          0 :                         break;
     281                 :            : 
     282                 :          4 :                 case '?':
     283                 :          4 :                         return -EINVAL;
     284                 :            : 
     285                 :          0 :                 default:
     286                 :          0 :                         assert_not_reached("Unhandled option");
     287                 :            :                 }
     288                 :            : 
     289                 :          0 :         return 1;
     290                 :            : }
     291                 :            : 
     292                 :          0 : static int import_main(int argc, char *argv[]) {
     293                 :            :         static const Verb verbs[] = {
     294                 :            :                 { "help", VERB_ANY, VERB_ANY, 0, help       },
     295                 :            :                 { "tar",  2,        3,        0, import_tar },
     296                 :            :                 { "raw",  2,        3,        0, import_raw },
     297                 :            :                 {}
     298                 :            :         };
     299                 :            : 
     300                 :          0 :         return dispatch_verb(argc, argv, verbs, NULL);
     301                 :            : }
     302                 :            : 
     303                 :         16 : static int run(int argc, char *argv[]) {
     304                 :            :         int r;
     305                 :            : 
     306                 :         16 :         setlocale(LC_ALL, "");
     307                 :         16 :         log_parse_environment();
     308                 :         16 :         log_open();
     309                 :            : 
     310                 :         16 :         r = parse_argv(argc, argv);
     311         [ +  - ]:         16 :         if (r <= 0)
     312                 :         16 :                 return 0;
     313                 :            : 
     314                 :          0 :         (void) ignore_signals(SIGPIPE, -1);
     315                 :            : 
     316                 :          0 :         return import_main(argc, argv);
     317                 :            : }
     318                 :            : 
     319                 :         16 : DEFINE_MAIN_FUNCTION(run);

Generated by: LCOV version 1.14