From: Ivan Kruglov Date: Tue, 17 Dec 2024 11:53:28 +0000 (+0100) Subject: machine: use machine_copy_from_to() in dbus implementation X-Git-Tag: v258-rc1~1692^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8632e7ae233a2e8d5d4d3c294c6d17de9d302819;p=thirdparty%2Fsystemd.git machine: use machine_copy_from_to() in dbus implementation --- diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c index 2ed779d117f..2d05c52608c 100644 --- a/src/machine/machine-dbus.c +++ b/src/machine/machine-dbus.c @@ -492,15 +492,11 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu } int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_error *error) { - _cleanup_free_ char *host_basename = NULL, *container_basename = NULL; const char *src, *dest, *host_path, *container_path; - _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR; CopyFlags copy_flags = COPY_REFLINK|COPY_MERGE|COPY_HARDLINKS; - _cleanup_close_ int hostfd = -EBADF; Machine *m = ASSERT_PTR(userdata); + Manager *manager = m->manager; bool copy_from; - pid_t child; - uid_t uid_shift; int r; assert(message); @@ -549,17 +545,13 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro message, "org.freedesktop.machine1.manage-machines", details, - &m->manager->polkit_registry, + &manager->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* Will call us back */ - r = machine_get_uid_shift(m, &uid_shift); - if (r < 0) - return r; - copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom"); if (copy_from) { @@ -570,83 +562,12 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro container_path = dest; } - r = path_extract_filename(host_path, &host_basename); + Operation *op; + r = machine_copy_from_to(manager, m, host_path, container_path, copy_from, copy_flags, &op); if (r < 0) - return sd_bus_error_set_errnof(error, r, "Failed to extract file name of '%s' path: %m", host_path); - - r = path_extract_filename(container_path, &container_basename); - if (r < 0) - return sd_bus_error_set_errnof(error, r, "Failed to extract file name of '%s' path: %m", container_path); - - hostfd = open_parent(host_path, O_CLOEXEC, 0); - if (hostfd < 0) - return sd_bus_error_set_errnof(error, hostfd, "Failed to open host directory %s: %m", host_path); - - if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m"); - - r = safe_fork("(sd-copy)", FORK_RESET_SIGNALS, &child); - if (r < 0) - return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); - if (r == 0) { - int containerfd; - const char *q; - int mntfd; - - errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); - - q = procfs_file_alloca(m->leader.pid, "ns/mnt"); - mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC); - if (mntfd < 0) { - r = log_error_errno(errno, "Failed to open mount namespace of leader: %m"); - goto child_fail; - } - - if (setns(mntfd, CLONE_NEWNS) < 0) { - r = log_error_errno(errno, "Failed to join namespace of leader: %m"); - goto child_fail; - } - - containerfd = open_parent(container_path, O_CLOEXEC, 0); - if (containerfd < 0) { - r = log_error_errno(containerfd, "Failed to open destination directory: %m"); - goto child_fail; - } - - /* Run the actual copy operation. Note that when a UID shift is set we'll either clamp the UID/GID to - * 0 or to the actual UID shift depending on the direction we copy. If no UID shift is set we'll copy - * the UID/GIDs as they are. */ - if (copy_from) - r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, uid_shift == 0 ? UID_INVALID : 0, uid_shift == 0 ? GID_INVALID : 0, copy_flags, NULL, NULL); - else - r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, uid_shift == 0 ? UID_INVALID : uid_shift, uid_shift == 0 ? GID_INVALID : uid_shift, copy_flags, NULL, NULL); - - hostfd = safe_close(hostfd); - containerfd = safe_close(containerfd); - - if (r < 0) { - r = log_error_errno(r, "Failed to copy tree: %m"); - goto child_fail; - } - - _exit(EXIT_SUCCESS); - - child_fail: - (void) write(errno_pipe_fd[1], &r, sizeof(r)); - _exit(EXIT_FAILURE); - } - - errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]); - - /* Copying might take a while, hence install a watch on the child, and return */ - - r = operation_new_with_bus_reply(m->manager, m, child, message, errno_pipe_fd[0], /* ret= */ NULL); - if (r < 0) { - (void) sigkill_wait(child); - return r; - } - errno_pipe_fd[0] = -EBADF; + return sd_bus_error_set_errnof(error, r, "Failed to copy from/to machine '%s': %m", m->name); + operation_attach_bus_reply(op, message); return 1; }