xbps-uchroot: make sure to cleanup tempdir with overlayfs.

Go modules seem to have too restrictive permissions on
its builddir, making xbps-uchroot(1) unable to remove
its directory tree due to insufficient permissions.

Run nftw() twice, the first run to set chmod 755, and
second run to remove the file.

Fixes `xbps-src -t` with any pkg that uses `build_style=go`.

This should avoid lots of temp dirs in the buildbot
builders while building go modules and others.
This commit is contained in:
Juan RP 2020-02-04 13:17:26 +01:00
parent adebbf71e2
commit f6a6385b42
No known key found for this signature in database
GPG Key ID: AF19F6CB482F9368

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright (c) 2014-2015 Juan Romero Pardines. * Copyright (c) 2014-2020 Juan Romero Pardines.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -109,22 +109,34 @@ die(const char *fmt, ...)
} }
static int static int
ftw_cb(const char *fpath, const struct stat *sb UNUSED, int type, ftw_perms_cb(const char *fpath, const struct stat *sb UNUSED,
struct FTW *ftwbuf UNUSED) int type UNUSED, struct FTW *ftwbuf UNUSED)
{ {
int sverrno = 0; chmod(fpath, 0755);
return 0;
}
if (type == FTW_F || type == FTW_SL || type == FTW_SLN) { static int
if (unlink(fpath) == -1) ftw_cb(const char *fpath, const struct stat *sb UNUSED,
sverrno = errno; int type UNUSED, struct FTW *ftwbuf UNUSED)
} else if (type == FTW_D || type == FTW_DNR || type == FTW_DP) { {
if (rmdir(fpath) == -1) switch (type) {
sverrno = errno; case FTW_F:
} else { case FTW_SL:
return 0; case FTW_SLN:
} if (unlink(fpath) != 0) {
if (sverrno != 0) { fprintf(stderr, "failed to remove %s: %s\n", fpath, strerror(errno));
fprintf(stderr, "Failed to remove %s: %s\n", fpath, strerror(sverrno)); }
break;
case FTW_D:
case FTW_DP:
case FTW_DNR:
if (rmdir(fpath) != 0) {
fprintf(stderr, "failed to remove %s: %s\n", fpath, strerror(errno));
}
break;
default:
break;
} }
return 0; return 0;
} }
@ -132,17 +144,39 @@ ftw_cb(const char *fpath, const struct stat *sb UNUSED, int type,
static void static void
cleanup_overlayfs(void) cleanup_overlayfs(void)
{ {
char *workdir;
if (tmpdir == NULL) if (tmpdir == NULL)
return; return;
if (!overlayfs_on_tmpfs) { if (!overlayfs_on_tmpfs) {
/* recursively remove the temporary dir */ /*
if (nftw(tmpdir, ftw_cb, 20, FTW_MOUNT|FTW_PHYS|FTW_DEPTH) != 0) { * nftw() runs twice because the first run
* chmods all files and directories to be 755,
* so that second run can remove all them.
*
* Go modules in xbps-src seem to have too
* restrictive permissions and this cleans up
* this mess.
*/
if (nftw(tmpdir, ftw_perms_cb, 256, FTW_MOUNT|FTW_PHYS|FTW_DEPTH) != 0) {
fprintf(stderr, "Failed to remove directory tree %s: %s\n",
tmpdir, strerror(errno));
exit(EXIT_FAILURE);
}
if (nftw(tmpdir, ftw_cb, 256, FTW_MOUNT|FTW_PHYS|FTW_DEPTH) != 0) {
fprintf(stderr, "Failed to remove directory tree %s: %s\n", fprintf(stderr, "Failed to remove directory tree %s: %s\n",
tmpdir, strerror(errno)); tmpdir, strerror(errno));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
workdir = xbps_xasprintf("%s/workdir/work", tmpdir);
chmod(workdir, 0755);
rmdir(workdir);
free(workdir);
workdir = xbps_xasprintf("%s/workdir", tmpdir);
rmdir(workdir);
free(workdir);
rmdir(tmpdir); rmdir(tmpdir);
} }
@ -342,17 +376,16 @@ main(int argc, char **argv)
die("failed to create tmpdir directory"); die("failed to create tmpdir directory");
if (chown(tmpdir, ruid, rgid) == -1) if (chown(tmpdir, ruid, rgid) == -1)
die("chown tmpdir %s", tmpdir); die("chown tmpdir %s", tmpdir);
/*
* Register a signal handler to clean up temporary masterdir.
*/
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sighandler_cleanup;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
} }
/*
* Register a signal handler to clean up temporary masterdir.
*/
memset(&sa, 0, sizeof(sa));
sa.sa_handler = sighandler_cleanup;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
clone_flags = (SIGCHLD|CLONE_NEWNS|CLONE_NEWIPC|CLONE_NEWUTS|CLONE_NEWPID); clone_flags = (SIGCHLD|CLONE_NEWNS|CLONE_NEWIPC|CLONE_NEWUTS|CLONE_NEWPID);
container_flags = clone_flags & ~(CLONE_NEWNS|CLONE_NEWIPC|CLONE_NEWUTS|CLONE_NEWPID); container_flags = clone_flags & ~(CLONE_NEWNS|CLONE_NEWIPC|CLONE_NEWUTS|CLONE_NEWPID);