After a successful creation of a directory, if some other call results
in returning a failure, let's remove the directory we created to
prevent another round trip or confusion in the caller. In particular, this
function can be called during a storage backend buildVol, so in order
to ensure that caller doesn't need to distinguish between failed create
or some other failure after create, just remove the directory we created.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
src/util/virfile.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 51198e2..2cb2469 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -2420,6 +2420,7 @@ virDirCreateNoFork(const char *path,
{
int ret = 0;
struct stat st;
+ bool created = false;
if (!((flags & VIR_DIR_CREATE_ALLOW_EXIST) && virFileExists(path))) {
if (mkdir(path, mode) < 0) {
@@ -2428,6 +2429,7 @@ virDirCreateNoFork(const char *path,
path);
goto error;
}
+ created = true;
}
if (stat(path, &st) == -1) {
@@ -2451,6 +2453,8 @@ virDirCreateNoFork(const char *path,
goto error;
}
error:
+ if (ret < 0 && created)
+ rmdir(path);
return ret;
}
@@ -2465,6 +2469,7 @@ virDirCreate(const char *path,
int status = 0, ret = 0;
gid_t *groups;
int ngroups;
+ bool created = false;
/* Everything after this check is crazyness to allow setting uid/gid
* on directories that are on root-squash NFS shares. We only want
@@ -2552,6 +2557,7 @@ virDirCreate(const char *path,
}
goto childerror;
}
+ created = true;
/* check if group was set properly by creating after
* setgid. If not, try doing it with chown */
@@ -2578,6 +2584,9 @@ virDirCreate(const char *path,
}
childerror:
+ if (ret != 0 && created)
+ rmdir(path);
+
if ((ret & 0xff) != ret) {
VIR_WARN("unable to pass desired return value %d", ret);
ret = 0xff;
--
2.1.0