mirror of
https://codeberg.org/guix/guix.git
synced 2025-10-02 02:15:12 +00:00
daemon: Gracefully handle target mount point already existing.
Fixes guix/guix#903. * nix/libutil/spawn.cc (bindMount): in the "regular file" case, only create a placeholder file if one doesn't already exist. Change-Id: Ie46b2fef2cea5b2a052c4ec48d00e97bfc1ee506 Reported-by: Hilton Chain <hako@ultrarare.space> Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
parent
6b42df3ad6
commit
05a669efa5
1 changed files with 24 additions and 1 deletions
|
@ -538,8 +538,31 @@ void bindMount(Path source, Path target, bool readOnly)
|
|||
return;
|
||||
}
|
||||
else {
|
||||
struct stat st2;
|
||||
createDirs(dirOf(target));
|
||||
writeFile(target, "");
|
||||
/* Alternate between trying to create placeholder file at target and
|
||||
* checking for its existence and type */
|
||||
while(true){
|
||||
if(lstat(target.c_str(), &st2) != -1) {
|
||||
if(!S_ISREG(st2.st_mode))
|
||||
throw Error(format("mount target `%1%' exists but is not a regular file") % target);
|
||||
break;
|
||||
}
|
||||
if(errno != ENOENT) {
|
||||
throw SysError(format("stat'ing path `%1%'") % target);
|
||||
}
|
||||
AutoCloseFD fd = open(target.c_str(),
|
||||
O_WRONLY | O_NOFOLLOW | O_CREAT | O_EXCL,
|
||||
0600);
|
||||
if(fd != -1) {
|
||||
fd.close(); /* Now exists and is a fresh regular file */
|
||||
break;
|
||||
}
|
||||
/* Note: because of O_CREAT | O_EXCL, EACCES can only mean a
|
||||
* permission issue with the parent directory */
|
||||
if(errno != EEXIST)
|
||||
throw SysError(format("Creating placeholder regular file target mount `%1%'") % target);
|
||||
}
|
||||
}
|
||||
|
||||
/* This may fail with EINVAL unless we specify MS_REC, specifically if we
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue