From nobody@FreeBSD.org  Wed Oct  8 00:09:51 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 455DF1065693
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  8 Oct 2008 00:09:51 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 3398E8FC19
	for <freebsd-gnats-submit@FreeBSD.org>; Wed,  8 Oct 2008 00:09:51 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id m9809owe035954
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 8 Oct 2008 00:09:50 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id m9809oMp035952;
	Wed, 8 Oct 2008 00:09:50 GMT
	(envelope-from nobody)
Message-Id: <200810080009.m9809oMp035952@www.freebsd.org>
Date: Wed, 8 Oct 2008 00:09:50 GMT
From: Till Toenges <tt@kyon.de>
To: freebsd-gnats-submit@FreeBSD.org
Subject: mkdir -p PATH fails if a directory in PATH is on a read-only fs
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         127932
>Category:       bin
>Synopsis:       [unionfs] mkdir -p PATH fails if a directory in PATH is on a read-only unionfs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          analyzed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 08 00:10:04 UTC 2008
>Closed-Date:    
>Last-Modified:  Thu Nov 05 18:29:44 UTC 2009
>Originator:     Till Toenges
>Release:        7.0
>Organization:
ky-on
>Environment:
FreeBSD deusexmachina.kyon.de 7.0-RELEASE FreeBSD 7.0-RELEASE #0: Mon Oct  6 12:44:33 UTC 2008     root@dyn1-166.cicely.de:/usr/src/sys/amd64/compile/MAIL  amd64
>Description:
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.
>How-To-Repeat:
Assuming a read-only root, and /var mounted writable:

mkdir -p /var/db/ports/openldap24

fails.
>Fix:
Treat EROFS like EISDIR and EEXIST.

Patch attached with submission follows:

--- /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;


>Release-Note:
>Audit-Trail:

From: Jaakko Heinonen <jh@saunalahti.fi>
To: Till Toenges <tt@kyon.de>
Cc: bug-followup@freebsd.org
Subject: Re: bin/127932: mkdir -p PATH fails if a directory in PATH is on a
	read-only fs
Date: Fri, 31 Oct 2008 19:01:13 +0200

 Hi,
 
 On 2008-10-08, Till Toenges wrote:
 > Treat EROFS like EISDIR and EEXIST.
 > 
 > Patch attached with submission follows:
 > 
 > --- /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
State-Changed-From-To: open->feedback 
State-Changed-By: jh 
State-Changed-When: Sat Oct 31 08:47:40 UTC 2009 
State-Changed-Why:  
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? 


Responsible-Changed-From-To: freebsd-bugs->jh 
Responsible-Changed-By: jh 
Responsible-Changed-When: Sat Oct 31 08:47:40 UTC 2009 
Responsible-Changed-Why:  
Track. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=127932 
State-Changed-From-To: feedback->analyzed 
State-Changed-By: jh 
State-Changed-When: Thu Nov 5 18:20:45 UTC 2009 
State-Changed-Why:  
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). 


Responsible-Changed-From-To: jh->freebsd-bugs 
Responsible-Changed-By: jh 
Responsible-Changed-When: Thu Nov 5 18:20:45 UTC 2009 
Responsible-Changed-Why:  
Back to pool. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=127932 
>Unformatted:
