import.c revision 25300b5a1fcf54674a69d0f4ab08925be00b0227
796b06c21b62d13c9021e2fbd9c58a5c6edb2764Kay Sievers/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
796b06c21b62d13c9021e2fbd9c58a5c6edb2764Kay Sievers This file is part of systemd.
cf7ebcea78223b95b2676b97e1d2aad16caa3c86Kay Sievers Copyright 2015 Lennart Poettering
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers systemd is free software; you can redistribute it and/or modify it
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers under the terms of the GNU Lesser General Public License as published by
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers the Free Software Foundation; either version 2.1 of the License, or
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers (at your option) any later version.
378cf88f72a9cda84baf703ed24f54c8c539fdcfKay Sievers systemd is distributed in the hope that it will be useful, but
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers WITHOUT ANY WARRANTY; without even the implied warranty of
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers Lesser General Public License for more details.
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers You should have received a copy of the GNU Lesser General Public License
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers along with systemd; If not, see <http://www.gnu.org/licenses/>.
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sieversstatic bool arg_force = false;
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sieversstatic bool arg_read_only = false;
f9cd22249dbdcebe2ab54eea56c0b32e2a1c2ce5Mantas Mikulėnasstatic const char *arg_image_root = "/var/lib/machines";
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sieversstatic int interrupt_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers sd_event_exit(sd_event_source_get_event(s), EINTR);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sieversstatic void on_tar_finished(TarImport *import, int error, void *userdata) {
c35ddc5b69ef1911de39933329eda0b569cae4b9Kay Sieversstatic int import_tar(int argc, char *argv[], void *userdata) {
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers _cleanup_(tar_import_unrefp) TarImport *import = NULL;
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers log_error("Local image name '%s' is not valid.", local);
c35ddc5b69ef1911de39933329eda0b569cae4b9Kay Sievers return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers else if (r > 0) {
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers log_error_errno(EEXIST, "Image '%s' already exists.", local);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers open_fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers return log_error_errno(errno, "Failed to open tar image to import: %m");
cf7ebcea78223b95b2676b97e1d2aad16caa3c86Kay Sievers log_info("Importing '%s', saving as '%s'.", path, local);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers (void) readlink_malloc("/proc/self/fd/0", &pretty);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers log_info("Importing '%s', saving as '%s'.", strna(pretty), local);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers return log_error_errno(r, "Failed to allocate event loop: %m");
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers (void) sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers (void) sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers r = tar_import_new(&import, event, arg_image_root, on_tar_finished, event);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers return log_error_errno(r, "Failed to allocate importer: %m");
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers r = tar_import_start(import, fd, local, arg_force, arg_read_only);
c35ddc5b69ef1911de39933329eda0b569cae4b9Kay Sievers return log_error_errno(r, "Failed to import image: %m");
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers return log_error_errno(r, "Failed to run event loop: %m");
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sieversstatic void on_raw_finished(RawImport *import, int error, void *userdata) {
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sieversstatic int import_raw(int argc, char *argv[], void *userdata) {
f9cd22249dbdcebe2ab54eea56c0b32e2a1c2ce5Mantas Mikulėnas _cleanup_(raw_import_unrefp) RawImport *import = NULL;
f9cd22249dbdcebe2ab54eea56c0b32e2a1c2ce5Mantas Mikulėnas _cleanup_event_unref_ sd_event *event = NULL;
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers log_error("Local image name '%s' is not valid.", local);
c35ddc5b69ef1911de39933329eda0b569cae4b9Kay Sievers return log_error_errno(r, "Failed to check whether image '%s' exists: %m", local);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers else if (r > 0) {
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers log_error_errno(EEXIST, "Image '%s' already exists.", local);
c35ddc5b69ef1911de39933329eda0b569cae4b9Kay Sievers open_fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers return log_error_errno(errno, "Failed to open raw image to import: %m");
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers log_info("Importing '%s', saving as '%s'.", path, local);
796b06c21b62d13c9021e2fbd9c58a5c6edb2764Kay Sievers (void) readlink_malloc("/proc/self/fd/0", &pretty);
cf7ebcea78223b95b2676b97e1d2aad16caa3c86Kay Sievers log_info("Importing '%s', saving as '%s'.", pretty, local);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers return log_error_errno(r, "Failed to allocate event loop: %m");
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
378cf88f72a9cda84baf703ed24f54c8c539fdcfKay Sievers (void) sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL);
378cf88f72a9cda84baf703ed24f54c8c539fdcfKay Sievers (void) sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers r = raw_import_new(&import, event, arg_image_root, on_raw_finished, event);
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers return log_error_errno(r, "Failed to allocate importer: %m");
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers r = raw_import_start(import, fd, local, arg_force, arg_read_only);
5fe25affc01fb003a3a66937458a25640a6075ceTom Gundersen return log_error_errno(r, "Failed to import image: %m");
5fe25affc01fb003a3a66937458a25640a6075ceTom Gundersen return log_error_errno(r, "Failed to run event loop: %m");
5fe25affc01fb003a3a66937458a25640a6075ceTom Gundersenstatic int help(int argc, char *argv[], void *userdata) {
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers "Import container or virtual machine images.\n\n"
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers " -h --help Show this help\n"
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers " --version Show package version\n"
f9cd22249dbdcebe2ab54eea56c0b32e2a1c2ce5Mantas Mikulėnas " --force Force creation of image\n"
5fe25affc01fb003a3a66937458a25640a6075ceTom Gundersen " --image-root=PATH Image root directory\n"
5fe25affc01fb003a3a66937458a25640a6075ceTom Gundersen " --read-only Create a read-only image\n\n"
5fe25affc01fb003a3a66937458a25640a6075ceTom Gundersen "Commands:\n"
f2f1861383c5cf4c07a7c6098d7c0b7134f06d51Kay Sievers " tar FILE [NAME] Import a TAR image\n"
5fe25affc01fb003a3a66937458a25640a6075ceTom Gundersen " raw FILE [NAME] Import a RAW image\n",
5fe25affc01fb003a3a66937458a25640a6075ceTom Gundersenstatic int parse_argv(int argc, char *argv[]) {
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers { "image-root", required_argument, NULL, ARG_IMAGE_ROOT },
8db6dcfd3c3d19d35767f04884a99368f6c64b36Kay Sievers { "read-only", no_argument, NULL, ARG_READ_ONLY },
case ARG_VERSION:
case ARG_FORCE:
arg_force = true;
case ARG_IMAGE_ROOT:
case ARG_READ_ONLY:
arg_read_only = true;
return -EINVAL;
log_open();
goto finish;