X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=2bda27edf07472a5e36650b488c2b43afbc5054b;hb=733d15ac7a23c80f2e447f6c2fca0406bc9960db;hp=3fce3ad77f0c72cd4081dbe74c9e2faf705ebd08;hpb=ab5e3a1bccaf79d65c93fc15ddeaa7595ffe0b86;p=elogind.git diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 3fce3ad77..2bda27edf 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1655,7 +1655,7 @@ static int watch_rtnl(sd_event *event, int recv_fd, union in_addr_union *exposed cmsg = CMSG_FIRSTHDR(&mh); assert(cmsg->cmsg_level == SOL_SOCKET); assert(cmsg->cmsg_type == SCM_RIGHTS); - assert(cmsg->cmsg_len = CMSG_LEN(sizeof(int))); + assert(cmsg->cmsg_len == CMSG_LEN(sizeof(int))); memcpy(&fd, CMSG_DATA(cmsg), sizeof(int)); r = sd_rtnl_open_fd(&rtnl, fd, 1, RTNLGRP_IPV4_IFADDR); @@ -3337,6 +3337,7 @@ int main(int argc, char *argv[]) { pid_t pid = 0; int ret = EXIT_SUCCESS; union in_addr_union exposed = {}; + _cleanup_release_lock_file_ LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT; log_parse_environment(); log_open(); @@ -3382,20 +3383,8 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_template) { - r = btrfs_subvol_snapshot(arg_template, arg_directory, arg_read_only, true); - if (r == -EEXIST) { - if (!arg_quiet) - log_info("Directory %s already exists, not populating from template %s.", arg_directory, arg_template); - } else if (r < 0) { - log_error_errno(r, "Couldn't create snapshort %s from %s: %m", arg_directory, arg_template); - goto finish; - } else { - if (!arg_quiet) - log_info("Populated %s from template %s.", arg_directory, arg_template); - } - - } else if (arg_ephemeral) { + if (arg_ephemeral) { + _cleanup_release_lock_file_ LockFile original_lock = LOCK_FILE_INIT; char *np; /* If the specified path is a mount point we @@ -3418,6 +3407,12 @@ int main(int argc, char *argv[]) { goto finish; } + r = image_path_lock(np, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, &tree_global_lock, &tree_local_lock); + if (r < 0) { + log_error_errno(r, "Failed to lock %s: %m", np); + goto finish; + } + r = btrfs_subvol_snapshot(arg_directory, np, arg_read_only, true); if (r < 0) { free(np); @@ -3429,6 +3424,31 @@ int main(int argc, char *argv[]) { arg_directory = np; remove_subvol = true; + + } else { + r = image_path_lock(arg_directory, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, &tree_global_lock, &tree_local_lock); + if (r == -EBUSY) { + log_error_errno(r, "Directory tree %s is currently busy.", arg_directory); + goto finish; + } + if (r < 0) { + log_error_errno(r, "Failed to lock %s: %m", arg_directory); + return r; + } + + if (arg_template) { + r = btrfs_subvol_snapshot(arg_template, arg_directory, arg_read_only, true); + if (r == -EEXIST) { + if (!arg_quiet) + log_info("Directory %s already exists, not populating from template %s.", arg_directory, arg_template); + } else if (r < 0) { + log_error_errno(r, "Couldn't create snapshort %s from %s: %m", arg_directory, arg_template); + goto finish; + } else { + if (!arg_quiet) + log_info("Populated %s from template %s.", arg_directory, arg_template); + } + } } if (arg_boot) { @@ -3455,6 +3475,16 @@ int main(int argc, char *argv[]) { assert(arg_image); assert(!arg_template); + r = image_path_lock(arg_image, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, &tree_global_lock, &tree_local_lock); + if (r == -EBUSY) { + r = log_error_errno(r, "Disk image %s is currently busy.", arg_image); + goto finish; + } + if (r < 0) { + r = log_error_errno(r, "Failed to create image lock: %m"); + goto finish; + } + if (!mkdtemp(template)) { log_error_errno(errno, "Failed to create temporary directory: %m"); r = -errno; @@ -3917,9 +3947,10 @@ int main(int argc, char *argv[]) { _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; char last_char = 0; - sd_notify(false, - "READY=1\n" - "STATUS=Container running."); + sd_notifyf(false, + "READY=1\n" + "STATUS=Container running.\n" + "X_NSPAWN_LEADER_PID=" PID_FMT, pid); r = sd_event_new(&event); if (r < 0) { @@ -4034,7 +4065,7 @@ finish: if (arg_machine) { const char *p; - p = strappenda("/run/systemd/nspawn/propagate", arg_machine); + p = strappenda("/run/systemd/nspawn/propagate/", arg_machine); (void) rm_rf(p, false, true, false); }