diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-11-29 16:38:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-29 16:38:46 +0100 |
commit | 401faa3533280b05fee972e0c64885caf4b31e4c (patch) | |
tree | febc63c1b0a46948cc3af8d23cbc6596f73b8f3d /src/machine | |
parent | Merge pull request #10959 from poettering/systemctl-edit-fixo (diff) | |
parent | update TODO (diff) | |
download | systemd-401faa3533280b05fee972e0c64885caf4b31e4c.tar.xz systemd-401faa3533280b05fee972e0c64885caf4b31e4c.zip |
Merge pull request #10357 from poettering/import-fs
machinectl import-fs command and other fixes
Diffstat (limited to 'src/machine')
-rw-r--r-- | src/machine/machinectl.c | 135 | ||||
-rw-r--r-- | src/machine/machined-dbus.c | 31 |
2 files changed, 110 insertions, 56 deletions
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 094ee9d360..a49b11e7b0 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -5,6 +5,7 @@ #include <fcntl.h> #include <getopt.h> #include <locale.h> +#include <math.h> #include <net/if.h> #include <netinet/in.h> #include <string.h> @@ -1999,28 +2000,38 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) { return -r; } +static const char *nullify_dash(const char *p) { + if (isempty(p)) + return NULL; + + if (streq(p, "-")) + return NULL; + + return p; +} + static int import_tar(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; - _cleanup_free_ char *ll = NULL; - _cleanup_close_ int fd = -1; + _cleanup_free_ char *ll = NULL, *fn = NULL; const char *local = NULL, *path = NULL; + _cleanup_close_ int fd = -1; sd_bus *bus = userdata; int r; assert(bus); if (argc >= 2) - path = argv[1]; - if (isempty(path) || streq(path, "-")) - path = NULL; + path = nullify_dash(argv[1]); if (argc >= 3) - local = argv[2]; - else if (path) - local = basename(path); - if (isempty(local) || streq(local, "-")) - local = NULL; + local = nullify_dash(argv[2]); + else if (path) { + r = path_extract_filename(path, &fn); + if (r < 0) + return log_error_errno(r, "Cannot extract container name from filename: %m"); + local = fn; + } if (!local) { log_error("Need either path or local name."); return -EINVAL; @@ -2068,26 +2079,26 @@ static int import_tar(int argc, char *argv[], void *userdata) { static int import_raw(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; - _cleanup_free_ char *ll = NULL; - _cleanup_close_ int fd = -1; + _cleanup_free_ char *ll = NULL, *fn = NULL; const char *local = NULL, *path = NULL; + _cleanup_close_ int fd = -1; sd_bus *bus = userdata; int r; assert(bus); if (argc >= 2) - path = argv[1]; - if (isempty(path) || streq(path, "-")) - path = NULL; + path = nullify_dash(argv[1]); if (argc >= 3) - local = argv[2]; - else if (path) - local = basename(path); - if (isempty(local) || streq(local, "-")) - local = NULL; + local = nullify_dash(argv[2]); + else if (path) { + r = path_extract_filename(path, &fn); + if (r < 0) + return log_error_errno(r, "Cannot extract container name from filename: %m"); + local = fn; + } if (!local) { log_error("Need either path or local name."); return -EINVAL; @@ -2133,6 +2144,67 @@ static int import_raw(int argc, char *argv[], void *userdata) { return transfer_image_common(bus, m); } +static int import_fs(int argc, char *argv[], void *userdata) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + const char *local = NULL, *path = NULL; + _cleanup_free_ char *fn = NULL; + _cleanup_close_ int fd = -1; + sd_bus *bus = userdata; + int r; + + assert(bus); + + if (argc >= 2) + path = nullify_dash(argv[1]); + + if (argc >= 3) + local = nullify_dash(argv[2]); + else if (path) { + r = path_extract_filename(path, &fn); + if (r < 0) + return log_error_errno(r, "Cannot extract container name from filename: %m"); + + local = fn; + } + if (!local) { + log_error("Need either path or local name."); + return -EINVAL; + } + + if (!machine_name_is_valid(local)) { + log_error("Local name %s is not a suitable machine name.", local); + return -EINVAL; + } + + if (path) { + fd = open(path, O_DIRECTORY|O_RDONLY|O_CLOEXEC); + if (fd < 0) + return log_error_errno(errno, "Failed to open directory '%s': %m", path); + } + + r = sd_bus_message_new_method_call( + bus, + &m, + "org.freedesktop.import1", + "/org/freedesktop/import1", + "org.freedesktop.import1.Manager", + "ImportFileSystem"); + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_append( + m, + "hsbb", + fd >= 0 ? fd : STDIN_FILENO, + local, + arg_force, + arg_read_only); + if (r < 0) + return bus_log_create_error(r); + + return transfer_image_common(bus, m); +} + static void determine_compression_from_filename(const char *p) { if (arg_format) return; @@ -2464,12 +2536,21 @@ static int list_transfers(int argc, char *argv[], void *userdata) { (int) max_remote, "REMOTE"); for (j = 0; j < n_transfers; j++) - printf("%*" PRIu32 " %*u%% %-*s %-*s %-*s\n", - (int) MAX(2U, DECIMAL_STR_WIDTH(max_id)), transfers[j].id, - (int) 6, (unsigned) (transfers[j].progress * 100), - (int) max_type, transfers[j].type, - (int) max_local, transfers[j].local, - (int) max_remote, transfers[j].remote); + + if (transfers[j].progress < 0) + printf("%*" PRIu32 " %*s %-*s %-*s %-*s\n", + (int) MAX(2U, DECIMAL_STR_WIDTH(max_id)), transfers[j].id, + (int) 7, "n/a", + (int) max_type, transfers[j].type, + (int) max_local, transfers[j].local, + (int) max_remote, transfers[j].remote); + else + printf("%*" PRIu32 " %*u%% %-*s %-*s %-*s\n", + (int) MAX(2U, DECIMAL_STR_WIDTH(max_id)), transfers[j].id, + (int) 6, (unsigned) (transfers[j].progress * 100), + (int) max_type, transfers[j].type, + (int) max_local, transfers[j].local, + (int) max_remote, transfers[j].remote); if (arg_legend) { if (n_transfers > 0) @@ -2687,6 +2768,7 @@ static int help(int argc, char *argv[], void *userdata) { " pull-raw URL [NAME] Download a RAW container or VM image\n" " import-tar FILE [NAME] Import a local TAR container image\n" " import-raw FILE [NAME] Import a local RAW container or VM image\n" + " import-fs DIRECTORY [NAME] Import a local directory container image\n" " export-tar NAME [FILE] Export a TAR container image locally\n" " export-raw NAME [FILE] Export a RAW container or VM image locally\n" " list-transfers Show list of downloads in progress\n" @@ -3008,6 +3090,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) { { "disable", 2, VERB_ANY, 0, enable_machine }, { "import-tar", 2, 3, 0, import_tar }, { "import-raw", 2, 3, 0, import_raw }, + { "import-fs", 2, 3, 0, import_fs }, { "export-tar", 2, 3, 0, export_tar }, { "export-raw", 2, 3, 0, export_raw }, { "pull-tar", 2, 3, 0, pull_tar }, diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 87e6298c78..453ca30b64 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -41,15 +41,10 @@ static int property_get_pool_usage( _cleanup_close_ int fd = -1; uint64_t usage = (uint64_t) -1; - struct stat st; assert(bus); assert(reply); - /* We try to read the quota info from /var/lib/machines, as - * well as the usage of the loopback file - * /var/lib/machines.raw, and pick the larger value. */ - fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY); if (fd >= 0) { BtrfsQuotaInfo q; @@ -58,11 +53,6 @@ static int property_get_pool_usage( usage = q.referenced; } - if (stat("/var/lib/machines.raw", &st) >= 0) { - if (usage == (uint64_t) -1 || st.st_blocks * 512ULL > usage) - usage = st.st_blocks * 512ULL; - } - return sd_bus_message_append(reply, "t", usage); } @@ -77,15 +67,10 @@ static int property_get_pool_limit( _cleanup_close_ int fd = -1; uint64_t size = (uint64_t) -1; - struct stat st; assert(bus); assert(reply); - /* We try to read the quota limit from /var/lib/machines, as - * well as the size of the loopback file - * /var/lib/machines.raw, and pick the smaller value. */ - fd = open("/var/lib/machines", O_RDONLY|O_CLOEXEC|O_DIRECTORY); if (fd >= 0) { BtrfsQuotaInfo q; @@ -94,11 +79,6 @@ static int property_get_pool_limit( size = q.referenced_max; } - if (stat("/var/lib/machines.raw", &st) >= 0) { - if (size == (uint64_t) -1 || (uint64_t) st.st_size < size) - size = st.st_size; - } - return sd_bus_message_append(reply, "t", size); } @@ -877,19 +857,10 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus return 1; /* Will call us back */ /* Set up the machine directory if necessary */ - r = setup_machine_directory(limit, error); + r = setup_machine_directory(error); if (r < 0) return r; - /* Resize the backing loopback device, if there is one, except if we asked to drop any limit */ - if (limit != (uint64_t) -1) { - r = btrfs_resize_loopback("/var/lib/machines", limit, false); - if (r == -ENOTTY) - return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs."); - if (r < 0 && r != -ENODEV) /* ignore ENODEV, as that's what is returned if the file system is not on loopback */ - return sd_bus_error_set_errnof(error, r, "Failed to adjust loopback limit: %m"); - } - (void) btrfs_qgroup_set_limit("/var/lib/machines", 0, limit); r = btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, limit); |