#include "bus-get-properties.h"
#include "bus-log-control-api.h"
#include "bus-polkit.h"
-#include "def.h"
+#include "constants.h"
#include "env-util.h"
#include "fd-util.h"
#include "float.h"
#include "strv.h"
#include "syslog-util.h"
#include "user-util.h"
-#include "util.h"
#include "web-util.h"
typedef struct Transfer Transfer;
int notify_fd;
sd_event_source *notify_event_source;
+
+ bool use_btrfs_subvol;
+ bool use_btrfs_quota;
};
#define TRANSFERS_MAX 64
*t = (Transfer) {
.type = _TRANSFER_TYPE_INVALID,
- .log_fd = -1,
- .stdin_fd = -1,
- .stdout_fd = -1,
+ .log_fd = -EBADF,
+ .stdin_fd = -EBADF,
+ .stdout_fd = -EBADF,
.verify = _IMPORT_VERIFY_INVALID,
.progress_percent= UINT_MAX,
};
}
static int transfer_on_pid(sd_event_source *s, const siginfo_t *si, void *userdata) {
- Transfer *t = userdata;
+ Transfer *t = ASSERT_PTR(userdata);
bool success = false;
assert(s);
- assert(t);
if (si->si_code == CLD_EXITED) {
if (si->si_status != 0)
}
static int transfer_on_log(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
- Transfer *t = userdata;
+ Transfer *t = ASSERT_PTR(userdata);
ssize_t l;
assert(s);
- assert(t);
l = read(fd, t->log_message + t->log_message_size, sizeof(t->log_message) - t->log_message_size);
if (l < 0)
}
static int transfer_start(Transfer *t) {
- _cleanup_close_pair_ int pipefd[2] = { -1, -1 };
+ _cleanup_close_pair_ int pipefd[2] = PIPE_EBADF;
int r;
assert(t);
int r;
n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
- if (IN_SET(n, -EAGAIN, -EINTR))
- return 0;
- if (n < 0)
+ if (n < 0) {
+ if (ERRNO_IS_TRANSIENT(n))
+ return 0;
return (int) n;
+ }
cmsg_close_all(&msghdr);
assert(ret);
- m = new0(Manager, 1);
+ m = new(Manager, 1);
if (!m)
return -ENOMEM;
+ *m = (Manager) {
+ .use_btrfs_subvol = true,
+ .use_btrfs_quota = true,
+ };
+
r = sd_event_default(&m->event);
if (r < 0)
return r;
_cleanup_(transfer_unrefp) Transfer *t = NULL;
int fd, force, read_only, r;
const char *local, *object;
- Manager *m = userdata;
+ Manager *m = ASSERT_PTR(userdata);
TransferType type;
struct stat st;
uint32_t id;
assert(msg);
- assert(m);
r = bus_verify_polkit_async(
msg,
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Local name %s is invalid", local);
- r = setup_machine_directory(error);
+ r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
if (r < 0)
return r;
_cleanup_(transfer_unrefp) Transfer *t = NULL;
int fd, force, read_only, r;
const char *local, *object;
- Manager *m = userdata;
+ Manager *m = ASSERT_PTR(userdata);
uint32_t id;
assert(msg);
- assert(m);
r = bus_verify_polkit_async(
msg,
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Local name %s is invalid", local);
- r = setup_machine_directory(error);
+ r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
if (r < 0)
return r;
_cleanup_(transfer_unrefp) Transfer *t = NULL;
int fd, r;
const char *local, *object, *format;
- Manager *m = userdata;
+ Manager *m = ASSERT_PTR(userdata);
TransferType type;
struct stat st;
uint32_t id;
assert(msg);
- assert(m);
r = bus_verify_polkit_async(
msg,
static int method_pull_tar_or_raw(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
_cleanup_(transfer_unrefp) Transfer *t = NULL;
const char *remote, *local, *verify, *object;
- Manager *m = userdata;
+ Manager *m = ASSERT_PTR(userdata);
ImportVerify v;
TransferType type;
int force, r;
uint32_t id;
assert(msg);
- assert(m);
r = bus_verify_polkit_async(
msg,
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Unknown verification mode %s", verify);
- r = setup_machine_directory(error);
+ r = setup_machine_directory(error, m->use_btrfs_subvol, m->use_btrfs_quota);
if (r < 0)
return r;
static int method_list_transfers(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
- Manager *m = userdata;
+ Manager *m = ASSERT_PTR(userdata);
Transfer *t;
int r;
assert(msg);
- assert(m);
r = sd_bus_message_new_method_return(msg, &reply);
if (r < 0)
}
static int method_cancel(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
- Transfer *t = userdata;
+ Transfer *t = ASSERT_PTR(userdata);
int r;
assert(msg);
- assert(t);
r = bus_verify_polkit_async(
msg,
}
static int method_cancel_transfer(sd_bus_message *msg, void *userdata, sd_bus_error *error) {
- Manager *m = userdata;
+ Manager *m = ASSERT_PTR(userdata);
Transfer *t;
uint32_t id;
int r;
assert(msg);
- assert(m);
r = bus_verify_polkit_async(
msg,
void *userdata,
sd_bus_error *error) {
- Transfer *t = userdata;
+ Transfer *t = ASSERT_PTR(userdata);
assert(bus);
assert(reply);
- assert(t);
return sd_bus_message_append(reply, "d", transfer_percent_as_double(t));
}
void **found,
sd_bus_error *error) {
- Manager *m = userdata;
+ Manager *m = ASSERT_PTR(userdata);
Transfer *t;
const char *p;
uint32_t id;
assert(path);
assert(interface);
assert(found);
- assert(m);
p = startswith(path, "/org/freedesktop/import1/transfer/_");
if (!p)
m);
}
+static void manager_parse_env(Manager *m) {
+ int r;
+
+ assert(m);
+
+ /* Same as src/import/{import,pull}.c:
+ * Let's make these relatively low-level settings also controllable via env vars. User can then set
+ * them for systemd-importd.service if they like to tweak behaviour */
+
+ r = getenv_bool("SYSTEMD_IMPORT_BTRFS_SUBVOL");
+ if (r >= 0)
+ m->use_btrfs_subvol = r;
+ else if (r != -ENXIO)
+ log_warning_errno(r, "Failed to parse $SYSTEMD_IMPORT_BTRFS_SUBVOL: %m");
+
+ r = getenv_bool("SYSTEMD_IMPORT_BTRFS_QUOTA");
+ if (r >= 0)
+ m->use_btrfs_quota = r;
+ else if (r != -ENXIO)
+ log_warning_errno(r, "Failed to parse $SYSTEMD_IMPORT_BTRFS_QUOTA: %m");
+}
+
static int run(int argc, char *argv[]) {
_cleanup_(manager_unrefp) Manager *m = NULL;
int r;
if (r < 0)
return log_error_errno(r, "Failed to allocate manager object: %m");
+ manager_parse_env(m);
+
r = manager_add_bus_objects(m);
if (r < 0)
return r;