/*---------------------------------------------------------------------------*/
-/* Copyright (C) 2006-2012 Red Hat, Inc.
+/* Copyright (C) 2006-2013 Red Hat, Inc.
* Copyright (C) 2011-2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
* Copyright (C) 2011 Univention GmbH.
*
char *xml = NULL;
if ((fd = virFileOpenAs(from, O_RDONLY, 0, -1, -1, 0)) < 0) {
- virReportError(VIR_ERR_OPERATION_FAILED,
- "%s", _("cannot read domain image"));
+ virReportSystemError(-fd,
+ _("Failed to open domain image file '%s'"), from);
goto error;
}
/* First try creating the file as root */
if (!is_reg) {
- fd = open(path, oflags & ~O_CREAT);
- if (fd < 0) {
- virReportSystemError(errno, _("unable to open %s"), path);
- goto cleanup;
+ if ((fd = open(path, oflags & ~O_CREAT)) < 0) {
+ fd = -errno;
+ goto error;
}
} else {
if ((fd = virFileOpenAs(path, oflags, S_IRUSR | S_IWUSR, uid, gid,
qemu user (cfg->user) is non-root, just set a flag to
bypass security driver shenanigans, and retry the operation
after doing setuid to qemu user */
- if ((fd != -EACCES && fd != -EPERM) ||
- cfg->user == getuid()) {
- virReportSystemError(-fd,
- _("Failed to create file '%s'"),
- path);
- goto cleanup;
- }
+ if ((fd != -EACCES && fd != -EPERM) || cfg->user == getuid())
+ goto error;
/* On Linux we can also verify the FS-type of the directory. */
switch (path_shared) {
case 1:
- /* it was on a network share, so we'll continue
- * as outlined above
- */
- break;
+ /* it was on a network share, so we'll continue
+ * as outlined above
+ */
+ break;
case -1:
- virReportSystemError(errno,
- _("Failed to create file "
- "'%s': couldn't determine fs type"),
- path);
- goto cleanup;
+ virReportSystemError(-fd, oflags & O_CREAT
+ ? _("Failed to create file "
+ "'%s': couldn't determine fs type")
+ : _("Failed to open file "
+ "'%s': couldn't determine fs type"),
+ path);
+ goto cleanup;
case 0:
default:
- /* local file - log the error returned by virFileOpenAs */
- virReportSystemError(-fd,
- _("Failed to create file '%s'"),
- path);
- goto cleanup;
+ /* local file - log the error returned by virFileOpenAs */
+ goto error;
}
/* Retry creating the file as cfg->user */
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP,
cfg->user, cfg->group,
vfoflags | VIR_FILE_OPEN_FORK)) < 0) {
- virReportSystemError(-fd,
- _("Error from child process creating '%s'"),
+ virReportSystemError(-fd, oflags & O_CREAT
+ ? _("Error from child process creating '%s'")
+ : _("Error from child process opening '%s'"),
path);
goto cleanup;
}
*bypassSecurityDriver = bypass_security;
virObjectUnref(cfg);
return fd;
+
+error:
+ virReportSystemError(-fd, oflags & O_CREAT
+ ? _("Failed to create file '%s'")
+ : _("Failed to open file '%s'"),
+ path);
+ goto cleanup;
}
/* Helper function to execute a migration to file with a correct save header
vol->target.perms.gid,
operation_flags)) < 0) {
virReportSystemError(-fd,
- _("cannot create path '%s'"),
+ _("Failed to create file '%s'"),
vol->target.path);
goto cleanup;
}
int fd, ret;
if ((fd = virFileOpenAs(path, O_RDONLY, 0, uid, gid, 0)) < 0) {
- virReportSystemError(errno, _("cannot open file '%s'"), path);
+ virReportSystemError(-fd, _("Failed to open file '%s'"), path);
return -1;
}
return NULL;
if ((fd = virFileOpenAs(path, O_RDONLY, 0, uid, gid, 0)) < 0) {
- virReportSystemError(-fd, _("cannot open file '%s'"), path);
+ virReportSystemError(-fd, _("Failed to open file '%s'"), path);
return NULL;
}
* uid:gid before returning (even if it already existed with a
* different owner). If @flags includes VIR_FILE_OPEN_FORCE_MODE,
* ensure it has those permissions before returning (again, even if
- * the file already existed with different permissions). The return
- * value (if non-negative) is the file descriptor, left open. Returns
- * -errno on failure. */
+ * the file already existed with different permissions).
+ *
+ * The return value (if non-negative) is the file descriptor, left
+ * open. Returns -errno on failure.
+ */
int
virFileOpenAs(const char *path, int openflags, mode_t mode,
uid_t uid, gid_t gid, unsigned int flags)
if ((fd = open(path, openflags, mode)) < 0) {
ret = -errno;
+ if (!(flags & VIR_FILE_OPEN_FORK))
+ goto error;
} else {
ret = virFileOpenForceOwnerMode(path, fd, mode, uid, gid, flags);
if (ret < 0)
/* On Linux we can also verify the FS-type of the
* directory. (this is a NOP on other platforms). */
- switch (virStorageFileIsSharedFS(path)) {
- case 1:
- /* it was on a network share, so we'll re-try */
- break;
- case -1:
- /* failure detecting fstype */
- virReportSystemError(errno, _("couldn't determine fs type "
- "of mount containing '%s'"), path);
- goto error;
- case 0:
- default:
- /* file isn't on a recognized network FS */
+ if (virStorageFileIsSharedFS(path) <= 0)
goto error;
- }
}
/* passed all prerequisites - retry the open w/fork+setuid */
if ((fd = virFileOpenForked(path, openflags, mode, uid, gid, flags)) < 0) {
ret = fd;
- fd = -1;
goto error;
}
}
/* File is successfully opened */
-
return fd;
error:
- if (fd < 0) {
- /* whoever failed the open last has already set ret = -errno */
- virReportSystemError(-ret, openflags & O_CREAT
- ? _("failed to create file '%s'")
- : _("failed to open file '%s'"),
- path);
- } else {
+ if (fd >= 0) {
/* some other failure after the open succeeded */
VIR_FORCE_CLOSE(fd);
}
+ /* whoever failed the open last has already set ret = -errno */
return ret;
}