On 05/13/2013 10:05 AM, Jan Safranek wrote: > On 05/12/2013 02:08 PM, Ivana Varekova wrote: >> Seems ok for me, Jan could you look at it pleas? >> Ivana >> >> ----- Original Message ----- >>> From: "Peter Schiffer" <pschi...@redhat.com> >>> To: libcg-devel@lists.sourceforge.net >>> Sent: Monday, February 11, 2013 6:09:02 PM >>> Subject: [Libcg-devel] [PATCH] Make cg_mkdir_p() function compatible with >>> read-only fs >>> >>> mkdir(2) function returns EROFS error even when the path already exists on >>> the >>> read only file system, so it is impossible to determine whether the path >>> already >>> exists on this kind of fs only be return code from the mkdir(2). To make >>> cg_mkdir_p() compatible with the ro fs, the function checks whether the path >>> exists with stat(2) before trying to create it. >>> >>> Signed-off-by: Peter Schiffer <pschi...@redhat.com> >>> --- >>> 0 files changed >>> >>> diff --git a/src/api.c b/src/api.c >>> index 11cd1b4..4acdc30 100644 >>> --- a/src/api.c >>> +++ b/src/api.c >>> @@ -1271,6 +1271,7 @@ int cg_mkdir_p(const char *path) >>> int i = 0; >>> char pos; >>> int ret = 0; >>> + struct stat st; >>> >>> real_path = strdup(path); >>> if (!real_path) { >>> @@ -1287,6 +1288,10 @@ int cg_mkdir_p(const char *path) >>> i++; >>> pos = real_path[i]; >>> real_path[i] = '\0'; /* Temporarily overwrite "/" */ >>> + if (stat(real_path, &st) == 0) { /* Continue if >>> dir exists */ >>> + real_path[i] = pos; >>> + continue; >>> + } > > I think this code is racy. There can be a change between stat() and > mkdir(). Shouldn't mkdir() return EEXIST is the directory already > exists? Please check/test it. If it still returns EROFS in this case, > then I ack this patch, there is no other way how to do it. > >>> ret = mkdir(real_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); >>> real_path[i] = pos; >>> if (ret) { >
There is updated version of this patch, which shouldn't be racy, see below. I can confirm that mkdir() returns EROFS on read-only fs even when the directory exists. peter diff --git a/src/api.c b/src/api.c index 11cd1b4..b5bbb74 100644 --- a/src/api.c +++ b/src/api.c @@ -1270,7 +1270,8 @@ int cg_mkdir_p(const char *path) char *real_path = NULL; int i = 0; char pos; - int ret = 0; + int ret = 0, stat_ret; + struct stat st; real_path = strdup(path); if (!real_path) { @@ -1298,6 +1299,14 @@ int cg_mkdir_p(const char *path) ret = ECGROUPNOTOWNER; goto done; default: + /* Check if path exists */ + real_path[i] = '\0'; + stat_ret = stat(real_path, &st); + real_path[i] = pos; + if (stat_ret == 0) { + ret = 0; /* Path exists */ + break; + } ret = ECGROUPNOTALLOWED; goto done; } ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. This 200-page book is written by three acclaimed leaders in the field. The early access version is available now. Download your free book today! http://p.sf.net/sfu/neotech_d2d_may _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel