" --network-macvlan=INTERFACE\n"
" Create a macvlan network interface based on an\n"
" existing network interface to the container\n"
- " --network-veth Add a virtual ethernet connection between host\n"
+ " -n --network-veth Add a virtual ethernet connection between host\n"
" and container\n"
" --network-bridge=INTERFACE\n"
" Add a virtual ethernet connection between host\n"
" and container and add it to an existing bridge on\n"
" the host\n"
" -p --port=[PROTOCOL:]HOSTPORT[:CONTAINERPORT]\n"
- " Expose a container IP port ont the host\n"
+ " Expose a container IP port on the host\n"
" -Z --selinux-context=SECLABEL\n"
" Set the SELinux security context to be used by\n"
" processes in the container\n"
ARG_KEEP_UNIT,
ARG_NETWORK_INTERFACE,
ARG_NETWORK_MACVLAN,
- ARG_NETWORK_VETH,
ARG_NETWORK_BRIDGE,
ARG_PERSONALITY,
ARG_VOLATILE,
{ "keep-unit", no_argument, NULL, ARG_KEEP_UNIT },
{ "network-interface", required_argument, NULL, ARG_NETWORK_INTERFACE },
{ "network-macvlan", required_argument, NULL, ARG_NETWORK_MACVLAN },
- { "network-veth", no_argument, NULL, ARG_NETWORK_VETH },
+ { "network-veth", no_argument, NULL, 'n' },
{ "network-bridge", required_argument, NULL, ARG_NETWORK_BRIDGE },
{ "personality", required_argument, NULL, ARG_PERSONALITY },
{ "image", required_argument, NULL, 'i' },
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:qi:xp:", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:qi:xp:n", options, NULL)) >= 0)
switch (c) {
/* fall through */
- case ARG_NETWORK_VETH:
+ case 'n':
arg_network_veth = true;
arg_private_network = true;
break;
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);
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();
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
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);
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) {
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;
_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) {
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);
}