Skip to content

Commit 067b833

Browse files
committed
libct/nsenter: add and use bailx
We use bail to report fatal errors, and bail always append %m (aka strerror(errno)). In case an error condition did not set errno, the log message will end up with ": Success" or an error from a stale errno value. Either case is confusing for users. Introduce bailx which is the same as bail except it does not append %m, and use it where appropriate. The naming follows libc's err(3) and errx(3). PS we still use bail in a few cases after read or write, even if that read/write did not return an error, because the code does not distinguish between short read/write and error (-1). This will be addressed by the next commit. Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent 9c8f476 commit 067b833

File tree

2 files changed

+37
-28
lines changed

2 files changed

+37
-28
lines changed

libcontainer/nsenter/log.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,20 @@ bool log_enabled_for(int level);
2626
void write_log(int level, const char *format, ...) __attribute__((format(printf, 2, 3)));
2727

2828
extern int logfd;
29-
#define bail(fmt, ...) \
30-
do { \
31-
if (logfd < 0) \
32-
fprintf(stderr, "FATAL: " fmt ": %m\n", \
33-
##__VA_ARGS__); \
34-
else \
35-
write_log(FATAL, fmt ": %m", ##__VA_ARGS__); \
36-
exit(1); \
29+
30+
/* bailx logs a message to logfd (or stderr, if logfd is not available)
31+
* and terminates the program.
32+
*/
33+
#define bailx(fmt, ...) \
34+
do { \
35+
if (logfd < 0) \
36+
fprintf(stderr, "FATAL: " fmt "\n", ##__VA_ARGS__); \
37+
else \
38+
write_log(FATAL, fmt, ##__VA_ARGS__); \
39+
exit(1); \
3740
} while(0)
3841

42+
/* bail is the same as bailx, except it also adds ": %m" (errno). */
43+
#define bail(fmt, ...) bailx(fmt ": %m", ##__VA_ARGS__)
3944

4045
#endif /* NSENTER_LOG_H */

libcontainer/nsenter/nsexec.c

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ static int try_mapping_tool(const char *app, int pid, char *map, size_t map_len)
208208
* or programming issue.
209209
*/
210210
if (!app)
211-
bail("mapping tool not present");
211+
bailx("mapping tool not present");
212212

213213
child = fork();
214214
if (child < 0)
@@ -274,7 +274,7 @@ static void update_uidmap(const char *path, int pid, char *map, size_t map_len)
274274
bail("failed to update /proc/%d/uid_map", pid);
275275
write_log(DEBUG, "update /proc/%d/uid_map got -EPERM (trying %s)", pid, path);
276276
if (try_mapping_tool(path, pid, map, map_len))
277-
bail("failed to use newuid map on %d", pid);
277+
bailx("failed to use newuid map on %d", pid);
278278
}
279279
}
280280

@@ -289,7 +289,7 @@ static void update_gidmap(const char *path, int pid, char *map, size_t map_len)
289289
bail("failed to update /proc/%d/gid_map", pid);
290290
write_log(DEBUG, "update /proc/%d/gid_map got -EPERM (trying %s)", pid, path);
291291
if (try_mapping_tool(path, pid, map, map_len))
292-
bail("failed to use newgid map on %d", pid);
292+
bailx("failed to use newgid map on %d", pid);
293293
}
294294
}
295295

@@ -340,14 +340,16 @@ static void nl_parse(int fd, struct nlconfig_t *config)
340340

341341
/* Retrieve the netlink header. */
342342
len = read(fd, &hdr, NLMSG_HDRLEN);
343+
if (len < 0)
344+
bail("failed to read netlink header");
343345
if (len != NLMSG_HDRLEN)
344-
bail("invalid netlink header length %zu", len);
346+
bailx("invalid netlink header length %zu", len);
345347

346348
if (hdr.nlmsg_type == NLMSG_ERROR)
347-
bail("failed to read netlink message");
349+
bailx("failed to read netlink message");
348350

349351
if (hdr.nlmsg_type != INIT_MSG)
350-
bail("unexpected msg type %d", hdr.nlmsg_type);
352+
bailx("unexpected msg type %d", hdr.nlmsg_type);
351353

352354
/* Retrieve data. */
353355
size = NLMSG_PAYLOAD(&hdr, 0);
@@ -356,8 +358,10 @@ static void nl_parse(int fd, struct nlconfig_t *config)
356358
bail("failed to allocate %zu bytes of memory for nl_payload", size);
357359

358360
len = read(fd, data, size);
361+
if (len < 0)
362+
bail("failed to read netlink payload");
359363
if (len != size)
360-
bail("failed to read netlink payload, %zu != %zu", len, size);
364+
bailx("failed to read netlink payload, %zu != %zu", len, size);
361365

362366
/* Parse the netlink payload. */
363367
config->data = data;
@@ -456,7 +460,7 @@ static int nstype(char *name)
456460
* without corresponding handling could result in broken behaviour) and
457461
* the rest of runc doesn't allow unknown namespace types anyway.
458462
*/
459-
bail("unknown namespace type %s", name);
463+
bailx("unknown namespace type %s", name);
460464
}
461465

462466
static nsset_t __open_namespaces(char *nsspec, struct namespace_t **ns_list, size_t *ns_len)
@@ -469,7 +473,7 @@ static nsset_t __open_namespaces(char *nsspec, struct namespace_t **ns_list, siz
469473
namespace = strtok_r(nsspec, ",", &saveptr);
470474

471475
if (!namespace || !strlen(namespace) || !strlen(nsspec))
472-
bail("ns paths are empty");
476+
bailx("ns paths are empty");
473477

474478
do {
475479
int fd;
@@ -485,7 +489,7 @@ static nsset_t __open_namespaces(char *nsspec, struct namespace_t **ns_list, siz
485489
/* Split 'ns:path'. */
486490
path = strstr(namespace, ":");
487491
if (!path)
488-
bail("failed to parse %s", namespace);
492+
bailx("failed to parse %s", namespace);
489493
*path++ = '\0';
490494

491495
fd = open(path, O_RDONLY);
@@ -530,7 +534,7 @@ static nsset_t __join_namespaces(nsset_t allow, struct namespace_t *ns_list, siz
530534
/* Skip permission errors. */
531535
if (saved_errno == EPERM)
532536
continue;
533-
bail("failed to setns into %s namespace", ns->type);
537+
bailx("failed to setns into %s namespace: %s", ns->type, strerror(saved_errno));
534538
}
535539
joined |= type;
536540

@@ -597,7 +601,7 @@ static void __close_namespaces(nsset_t to_join, nsset_t joined, struct namespace
597601

598602
/* Make sure we joined the namespaces we planned to. */
599603
if (failed_to_join)
600-
bail("failed to join {%s} namespaces: %s", nsset_to_str(failed_to_join), strerror(EPERM));
604+
bailx("failed to join {%s} namespaces: %s", nsset_to_str(failed_to_join), strerror(EPERM));
601605

602606
free(ns_list);
603607
}
@@ -936,7 +940,7 @@ void nsexec(void)
936940
stage1_complete = true;
937941
break;
938942
default:
939-
bail("unexpected sync value: %u", s);
943+
bailx("unexpected sync value: %u", s);
940944
}
941945
}
942946
write_log(DEBUG, "<- stage-1 synchronisation loop");
@@ -967,7 +971,7 @@ void nsexec(void)
967971
stage2_complete = true;
968972
break;
969973
default:
970-
bail("unexpected sync value: %u", s);
974+
bailx("unexpected sync value: %u", s);
971975
}
972976
}
973977
write_log(DEBUG, "<- stage-2 synchronisation loop");
@@ -1058,7 +1062,7 @@ void nsexec(void)
10581062
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
10591063
bail("failed to sync with parent: read(SYNC_USERMAP_ACK)");
10601064
if (s != SYNC_USERMAP_ACK)
1061-
bail("failed to sync with parent: SYNC_USERMAP_ACK: got %u", s);
1065+
bailx("failed to sync with parent: SYNC_USERMAP_ACK: got %u", s);
10621066

10631067
/* Revert temporary re-dumpable setting. */
10641068
if (config.namespaces) {
@@ -1094,7 +1098,7 @@ void nsexec(void)
10941098
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
10951099
bail("failed to sync with parent: read(SYNC_TIMEOFFSETS_ACK)");
10961100
if (s != SYNC_TIMEOFFSETS_ACK)
1097-
bail("failed to sync with parent: SYNC_TIMEOFFSETS_ACK: got %u", s);
1101+
bailx("failed to sync with parent: SYNC_TIMEOFFSETS_ACK: got %u", s);
10981102
}
10991103

11001104
/*
@@ -1130,7 +1134,7 @@ void nsexec(void)
11301134
}
11311135
if (s != SYNC_RECVPID_ACK) {
11321136
sane_kill(stage2_pid, SIGKILL);
1133-
bail("failed to sync with parent: SYNC_RECVPID_ACK: got %u", s);
1137+
bailx("failed to sync with parent: SYNC_RECVPID_ACK: got %u", s);
11341138
}
11351139

11361140
write_log(DEBUG, "signal completion to stage-0");
@@ -1177,7 +1181,7 @@ void nsexec(void)
11771181
if (read(syncfd, &s, sizeof(s)) != sizeof(s))
11781182
bail("failed to sync with parent: read(SYNC_GRANDCHILD)");
11791183
if (s != SYNC_GRANDCHILD)
1180-
bail("failed to sync with parent: SYNC_GRANDCHILD: got %u", s);
1184+
bailx("failed to sync with parent: SYNC_GRANDCHILD: got %u", s);
11811185

11821186
if (setsid() < 0)
11831187
bail("setsid failed");
@@ -1212,9 +1216,9 @@ void nsexec(void)
12121216
}
12131217
break;
12141218
default:
1215-
bail("unexpected jump value");
1219+
bailx("unexpected jump value");
12161220
}
12171221

12181222
/* Should never be reached. */
1219-
bail("should never be reached");
1223+
bailx("should never be reached");
12201224
}

0 commit comments

Comments
 (0)