export.c revision ce30c8dcb41dfe9264f79f30c7f51c0e74576638
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye This file is part of systemd.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye Copyright 2015 Lennart Poettering
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye systemd is free software; you can redistribute it and/or modify it
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye under the terms of the GNU Lesser General Public License as published by
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye the Free Software Foundation; either version 2.1 of the License, or
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye (at your option) any later version.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye systemd is distributed in the hope that it will be useful, but
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye WITHOUT ANY WARRANTY; without even the implied warranty of
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye Lesser General Public License for more details.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye You should have received a copy of the GNU Lesser General Public License
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye along with systemd; If not, see <http://www.gnu.org/licenses/>.
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic void determine_compression_from_filename(const char *p) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic int interrupt_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye sd_event_exit(sd_event_source_get_event(s), EINTR);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic void on_tar_finished(TarExport *export, int error, void *userdata) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbyestatic int export_tar(int argc, char *argv[], void *userdata) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye _cleanup_(tar_export_unrefp) TarExport *export = NULL;
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye return log_error_errno(r, "Failed to look for machine %s: %m", argv[1]);
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye if (r == 0) {
64b763950bf11e9357facbd2b5666631a895c085Trond Norbye log_error("Machine image %s not found.", argv[1]);
945f4c3c36a15447913781dfb1894b34f2941c57Jorgen Austvik open_fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC|O_NOCTTY, 0666);
780cc7d1b57609ff15fb283201e93cb501ebe9e6Jorgen Austvik return log_error_errno(errno, "Failed to open tar image for export: %m");
d3d2404f9a49bf70b124053feabe666f85ef5361Knut Anders Hatlen log_info("Exporting '%s', saving to '%s' with compression '%s'.", local, path, import_compress_type_to_string(arg_compress));
0466de7c67573e1ce5e0733325c1e5383270f5d5Knut Anders Hatlen (void) readlink_malloc("/proc/self/fd/1", &pretty);
0466de7c67573e1ce5e0733325c1e5383270f5d5Knut Anders Hatlen log_info("Exporting '%s', saving to '%s' with compression '%s'.", local, strna(pretty), import_compress_type_to_string(arg_compress));
1ed6b730409d4740e941142599767d5eac7e7d92Lubos Kosco return log_error_errno(r, "Failed to allocate event loop: %m");
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL);
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik r = tar_export_new(&export, event, on_tar_finished, event);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik return log_error_errno(r, "Failed to allocate exporter: %m");
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco r = tar_export_start(export, local, fd, arg_compress);
7ecd52b03dc1f0b03ff8f522b4891c8531896c3dJorgen Austvik return log_error_errno(r, "Failed to export image: %m");
5a0c5ad4116f5a4dd0dd5a0a4e6d02973cd5eef9Lubos Kosco return log_error_errno(r, "Failed to run event loop: %m");
945f4c3c36a15447913781dfb1894b34f2941c57Jorgen Austvikstatic void on_raw_finished(RawExport *export, int error, void *userdata) {
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Koscostatic int export_raw(int argc, char *argv[], void *userdata) {
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye _cleanup_(raw_export_unrefp) RawExport *export = NULL;
ecc9697029dc3bde02537b914756f7c49eb7cd1eLubos Kosco return log_error_errno(r, "Failed to look for machine %s: %m", argv[1]);
45909b3ef8c6e568a87482cb890fec7b5dbb7733Lubos Kosco if (r == 0) {
45909b3ef8c6e568a87482cb890fec7b5dbb7733Lubos Kosco log_error("Machine image %s not found.", argv[1]);
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco open_fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC|O_NOCTTY, 0666);
e3bec3188dc818cc194cd67e6871c6d0af0d6b26Felix Annan return log_error_errno(errno, "Failed to open raw image for export: %m");
b34561d2c3d92fac37dbced05ba6a8738e3d20e9Lubos Kosco log_info("Exporting '%s', saving to '%s' with compression '%s'.", local, path, import_compress_type_to_string(arg_compress));
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen (void) readlink_malloc("/proc/self/fd/1", &pretty);
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen log_info("Exporting '%s', saving to '%s' with compression '%s'.", local, strna(pretty), import_compress_type_to_string(arg_compress));
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye return log_error_errno(r, "Failed to allocate event loop: %m");
3d35131df8607ae05b064219b9448afc5c4b550aKnut Anders Hatlen assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
3d35131df8607ae05b064219b9448afc5c4b550aKnut Anders Hatlen sd_event_add_signal(event, NULL, SIGTERM, interrupt_signal_handler, NULL);
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye sd_event_add_signal(event, NULL, SIGINT, interrupt_signal_handler, NULL);
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye r = raw_export_new(&export, event, on_raw_finished, event);
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen return log_error_errno(r, "Failed to allocate exporter: %m");
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen r = raw_export_start(export, local, fd, arg_compress);
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen return log_error_errno(r, "Failed to export image: %m");
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen return log_error_errno(r, "Failed to run event loop: %m");
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbyestatic int help(int argc, char *argv[], void *userdata) {
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen printf("%s [OPTIONS...] {COMMAND} ...\n\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen "Export container or virtual machine images.\n\n"
d4ce228a333ba2daa19ad8b0672a704c8e42a2dcTrond Norbye " -h --help Show this help\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen " --version Show package version\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen " --format=FORMAT Select format\n\n"
a5cc1506d5c0704805c6733a46c7f1f8f91ae724Knut Anders Hatlen " tar NAME [FILE] Export a TAR image\n"
7b046969a1b2565787df8ae3a8126359e8cd6fafTrond Norbye " raw NAME [FILE] Export a RAW image\n",
2e3c025fdd5908a27cc82eb1d5346368a8be4e0dJorgen Austvik { "version", no_argument, NULL, ARG_VERSION },
d3d2404f9a49bf70b124053feabe666f85ef5361Knut Anders Hatlen { "format", required_argument, NULL, ARG_FORMAT },
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlen arg_compress = IMPORT_COMPRESS_UNCOMPRESSED;
2dbc1835e0ae88ad102e2b9a85e5c7b5298b14b6Knut Anders Hatlenstatic int export_main(int argc, char *argv[]) {