提交 2ad04f78 编写于 作者: L Laine Stump

Change virFileOperation to return -errno (ie < 0) on error.

virFileOperation previously returned 0 on success, or the value of
errno on failure. Although there are other functions in libvirt that
use this convention, the preferred (and more common) convention is to
return 0 on success and -errno (or simply -1 in some cases) on
failure. This way the check for failure is always (ret < 0).

* src/util/util.c - change virFileOperation and virFileOperationNoFork to
                    return -errno on failure.

* src/storage/storage_backend.c, src/qemu/qemu_driver.c
  - change the hook functions passed to virFileOperation to return
    -errno on failure.
上级 ee0684ab
...@@ -4992,12 +4992,13 @@ struct fileOpHookData { ...@@ -4992,12 +4992,13 @@ struct fileOpHookData {
struct qemud_save_header *header; struct qemud_save_header *header;
}; };
/* return -errno on failure, or 0 on success */
static int qemudDomainSaveFileOpHook(int fd, void *data) { static int qemudDomainSaveFileOpHook(int fd, void *data) {
struct fileOpHookData *hdata = data; struct fileOpHookData *hdata = data;
int ret = 0; int ret = 0;
if (safewrite(fd, hdata->header, sizeof(*hdata->header)) != sizeof(*hdata->header)) { if (safewrite(fd, hdata->header, sizeof(*hdata->header)) != sizeof(*hdata->header)) {
ret = errno; ret = -errno;
qemuReportError(VIR_ERR_OPERATION_FAILED, qemuReportError(VIR_ERR_OPERATION_FAILED,
_("failed to write header to domain save file '%s'"), _("failed to write header to domain save file '%s'"),
hdata->path); hdata->path);
...@@ -5005,7 +5006,7 @@ static int qemudDomainSaveFileOpHook(int fd, void *data) { ...@@ -5005,7 +5006,7 @@ static int qemudDomainSaveFileOpHook(int fd, void *data) {
} }
if (safewrite(fd, hdata->xml, hdata->header->xml_len) != hdata->header->xml_len) { if (safewrite(fd, hdata->xml, hdata->header->xml_len) != hdata->header->xml_len) {
ret = errno; ret = -errno;
qemuReportError(VIR_ERR_OPERATION_FAILED, qemuReportError(VIR_ERR_OPERATION_FAILED,
_("failed to write xml to '%s'"), hdata->path); _("failed to write xml to '%s'"), hdata->path);
goto endjob; goto endjob;
...@@ -5141,7 +5142,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path, ...@@ -5141,7 +5142,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
virReportSystemError(errno, _("unable to open %s"), path); virReportSystemError(errno, _("unable to open %s"), path);
goto endjob; goto endjob;
} }
if (qemudDomainSaveFileOpHook(fd, &hdata) != 0) { if (qemudDomainSaveFileOpHook(fd, &hdata) < 0) {
close(fd); close(fd);
goto endjob; goto endjob;
} }
...@@ -5154,7 +5155,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path, ...@@ -5154,7 +5155,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
S_IRUSR|S_IWUSR, S_IRUSR|S_IWUSR,
getuid(), getgid(), getuid(), getgid(),
qemudDomainSaveFileOpHook, &hdata, qemudDomainSaveFileOpHook, &hdata,
0)) != 0) { 0)) < 0) {
/* If we failed as root, and the error was permission-denied /* If we failed as root, and the error was permission-denied
(EACCES), assume it's on a network-connected share where (EACCES), assume it's on a network-connected share where
root access is restricted (eg, root-squashed NFS). If the root access is restricted (eg, root-squashed NFS). If the
...@@ -5162,9 +5163,9 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path, ...@@ -5162,9 +5163,9 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
bypass security driver shenanigans, and retry the operation bypass security driver shenanigans, and retry the operation
after doing setuid to qemu user */ after doing setuid to qemu user */
if ((rc != EACCES) || if ((rc != -EACCES) ||
driver->user == getuid()) { driver->user == getuid()) {
virReportSystemError(rc, _("Failed to create domain save file '%s'"), virReportSystemError(-rc, _("Failed to create domain save file '%s'"),
path); path);
goto endjob; goto endjob;
} }
...@@ -5188,7 +5189,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path, ...@@ -5188,7 +5189,7 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
case 0: case 0:
default: default:
/* local file - log the error returned by virFileOperation */ /* local file - log the error returned by virFileOperation */
virReportSystemError(rc, virReportSystemError(-rc,
_("Failed to create domain save file '%s'"), _("Failed to create domain save file '%s'"),
path); path);
goto endjob; goto endjob;
...@@ -5202,8 +5203,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path, ...@@ -5202,8 +5203,8 @@ static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,
driver->user, driver->group, driver->user, driver->group,
qemudDomainSaveFileOpHook, &hdata, qemudDomainSaveFileOpHook, &hdata,
VIR_FILE_OP_AS_UID)) != 0) { VIR_FILE_OP_AS_UID)) < 0) {
virReportSystemError(rc, _("Error from child process creating '%s'"), virReportSystemError(-rc, _("Error from child process creating '%s'"),
path); path);
goto endjob; goto endjob;
} }
......
...@@ -276,7 +276,7 @@ static int createRawFileOpHook(int fd, void *data) { ...@@ -276,7 +276,7 @@ static int createRawFileOpHook(int fd, void *data) {
/* Seek to the final size, so the capacity is available upfront /* Seek to the final size, so the capacity is available upfront
* for progress reporting */ * for progress reporting */
if (ftruncate(fd, hdata->vol->capacity) < 0) { if (ftruncate(fd, hdata->vol->capacity) < 0) {
ret = errno; ret = -errno;
virReportSystemError(errno, virReportSystemError(errno,
_("cannot extend file '%s'"), _("cannot extend file '%s'"),
hdata->vol->target.path); hdata->vol->target.path);
...@@ -286,10 +286,9 @@ static int createRawFileOpHook(int fd, void *data) { ...@@ -286,10 +286,9 @@ static int createRawFileOpHook(int fd, void *data) {
remain = hdata->vol->allocation; remain = hdata->vol->allocation;
if (hdata->inputvol) { if (hdata->inputvol) {
int res = virStorageBackendCopyToFD(hdata->vol, hdata->inputvol, ret = virStorageBackendCopyToFD(hdata->vol, hdata->inputvol,
fd, &remain, 1); fd, &remain, 1);
if (res < 0) { if (ret < 0) {
ret = -res;
goto cleanup; goto cleanup;
} }
} }
...@@ -308,7 +307,7 @@ static int createRawFileOpHook(int fd, void *data) { ...@@ -308,7 +307,7 @@ static int createRawFileOpHook(int fd, void *data) {
bytes = remain; bytes = remain;
if (safezero(fd, 0, hdata->vol->allocation - remain, if (safezero(fd, 0, hdata->vol->allocation - remain,
bytes) != 0) { bytes) != 0) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("cannot fill file '%s'"), virReportSystemError(errno, _("cannot fill file '%s'"),
hdata->vol->target.path); hdata->vol->target.path);
goto cleanup; goto cleanup;
...@@ -317,7 +316,7 @@ static int createRawFileOpHook(int fd, void *data) { ...@@ -317,7 +316,7 @@ static int createRawFileOpHook(int fd, void *data) {
} }
} else { /* No progress bars to be shown */ } else { /* No progress bars to be shown */
if (safezero(fd, 0, 0, remain) != 0) { if (safezero(fd, 0, 0, remain) != 0) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("cannot fill file '%s'"), virReportSystemError(errno, _("cannot fill file '%s'"),
hdata->vol->target.path); hdata->vol->target.path);
goto cleanup; goto cleanup;
...@@ -327,7 +326,7 @@ static int createRawFileOpHook(int fd, void *data) { ...@@ -327,7 +326,7 @@ static int createRawFileOpHook(int fd, void *data) {
} }
if (fsync(fd) < 0) { if (fsync(fd) < 0) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("cannot sync data to file '%s'"), virReportSystemError(errno, _("cannot sync data to file '%s'"),
hdata->vol->target.path); hdata->vol->target.path);
goto cleanup; goto cleanup;
...@@ -365,7 +364,7 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -365,7 +364,7 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
VIR_FILE_OP_FORCE_PERMS | VIR_FILE_OP_FORCE_PERMS |
(pool->def->type == VIR_STORAGE_POOL_NETFS (pool->def->type == VIR_STORAGE_POOL_NETFS
? VIR_FILE_OP_AS_UID : 0))) < 0) { ? VIR_FILE_OP_AS_UID : 0))) < 0) {
virReportSystemError(createstat, virReportSystemError(-createstat,
_("cannot create path '%s'"), _("cannot create path '%s'"),
vol->target.path); vol->target.path);
goto cleanup; goto cleanup;
......
...@@ -1267,6 +1267,7 @@ int virFileExists(const char *path) ...@@ -1267,6 +1267,7 @@ int virFileExists(const char *path)
} }
# ifndef WIN32 # ifndef WIN32
/* return -errno on failure, or 0 on success */
static int virFileOperationNoFork(const char *path, int openflags, mode_t mode, static int virFileOperationNoFork(const char *path, int openflags, mode_t mode,
uid_t uid, gid_t gid, uid_t uid, gid_t gid,
virFileOperationHook hook, void *hookdata, virFileOperationHook hook, void *hookdata,
...@@ -1276,26 +1277,26 @@ static int virFileOperationNoFork(const char *path, int openflags, mode_t mode, ...@@ -1276,26 +1277,26 @@ static int virFileOperationNoFork(const char *path, int openflags, mode_t mode,
struct stat st; struct stat st;
if ((fd = open(path, openflags, mode)) < 0) { if ((fd = open(path, openflags, mode)) < 0) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("failed to create file '%s'"), virReportSystemError(errno, _("failed to create file '%s'"),
path); path);
goto error; goto error;
} }
if (fstat(fd, &st) == -1) { if (fstat(fd, &st) == -1) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("stat of '%s' failed"), path); virReportSystemError(errno, _("stat of '%s' failed"), path);
goto error; goto error;
} }
if (((st.st_uid != uid) || (st.st_gid != gid)) if (((st.st_uid != uid) || (st.st_gid != gid))
&& (fchown(fd, uid, gid) < 0)) { && (fchown(fd, uid, gid) < 0)) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"), virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
path, (unsigned int) uid, (unsigned int) gid); path, (unsigned int) uid, (unsigned int) gid);
goto error; goto error;
} }
if ((flags & VIR_FILE_OP_FORCE_PERMS) if ((flags & VIR_FILE_OP_FORCE_PERMS)
&& (fchmod(fd, mode) < 0)) { && (fchmod(fd, mode) < 0)) {
ret = errno; ret = -errno;
virReportSystemError(errno, virReportSystemError(errno,
_("cannot set mode of '%s' to %04o"), _("cannot set mode of '%s' to %04o"),
path, mode); path, mode);
...@@ -1305,7 +1306,7 @@ static int virFileOperationNoFork(const char *path, int openflags, mode_t mode, ...@@ -1305,7 +1306,7 @@ static int virFileOperationNoFork(const char *path, int openflags, mode_t mode,
goto error; goto error;
} }
if (close(fd) < 0) { if (close(fd) < 0) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("failed to close new file '%s'"), virReportSystemError(errno, _("failed to close new file '%s'"),
path); path);
fd = -1; fd = -1;
...@@ -1356,6 +1357,7 @@ error: ...@@ -1356,6 +1357,7 @@ error:
return ret; return ret;
} }
/* return -errno on failure, or 0 on success */
int virFileOperation(const char *path, int openflags, mode_t mode, int virFileOperation(const char *path, int openflags, mode_t mode,
uid_t uid, gid_t gid, uid_t uid, gid_t gid,
virFileOperationHook hook, void *hookdata, virFileOperationHook hook, void *hookdata,
...@@ -1380,7 +1382,7 @@ int virFileOperation(const char *path, int openflags, mode_t mode, ...@@ -1380,7 +1382,7 @@ int virFileOperation(const char *path, int openflags, mode_t mode,
int forkRet = virFork(&pid); int forkRet = virFork(&pid);
if (pid < 0) { if (pid < 0) {
ret = errno; ret = -errno;
return ret; return ret;
} }
...@@ -1389,14 +1391,14 @@ int virFileOperation(const char *path, int openflags, mode_t mode, ...@@ -1389,14 +1391,14 @@ int virFileOperation(const char *path, int openflags, mode_t mode,
while ((waitret = waitpid(pid, &status, 0) == -1) while ((waitret = waitpid(pid, &status, 0) == -1)
&& (errno == EINTR)); && (errno == EINTR));
if (waitret == -1) { if (waitret == -1) {
ret = errno; ret = -errno;
virReportSystemError(errno, virReportSystemError(errno,
_("failed to wait for child creating '%s'"), _("failed to wait for child creating '%s'"),
path); path);
goto parenterror; goto parenterror;
} }
ret = WEXITSTATUS(status); ret = -WEXITSTATUS(status);
if (!WIFEXITED(status) || (ret == EACCES)) { if (!WIFEXITED(status) || (ret == -EACCES)) {
/* fall back to the simpler method, which works better in /* fall back to the simpler method, which works better in
* some cases */ * some cases */
return virFileOperationNoFork(path, openflags, mode, uid, gid, return virFileOperationNoFork(path, openflags, mode, uid, gid,
...@@ -1417,22 +1419,22 @@ parenterror: ...@@ -1417,22 +1419,22 @@ parenterror:
/* set desired uid/gid, then attempt to create the file */ /* set desired uid/gid, then attempt to create the file */
if ((gid != 0) && (setgid(gid) != 0)) { if ((gid != 0) && (setgid(gid) != 0)) {
ret = errno; ret = -errno;
virReportSystemError(errno, virReportSystemError(errno,
_("cannot set gid %u creating '%s'"), _("cannot set gid %u creating '%s'"),
(unsigned int) gid, path); (unsigned int) gid, path);
goto childerror; goto childerror;
} }
if ((uid != 0) && (setuid(uid) != 0)) { if ((uid != 0) && (setuid(uid) != 0)) {
ret = errno; ret = -errno;
virReportSystemError(errno, virReportSystemError(errno,
_("cannot set uid %u creating '%s'"), _("cannot set uid %u creating '%s'"),
(unsigned int) uid, path); (unsigned int) uid, path);
goto childerror; goto childerror;
} }
if ((fd = open(path, openflags, mode)) < 0) { if ((fd = open(path, openflags, mode)) < 0) {
ret = errno; ret = -errno;
if (ret != EACCES) { if (ret != -EACCES) {
/* in case of EACCES, the parent will retry */ /* in case of EACCES, the parent will retry */
virReportSystemError(errno, virReportSystemError(errno,
_("child failed to create file '%s'"), _("child failed to create file '%s'"),
...@@ -1441,20 +1443,20 @@ parenterror: ...@@ -1441,20 +1443,20 @@ parenterror:
goto childerror; goto childerror;
} }
if (fstat(fd, &st) == -1) { if (fstat(fd, &st) == -1) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("stat of '%s' failed"), path); virReportSystemError(errno, _("stat of '%s' failed"), path);
goto childerror; goto childerror;
} }
if ((st.st_gid != gid) if ((st.st_gid != gid)
&& (fchown(fd, -1, gid) < 0)) { && (fchown(fd, -1, gid) < 0)) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"), virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
path, (unsigned int) uid, (unsigned int) gid); path, (unsigned int) uid, (unsigned int) gid);
goto childerror; goto childerror;
} }
if ((flags & VIR_FILE_OP_FORCE_PERMS) if ((flags & VIR_FILE_OP_FORCE_PERMS)
&& (fchmod(fd, mode) < 0)) { && (fchmod(fd, mode) < 0)) {
ret = errno; ret = -errno;
virReportSystemError(errno, virReportSystemError(errno,
_("cannot set mode of '%s' to %04o"), _("cannot set mode of '%s' to %04o"),
path, mode); path, mode);
...@@ -1464,7 +1466,7 @@ parenterror: ...@@ -1464,7 +1466,7 @@ parenterror:
goto childerror; goto childerror;
} }
if (close(fd) < 0) { if (close(fd) < 0) {
ret = errno; ret = -errno;
virReportSystemError(errno, _("child failed to close new file '%s'"), virReportSystemError(errno, _("child failed to close new file '%s'"),
path); path);
goto childerror; goto childerror;
...@@ -1576,6 +1578,7 @@ childerror: ...@@ -1576,6 +1578,7 @@ childerror:
# else /* WIN32 */ # else /* WIN32 */
/* return -errno on failure, or 0 on success */
int virFileOperation(const char *path ATTRIBUTE_UNUSED, int virFileOperation(const char *path ATTRIBUTE_UNUSED,
int openflags ATTRIBUTE_UNUSED, int openflags ATTRIBUTE_UNUSED,
mode_t mode ATTRIBUTE_UNUSED, mode_t mode ATTRIBUTE_UNUSED,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册