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.
*
* Redistribution and use in source and binary forms, with or without
@ -109,22 +109,34 @@ die(const char *fmt, ...)
}
static int
ftw_cb(const char *fpath, const struct stat *sb UNUSED, int type,
struct FTW *ftwbuf UNUSED)
ftw_perms_cb(const char *fpath, const struct stat *sb 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) {
if (unlink(fpath) == -1)
sverrno = errno;
} else if (type == FTW_D || type == FTW_DNR || type == FTW_DP) {
if (rmdir(fpath) == -1)
sverrno = errno;
} else {
return 0;
}
if (sverrno != 0) {
fprintf(stderr, "Failed to remove %s: %s\n", fpath, strerror(sverrno));
static int
ftw_cb(const char *fpath, const struct stat *sb UNUSED,
int type UNUSED, struct FTW *ftwbuf UNUSED)
{
switch (type) {
case FTW_F:
case FTW_SL:
case FTW_SLN:
if (unlink(fpath) != 0) {
fprintf(stderr, "failed to remove %s: %s\n", fpath, strerror(errno));
}
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;
}
@ -132,17 +144,39 @@ ftw_cb(const char *fpath, const struct stat *sb UNUSED, int type,
static void
cleanup_overlayfs(void)
{
char *workdir;
if (tmpdir == NULL)
return;
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",
tmpdir, strerror(errno));
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);
}
@ -342,17 +376,16 @@ main(int argc, char **argv)
die("failed to create tmpdir directory");
if (chown(tmpdir, ruid, rgid) == -1)
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);
container_flags = clone_flags & ~(CLONE_NEWNS|CLONE_NEWIPC|CLONE_NEWUTS|CLONE_NEWPID);