#include "seccomp-util.h"
#endif
+typedef enum ContainerStatus {
+ CONTAINER_TERMINATED,
+ CONTAINER_REBOOTED
+} ContainerStatus;
+
typedef enum LinkJournal {
LINK_NO,
LINK_AUTO,
return r;
}
} else {
- log_error("Failed to bind mount %s: %s", *x, strerror(errno));
+ log_error("Failed to bind mount %s: %m", *x);
return -errno;
}
/* Create the mount point, but be conservative -- refuse to create block
return 0;
}
+static char* id128_format_as_uuid(sd_id128_t id, char s[37]) {
+
+ snprintf(s, 37,
+ "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ SD_ID128_FORMAT_VAL(id));
+
+ return s;
+}
+
static int setup_boot_id(const char *dest) {
_cleanup_free_ char *from = NULL, *to = NULL;
sd_id128_t rnd = {};
return r;
}
- snprintf(as_uuid, sizeof(as_uuid),
- "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- SD_ID128_FORMAT_VAL(rnd));
- char_array_0(as_uuid);
+ id128_format_as_uuid(rnd, as_uuid);
r = write_string_file(from, as_uuid);
if (r < 0) {
} else if (access(p, F_OK) < 0)
return 0;
- if (dir_is_empty(q) == 0) {
- log_error("%s not empty.", q);
- return -ENOTEMPTY;
- }
+ if (dir_is_empty(q) == 0)
+ log_warning("%s is not empty, proceeding anyway.", q);
r = mkdir_p(q, 0755);
if (r < 0) {
return r;
}
- r = sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "veth");
- if (r < 0) {
- log_error("Failed to append netlink kind: %s", strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_INFO_DATA);
+ r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "veth");
if (r < 0) {
log_error("Failed to open netlink container: %s", strerror(-r));
return r;
return r;
}
- r = sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "macvlan");
- if (r < 0) {
- log_error("Failed to append netlink kind: %s", strerror(-r));
- return r;
- }
-
- r = sd_rtnl_message_open_container(m, IFLA_INFO_DATA);
+ r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA, "macvlan");
if (r < 0) {
log_error("Failed to open netlink container: %s", strerror(-r));
return r;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_close_ int fd = -1;
unsigned n_uids = 0;
- size_t sz, l;
+ size_t sz = 0, l;
uid_t uid;
gid_t gid;
pid_t pid;
return 0;
}
+/*
+ * Return 0 in case the container is being rebooted, has been shut
+ * down or exited successfully. On failures a negative value is
+ * returned.
+ *
+ * The status of the container "CONTAINER_TERMINATED" or
+ * "CONTAINER_REBOOTED" will be saved in the container argument
+ */
+static int wait_for_container(pid_t pid, ContainerStatus *container) {
+ int r;
+ siginfo_t status;
+
+ r = wait_for_terminate(pid, &status);
+ if (r < 0)
+ return r;
+
+ switch (status.si_code) {
+ case CLD_EXITED:
+ r = status.si_status;
+ if (r == 0) {
+ if (!arg_quiet)
+ log_debug("Container %s exited successfully.",
+ arg_machine);
+
+ *container = CONTAINER_TERMINATED;
+ } else {
+ log_error("Container %s failed with error code %i.",
+ arg_machine, status.si_status);
+ r = -1;
+ }
+ break;
+
+ case CLD_KILLED:
+ if (status.si_status == SIGINT) {
+ if (!arg_quiet)
+ log_info("Container %s has been shut down.",
+ arg_machine);
+
+ *container = CONTAINER_TERMINATED;
+ r = 0;
+ break;
+ } else if (status.si_status == SIGHUP) {
+ if (!arg_quiet)
+ log_info("Container %s is being rebooted.",
+ arg_machine);
+
+ *container = CONTAINER_REBOOTED;
+ r = 0;
+ break;
+ }
+ /* CLD_KILLED fallthrough */
+
+ case CLD_DUMPED:
+ log_error("Container %s terminated by signal %s.",
+ arg_machine, signal_to_string(status.si_status));
+ r = -1;
+ break;
+
+ default:
+ log_error("Container %s failed due to unknown reason.",
+ arg_machine);
+ r = -1;
+ break;
+ }
+
+ return r;
+}
+
int main(int argc, char *argv[]) {
_cleanup_free_ char *kdbus_domain = NULL, *device_path = NULL, *root_device = NULL, *home_device = NULL, *srv_device = NULL;
assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
for (;;) {
+ ContainerStatus container_status;
int parent_ready_fd = -1, child_ready_fd = -1;
- siginfo_t status;
eventfd_t x;
parent_ready_fd = eventfd(0, EFD_CLOEXEC);
}
if (!sd_id128_equal(arg_uuid, SD_ID128_NULL)) {
- if (asprintf((char**)(envp + n_env++), "container_uuid=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(arg_uuid)) < 0) {
+ char as_uuid[37];
+
+ if (asprintf((char**)(envp + n_env++), "container_uuid=%s", id128_format_as_uuid(arg_uuid, as_uuid)) < 0) {
log_oom();
goto child_fail;
}
fds = NULL;
/* Wait until the child reported that it is ready with
- * all it needs to do with priviliges. After we got
+ * all it needs to do with privileges. After we got
* the notification we can make the process join its
* cgroup which might limit what it can do */
eventfd_read(child_ready_fd, &x);
/* Redundant, but better safe than sorry */
kill(pid, SIGKILL);
- k = wait_for_terminate(pid, &status);
+ r = wait_for_container(pid, &container_status);
pid = 0;
- if (k < 0) {
+ if (r < 0) {
r = EXIT_FAILURE;
break;
- }
-
- if (status.si_code == CLD_EXITED) {
- r = status.si_status;
- if (status.si_status != 0) {
- log_error("Container %s failed with error code %i.", arg_machine, status.si_status);
- break;
- }
-
- if (!arg_quiet)
- log_debug("Container %s exited successfully.", arg_machine);
- break;
- } else if (status.si_code == CLD_KILLED &&
- status.si_status == SIGINT) {
-
- if (!arg_quiet)
- log_info("Container %s has been shut down.", arg_machine);
- r = 0;
+ } else if (container_status == CONTAINER_TERMINATED)
break;
- } else if (status.si_code == CLD_KILLED &&
- status.si_status == SIGHUP) {
-
- if (!arg_quiet)
- log_info("Container %s is being rebooted.", arg_machine);
- continue;
- } else if (status.si_code == CLD_KILLED ||
- status.si_code == CLD_DUMPED) {
- log_error("Container %s terminated by signal %s.", arg_machine, signal_to_string(status.si_status));
- r = EXIT_FAILURE;
- break;
- } else {
- log_error("Container %s failed due to unknown reason.", arg_machine);
- r = EXIT_FAILURE;
- break;
- }
+ /* CONTAINER_REBOOTED, loop again */
}
finish: