Skip to content

Commit 78f0b74

Browse files
committed
init: record exit code of the entrypoint
Use the newly added exit code recording feature in virtio-fs to record the exit code from workload's entrypoint. We need to stop ignoring SIGCHLD, as otherwise waitpid doesn't record the exit code of our child, which also means we need to do a waitpid on every children to ensure we aren't leaving zombie processes. Signed-off-by: Sergio Lopez <[email protected]>
1 parent ef0b0fb commit 78f0b74

File tree

1 file changed

+38
-8
lines changed

1 file changed

+38
-8
lines changed

init/init.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "tee/snp_attest.h"
2929
#endif
3030

31+
#define KRUN_EXIT_CODE_IOCTL 0x7602
32+
3133
#define KRUN_MAGIC "KRUN"
3234
#define KRUN_FOOTER_LEN 12
3335
#define CMDLINE_SECRET_PATH "/sfs/secrets/coco/cmdline"
@@ -954,10 +956,30 @@ int setup_redirects()
954956
return 0;
955957
}
956958

959+
void set_exit_code(int code)
960+
{
961+
int fd;
962+
int ret;
963+
964+
fd = open("/", O_RDONLY);
965+
if (fd < 0) {
966+
perror("Couldn't open root filesystem to report exit code");
967+
return;
968+
}
969+
970+
ret = ioctl(fd, KRUN_EXIT_CODE_IOCTL, code);
971+
if (ret < 0) {
972+
perror("Error using the ioctl to set the exit code");
973+
}
974+
975+
close(fd);
976+
}
977+
957978
int main(int argc, char **argv)
958979
{
959980
struct ifreq ifr;
960981
int sockfd;
982+
int status;
961983
char localhost[] = "localhost\0";
962984
char *hostname;
963985
char *krun_home;
@@ -1042,12 +1064,12 @@ int main(int argc, char **argv)
10421064

10431065
// We need to fork ourselves, because pid 1 cannot doesn't receive SIGINT
10441066
// signal
1045-
int pid = fork();
1046-
if (pid < 0) {
1067+
int child = fork();
1068+
if (child < 0) {
10471069
perror("fork");
10481070
exit(-3);
10491071
}
1050-
if (pid == 0) { // child
1072+
if (child == 0) { // child
10511073
if (setup_redirects() < 0) {
10521074
exit(-4);
10531075
}
@@ -1057,11 +1079,19 @@ int main(int argc, char **argv)
10571079
exit(-3);
10581080
}
10591081
} else { // parent
1060-
// tell the kernel we don't want to be notified on SIGCHLD so it'll reap
1061-
// our children for us
1062-
signal(SIGCHLD, SIG_IGN);
1063-
// wait for children since we can't exit init
1064-
waitpid(pid, NULL, 0);
1082+
// Wait until the workload's entrypoint has exited, ignoring any other
1083+
// children.
1084+
while (waitpid(-1, &status, 0) != child) {
1085+
// Not the first child, ignore it.
1086+
};
1087+
1088+
// The workload's entrypoint has exited, record its exit code and exit
1089+
// ourselves.
1090+
if (WIFEXITED(status)) {
1091+
set_exit_code(WEXITSTATUS(status));
1092+
} else if (WIFSIGNALED(status)) {
1093+
set_exit_code(WTERMSIG(status) + 128);
1094+
}
10651095
}
10661096

10671097
return 0;

0 commit comments

Comments
 (0)