struct qemud_save_header *header;
};
+/* return -errno on failure, or 0 on success */
static int qemudDomainSaveFileOpHook(int fd, void *data) {
struct fileOpHookData *hdata = data;
int ret = 0;
if (safewrite(fd, hdata->header, sizeof(*hdata->header)) != sizeof(*hdata->header)) {
- ret = errno;
+ ret = -errno;
qemuReportError(VIR_ERR_OPERATION_FAILED,
_("failed to write header to domain save file '%s'"),
hdata->path);
}
if (safewrite(fd, hdata->xml, hdata->header->xml_len) != hdata->header->xml_len) {
- ret = errno;
+ ret = -errno;
qemuReportError(VIR_ERR_OPERATION_FAILED,
_("failed to write xml to '%s'"), hdata->path);
goto endjob;
virReportSystemError(errno, _("unable to open %s"), path);
goto endjob;
}
- if (qemudDomainSaveFileOpHook(fd, &hdata) != 0) {
+ if (qemudDomainSaveFileOpHook(fd, &hdata) < 0) {
close(fd);
goto endjob;
}
S_IRUSR|S_IWUSR,
getuid(), getgid(),
qemudDomainSaveFileOpHook, &hdata,
- 0)) != 0) {
+ 0)) < 0) {
/* If we failed as root, and the error was permission-denied
(EACCES), assume it's on a network-connected share where
root access is restricted (eg, root-squashed NFS). If the
bypass security driver shenanigans, and retry the operation
after doing setuid to qemu user */
- if ((rc != EACCES) ||
+ if ((rc != -EACCES) ||
driver->user == getuid()) {
- virReportSystemError(rc, _("Failed to create domain save file '%s'"),
+ virReportSystemError(-rc, _("Failed to create domain save file '%s'"),
path);
goto endjob;
}
case 0:
default:
/* local file - log the error returned by virFileOperation */
- virReportSystemError(rc,
+ virReportSystemError(-rc,
_("Failed to create domain save file '%s'"),
path);
goto endjob;
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,
driver->user, driver->group,
qemudDomainSaveFileOpHook, &hdata,
- VIR_FILE_OP_AS_UID)) != 0) {
- virReportSystemError(rc, _("Error from child process creating '%s'"),
+ VIR_FILE_OP_AS_UID)) < 0) {
+ virReportSystemError(-rc, _("Error from child process creating '%s'"),
path);
goto endjob;
}
/* Seek to the final size, so the capacity is available upfront
* for progress reporting */
if (ftruncate(fd, hdata->vol->capacity) < 0) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno,
_("cannot extend file '%s'"),
hdata->vol->target.path);
remain = hdata->vol->allocation;
if (hdata->inputvol) {
- int res = virStorageBackendCopyToFD(hdata->vol, hdata->inputvol,
- fd, &remain, 1);
- if (res < 0) {
- ret = -res;
+ ret = virStorageBackendCopyToFD(hdata->vol, hdata->inputvol,
+ fd, &remain, 1);
+ if (ret < 0) {
goto cleanup;
}
}
bytes = remain;
if (safezero(fd, 0, hdata->vol->allocation - remain,
bytes) != 0) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("cannot fill file '%s'"),
hdata->vol->target.path);
goto cleanup;
}
} else { /* No progress bars to be shown */
if (safezero(fd, 0, 0, remain) != 0) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("cannot fill file '%s'"),
hdata->vol->target.path);
goto cleanup;
}
if (fsync(fd) < 0) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("cannot sync data to file '%s'"),
hdata->vol->target.path);
goto cleanup;
VIR_FILE_OP_FORCE_PERMS |
(pool->def->type == VIR_STORAGE_POOL_NETFS
? VIR_FILE_OP_AS_UID : 0))) < 0) {
- virReportSystemError(createstat,
+ virReportSystemError(-createstat,
_("cannot create path '%s'"),
vol->target.path);
goto cleanup;
}
# ifndef WIN32
+/* return -errno on failure, or 0 on success */
static int virFileOperationNoFork(const char *path, int openflags, mode_t mode,
uid_t uid, gid_t gid,
virFileOperationHook hook, void *hookdata,
struct stat st;
if ((fd = open(path, openflags, mode)) < 0) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("failed to create file '%s'"),
path);
goto error;
}
if (fstat(fd, &st) == -1) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("stat of '%s' failed"), path);
goto error;
}
if (((st.st_uid != uid) || (st.st_gid != gid))
&& (fchown(fd, uid, gid) < 0)) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
path, (unsigned int) uid, (unsigned int) gid);
goto error;
}
if ((flags & VIR_FILE_OP_FORCE_PERMS)
&& (fchmod(fd, mode) < 0)) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno,
_("cannot set mode of '%s' to %04o"),
path, mode);
goto error;
}
if (close(fd) < 0) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("failed to close new file '%s'"),
path);
fd = -1;
return ret;
}
+/* return -errno on failure, or 0 on success */
int virFileOperation(const char *path, int openflags, mode_t mode,
uid_t uid, gid_t gid,
virFileOperationHook hook, void *hookdata,
int forkRet = virFork(&pid);
if (pid < 0) {
- ret = errno;
+ ret = -errno;
return ret;
}
while ((waitret = waitpid(pid, &status, 0) == -1)
&& (errno == EINTR));
if (waitret == -1) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno,
_("failed to wait for child creating '%s'"),
path);
goto parenterror;
}
- ret = WEXITSTATUS(status);
- if (!WIFEXITED(status) || (ret == EACCES)) {
+ ret = -WEXITSTATUS(status);
+ if (!WIFEXITED(status) || (ret == -EACCES)) {
/* fall back to the simpler method, which works better in
* some cases */
return virFileOperationNoFork(path, openflags, mode, uid, gid,
/* set desired uid/gid, then attempt to create the file */
if ((gid != 0) && (setgid(gid) != 0)) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno,
_("cannot set gid %u creating '%s'"),
(unsigned int) gid, path);
goto childerror;
}
if ((uid != 0) && (setuid(uid) != 0)) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno,
_("cannot set uid %u creating '%s'"),
(unsigned int) uid, path);
goto childerror;
}
if ((fd = open(path, openflags, mode)) < 0) {
- ret = errno;
- if (ret != EACCES) {
+ ret = -errno;
+ if (ret != -EACCES) {
/* in case of EACCES, the parent will retry */
virReportSystemError(errno,
_("child failed to create file '%s'"),
goto childerror;
}
if (fstat(fd, &st) == -1) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("stat of '%s' failed"), path);
goto childerror;
}
if ((st.st_gid != gid)
&& (fchown(fd, -1, gid) < 0)) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("cannot chown '%s' to (%u, %u)"),
path, (unsigned int) uid, (unsigned int) gid);
goto childerror;
}
if ((flags & VIR_FILE_OP_FORCE_PERMS)
&& (fchmod(fd, mode) < 0)) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno,
_("cannot set mode of '%s' to %04o"),
path, mode);
goto childerror;
}
if (close(fd) < 0) {
- ret = errno;
+ ret = -errno;
virReportSystemError(errno, _("child failed to close new file '%s'"),
path);
goto childerror;
# else /* WIN32 */
+/* return -errno on failure, or 0 on success */
int virFileOperation(const char *path ATTRIBUTE_UNUSED,
int openflags ATTRIBUTE_UNUSED,
mode_t mode ATTRIBUTE_UNUSED,