X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=d01da45930ce1900777c6248ecaa8a6e650a086a;hp=e75cc28074ac1b01bca67b005d0588e2670c507b;hb=4f758c23981342f1fb838f4b2630812eb89a3faa;hpb=a2da110b78abe4e4b1b6d8ae4ef78b087c4dcc8b diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index e75cc2807..d01da4593 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -166,8 +166,7 @@ static unsigned long arg_personality = 0xffffffffLU; static const char *arg_image = NULL; static Volatile arg_volatile = VOLATILE_NO; -static int help(void) { - +static void help(void) { printf("%s [OPTIONS...] [PATH] [ARGUMENTS...]\n\n" "Spawn a minimal namespace container for debugging, testing and building.\n\n" " -h --help Show this help\n" @@ -216,8 +215,6 @@ static int help(void) { " the service unit nspawn is running in\n" " --volatile[=MODE] Run the system in volatile mode\n", program_invocation_short_name); - - return 0; } static int parse_argv(int argc, char *argv[]) { @@ -285,12 +282,13 @@ static int parse_argv(int argc, char *argv[]) { assert(argc >= 0); assert(argv); - while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:qi:", options, NULL)) >= 0) { + while ((c = getopt_long(argc, argv, "+hD:u:bL:M:jS:Z:qi:", options, NULL)) >= 0) switch (c) { case 'h': - return help(); + help(); + return 0; case ARG_VERSION: puts(PACKAGE_STRING); @@ -395,7 +393,7 @@ static int parse_argv(int argc, char *argv[]) { case ARG_CAPABILITY: case ARG_DROP_CAPABILITY: { - char *state, *word; + const char *state, *word; size_t length; FOREACH_WORD_SEPARATOR(word, length, optarg, ",", state) { @@ -593,7 +591,6 @@ static int parse_argv(int argc, char *argv[]) { default: assert_not_reached("Unhandled option"); } - } if (arg_share_system) arg_register = false; @@ -1389,7 +1386,7 @@ static int drop_capabilities(void) { static int register_machine(pid_t pid, int local_ifindex) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_bus_close_unref_ sd_bus *bus = NULL; int r; if (!arg_register) @@ -1524,7 +1521,7 @@ static int register_machine(pid_t pid, int local_ifindex) { static int terminate_machine(pid_t pid) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - _cleanup_bus_unref_ sd_bus *bus = NULL; + _cleanup_bus_close_unref_ sd_bus *bus = NULL; const char *path; int r; @@ -1609,9 +1606,10 @@ static int reset_audit_loginuid(void) { return 0; } -#define HASH_KEY SD_ID128_MAKE(c3,c4,f9,19,b5,57,b2,1c,e6,cf,14,27,03,9c,ee,a2) +#define HOST_HASH_KEY SD_ID128_MAKE(1a,37,6f,c7,46,ec,45,0b,ad,a3,d5,31,06,60,5d,b1) +#define CONTAINER_HASH_KEY SD_ID128_MAKE(c3,c4,f9,19,b5,57,b2,1c,e6,cf,14,27,03,9c,ee,a2) -static int get_mac(struct ether_addr *mac) { +static int generate_mac(struct ether_addr *mac, sd_id128_t hash_key) { int r; uint8_t result[8]; @@ -1633,7 +1631,7 @@ static int get_mac(struct ether_addr *mac) { /* Let's hash the host machine ID plus the container name. We * use a fixed, but originally randomly created hash key here. */ - siphash24(result, v, sz, HASH_KEY.bytes); + siphash24(result, v, sz, hash_key.bytes); assert_cc(ETH_ALEN <= sizeof(result)); memcpy(mac->ether_addr_octet, result, ETH_ALEN); @@ -1648,7 +1646,7 @@ static int get_mac(struct ether_addr *mac) { static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ], int *ifi) { _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL; - struct ether_addr mac; + struct ether_addr mac_host, mac_container; int r, i; if (!arg_private_network) @@ -1659,15 +1657,18 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ], int *ifi) { /* Use two different interface name prefixes depending whether * we are in bridge mode or not. */ - if (arg_network_bridge) - memcpy(iface_name, "vb-", 3); - else - memcpy(iface_name, "ve-", 3); - strncpy(iface_name+3, arg_machine, IFNAMSIZ - 3); + snprintf(iface_name, IFNAMSIZ, "%s-%s", + arg_network_bridge ? "vb" : "ve", arg_machine); - r = get_mac(&mac); + r = generate_mac(&mac_container, CONTAINER_HASH_KEY); if (r < 0) { - log_error("Failed to generate predictable MAC address for host0"); + log_error("Failed to generate predictable MAC address for container side"); + return r; + } + + r = generate_mac(&mac_host, HOST_HASH_KEY); + if (r < 0) { + log_error("Failed to generate predictable MAC address for host side"); return r; } @@ -1689,6 +1690,12 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ], int *ifi) { return r; } + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, &mac_host); + if (r < 0) { + log_error("Failed to add netlink MAC address: %s", strerror(-r)); + return r; + } + r = sd_rtnl_message_open_container(m, IFLA_LINKINFO); if (r < 0) { log_error("Failed to open netlink container: %s", strerror(-r)); @@ -1713,7 +1720,7 @@ static int setup_veth(pid_t pid, char iface_name[IFNAMSIZ], int *ifi) { return r; } - r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, &mac); + r = sd_rtnl_message_append_ether_addr(m, IFLA_ADDRESS, &mac_container); if (r < 0) { log_error("Failed to add netlink MAC address: %s", strerror(-r)); return r; @@ -2602,7 +2609,8 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) { } static int change_uid_gid(char **_home) { - char line[LINE_MAX], *w, *x, *state, *u, *g, *h; + char line[LINE_MAX], *x, *u, *g, *h; + const char *word, *state; _cleanup_free_ uid_t *uids = NULL; _cleanup_free_ char *home = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -2752,10 +2760,10 @@ static int change_uid_gid(char **_home) { x += strcspn(x, WHITESPACE); x += strspn(x, WHITESPACE); - FOREACH_WORD(w, l, x, state) { + FOREACH_WORD(word, l, x, state) { char c[l+1]; - memcpy(c, w, l); + memcpy(c, word, l); c[l] = 0; if (!GREEDY_REALLOC(uids, sz, n_uids+1)) @@ -3073,13 +3081,13 @@ int main(int argc, char *argv[]) { for (;;) { ContainerStatus container_status; - _barrier_destroy_ Barrier barrier = { }; + _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL; struct sigaction sa = { .sa_handler = nop_handler, .sa_flags = SA_NOCLDSTOP, }; - r = barrier_init(&barrier); + r = barrier_create(&barrier); if (r < 0) { log_error("Cannot initialize IPC barrier: %s", strerror(-r)); goto finish;