mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
storage: On error rmdir created directory in virDirCreate[NoFork]
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@redhat.com>
This commit is contained in:
parent
695562154f
commit
21eb897241
@ -2421,7 +2421,15 @@ virFileRemove(const char *path,
|
||||
}
|
||||
|
||||
|
||||
/* return -errno on failure, or 0 on success */
|
||||
/* Attempt to create a directory and possibly adjust its owner/group and
|
||||
* permissions.
|
||||
*
|
||||
* return 0 on success or -errno on failure. Additionally to avoid another
|
||||
* round-trip to remove the directory on failure, perform the rmdir when
|
||||
* a mkdir was successful, but some other failure would cause a -1 return.
|
||||
* The storage driver buildVol backend function expects the directory to
|
||||
* be deleted on error.
|
||||
*/
|
||||
static int
|
||||
virDirCreateNoFork(const char *path,
|
||||
mode_t mode, uid_t uid, gid_t gid,
|
||||
@ -2429,6 +2437,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) {
|
||||
@ -2437,6 +2446,7 @@ virDirCreateNoFork(const char *path,
|
||||
path);
|
||||
goto error;
|
||||
}
|
||||
created = true;
|
||||
}
|
||||
|
||||
if (stat(path, &st) == -1) {
|
||||
@ -2460,10 +2470,30 @@ virDirCreateNoFork(const char *path,
|
||||
goto error;
|
||||
}
|
||||
error:
|
||||
if (ret < 0 && created)
|
||||
rmdir(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return -errno on failure, or 0 on success */
|
||||
/*
|
||||
* virDirCreate:
|
||||
* @path: directory to create
|
||||
* @mode: mode to use on creation or when forcing permissions
|
||||
* @uid: uid that should own directory
|
||||
* @gid: gid that should own directory
|
||||
* @flags: bit-wise or of VIR_DIR_CREATE_* flags
|
||||
*
|
||||
* Attempt to create a directory and possibly adjust its owner/group and
|
||||
* permissions. If conditions allow, use the *NoFork code in order to create
|
||||
* the directory under current owner/group rather than via a forked process.
|
||||
*
|
||||
* return 0 on success or -errno on failure. Additionally to avoid another
|
||||
* round-trip to remove the directory on failure, perform the rmdir if a
|
||||
* mkdir was successful, but some other failure would cause a -1 return.
|
||||
* The storage driver buildVol backend function expects the directory to
|
||||
* be deleted on error.
|
||||
*
|
||||
*/
|
||||
int
|
||||
virDirCreate(const char *path,
|
||||
mode_t mode, uid_t uid, gid_t gid,
|
||||
@ -2474,6 +2504,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
|
||||
@ -2561,6 +2592,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 */
|
||||
@ -2587,6 +2619,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;
|
||||
|
Loading…
Reference in New Issue
Block a user