Bug 127932 - [unionfs] mkdir -p PATH fails if a directory in PATH is on a read-only unionfs
Summary: [unionfs] mkdir -p PATH fails if a directory in PATH is on a read-only unionfs
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-10-08 01:10 UTC by Till Toenges
Modified: 2018-05-21 00:02 UTC (History)
0 users

See Also:


Attachments
file.diff (438 bytes, patch)
2008-10-08 01:10 UTC, Till Toenges
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Till Toenges 2008-10-08 01:10:04 UTC
mkdir -p <path> fails if a directory in <path> is on a read-only fs. It tries to create every directory <subdir> in <path>, and ignores EEXIST and EISDIR errors, if <subdir> is a directory. But it treats EROFS as an error and exits.

Noticed it while trying to build a port in a jail, where the jails / was read-only union mounted in the directory containing the jails /var.

Fix: Treat EROFS like EISDIR and EEXIST.

Patch attached with submission follows:
How-To-Repeat: Assuming a read-only root, and /var mounted writable:

mkdir -p /var/db/ports/openldap24

fails.
Comment 1 Jaakko Heinonen 2008-10-31 17:01:13 UTC
Hi,

On 2008-10-08, Till Toenges wrote:
> Treat EROFS like EISDIR and EEXIST.
> 
> > 
> --- /usr/src/bin/mkdir/mkdir.c	2006-10-10 22:18:20.000000000 +0200
> +++ /root/mkdir/mkdir.c	2008-10-08 01:44:22.000000000 +0200
> @@ -177,7 +177,7 @@
>  		if (last)
>  			(void)umask(oumask);
>  		if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
> -			if (errno == EEXIST || errno == EISDIR) {
> +			if (errno == EEXIST || errno == EISDIR || errno == EROFS) {
>  				if (stat(path, &sb) < 0) {
>  					warn("%s", path);
>  					retval = 0;

This has patch has a problem. Patched mkdir(1) gives a bogus error
message if a directory creation fails on read-only file system.

$ mkdir -p foo (unpatched)
mkdir: foo: Read-only file system
$ mkdir -p foo (patched)
mkdir: foo: No such file or directory

The latter error message is very misleading because the real reason for
the failure is read-only file system.

Maybe save the original error number and if stat(2) fails in EROFS case
then use it instead of the error from stat(2). Something like this:

%%%
Index: bin/mkdir/mkdir.c
===================================================================
--- bin/mkdir/mkdir.c	(revision 183921)
+++ bin/mkdir/mkdir.c	(working copy)
@@ -140,7 +140,7 @@ build(char *path, mode_t omode)
 {
 	struct stat sb;
 	mode_t numask, oumask;
-	int first, last, retval;
+	int first, last, retval, serrno;
 	char *p;
 
 	p = path;
@@ -177,8 +177,12 @@ build(char *path, mode_t omode)
 		if (last)
 			(void)umask(oumask);
 		if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) {
-			if (errno == EEXIST || errno == EISDIR) {
+			if (errno == EEXIST || errno == EISDIR ||
+			    errno == EROFS) {
+				serrno = errno;
 				if (stat(path, &sb) < 0) {
+					if (serrno == EROFS)
+						errno = EROFS;
 					warn("%s", path);
 					retval = 0;
 					break;
%%%

-- 
Jaakko
Comment 2 Jaakko Heinonen freebsd_committer freebsd_triage 2009-10-31 08:47:40 UTC
State Changed
From-To: open->feedback

I was unable to reproduce the problem. I don't see how mkdir(2) could return 
EROFS if the file exists (even on read-only file system). Thus I don't see the 
need to patch mkdir(1). 

Can you still reproduce the problem? 


Comment 3 Jaakko Heinonen freebsd_committer freebsd_triage 2009-10-31 08:47:40 UTC
Responsible Changed
From-To: freebsd-bugs->jh

Track.
Comment 4 Jaakko Heinonen freebsd_committer freebsd_triage 2009-11-05 18:20:45 UTC
State Changed
From-To: feedback->analyzed

Now I see how this can happen with unionfs: unionfs_lookup() returns EROFS 
for CREATE namei operation when unionfs is mounted as read-only even if the 
file exists. 

I consider this a kernel (unionfs) problem and I don't think it's sensible to 
patch mkdir(1). 


Comment 5 Jaakko Heinonen freebsd_committer freebsd_triage 2009-11-05 18:20:45 UTC
Responsible Changed
From-To: jh->freebsd-bugs

Back to pool.
Comment 6 Eitan Adler freebsd_committer freebsd_triage 2018-05-20 23:59:50 UTC
For bugs matching the following conditions:
- Status == In Progress
- Assignee == "bugs@FreeBSD.org"
- Last Modified Year <= 2017

Do
- Set Status to "Open"