提交 6ef20bb7 编写于 作者: L Laine Stump 提交者: Daniel Veillard

Use virFileOperation hook function in virStorageBackendFileSystemVolBuild

There were a few operations on the storage volume file that were still
being done as root, which will fail if the file is on a root-squashed
NFS share. The result was that attempts to create a storage volume of
type "raw" on a root-squashed NFS share would fail.

This patch uses the newly introduced "hook" function in
virFileOperation to execute all those file operations in the child
process that's run under the uid that owns the file (and, presumably,
has permission to write to the NFS share)

* src/storage/storage_backend.c: use virFileOperation() in
  virStorageBackendCreateRaw, turning virStorageBackendCreateRaw()
  into a new createRawFileOpHook() hook
上级 fbadc2b6
...@@ -270,61 +270,33 @@ cleanup: ...@@ -270,61 +270,33 @@ cleanup:
return ret; return ret;
} }
int struct createRawFileOpHookData {
virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, virStorageVolDefPtr vol;
virStoragePoolObjPtr pool, virStorageVolDefPtr inputvol;
virStorageVolDefPtr vol, };
virStorageVolDefPtr inputvol,
unsigned int flags ATTRIBUTE_UNUSED)
{
int fd = -1;
int ret = -1;
int createstat;
unsigned long long remain;
char *buf = NULL;
if (vol->target.encryption != NULL) {
virStorageReportError(VIR_ERR_NO_SUPPORT,
"%s", _("storage pool does not support encrypted "
"volumes"));
return -1;
}
if ((createstat = virFileOperation(vol->target.path, O_RDWR | O_CREAT | O_EXCL,
vol->target.perms.mode,
vol->target.perms.uid, vol->target.perms.gid,
NULL, NULL,
VIR_FILE_OP_FORCE_PERMS |
(pool->def->type == VIR_STORAGE_POOL_NETFS
? VIR_FILE_OP_AS_UID : 0))) < 0) {
virReportSystemError(createstat,
_("cannot create path '%s'"),
vol->target.path);
goto cleanup;
}
if ((fd = open(vol->target.path, O_RDWR | O_EXCL | O_DSYNC)) < 0) { static int createRawFileOpHook(int fd, void *data) {
virReportSystemError(errno, struct createRawFileOpHookData *hdata = data;
_("cannot open new path '%s'"), int ret = 0;
vol->target.path); unsigned long long remain;
goto cleanup;
}
/* 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, vol->capacity) < 0) { if (ftruncate(fd, hdata->vol->capacity) < 0) {
ret = errno;
virReportSystemError(errno, virReportSystemError(errno,
_("cannot extend file '%s'"), _("cannot extend file '%s'"),
vol->target.path); hdata->vol->target.path);
goto cleanup; goto cleanup;
} }
remain = vol->allocation; remain = hdata->vol->allocation;
if (inputvol) { if (hdata->inputvol) {
int res = virStorageBackendCopyToFD(vol, inputvol, int res = virStorageBackendCopyToFD(hdata->vol, hdata->inputvol,
fd, &remain, 1); fd, &remain, 1);
if (res < 0) if (res < 0)
ret = -res;
goto cleanup; goto cleanup;
} }
...@@ -341,11 +313,11 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -341,11 +313,11 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
if (bytes > remain) if (bytes > remain)
bytes = remain; bytes = remain;
if ((r = safezero(fd, 0, vol->allocation - remain, if ((r = safezero(fd, 0, hdata->vol->allocation - remain,
bytes)) != 0) { bytes)) != 0) {
virReportSystemError(r, ret = errno;
_("cannot fill file '%s'"), virReportSystemError(r, _("cannot fill file '%s'"),
vol->target.path); hdata->vol->target.path);
goto cleanup; goto cleanup;
} }
remain -= bytes; remain -= bytes;
...@@ -354,28 +326,51 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED, ...@@ -354,28 +326,51 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
int r; int r;
if ((r = safezero(fd, 0, 0, remain)) != 0) { if ((r = safezero(fd, 0, 0, remain)) != 0) {
virReportSystemError(r, ret = errno;
_("cannot fill file '%s'"), virReportSystemError(r, _("cannot fill file '%s'"),
vol->target.path); hdata->vol->target.path);
goto cleanup; goto cleanup;
} }
} }
} }
if (close(fd) < 0) { cleanup:
virReportSystemError(errno, return ret;
_("cannot close file '%s'"), }
vol->target.path);
int
virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
virStoragePoolObjPtr pool,
virStorageVolDefPtr vol,
virStorageVolDefPtr inputvol,
unsigned int flags ATTRIBUTE_UNUSED)
{
int ret = -1;
int createstat;
struct createRawFileOpHookData hdata = { vol, inputvol };
if (vol->target.encryption != NULL) {
virStorageReportError(VIR_ERR_NO_SUPPORT,
"%s", _("storage pool does not support encrypted "
"volumes"));
goto cleanup; goto cleanup;
} }
fd = -1;
if ((createstat = virFileOperation(vol->target.path, O_RDWR | O_CREAT | O_EXCL,
vol->target.perms.mode,
vol->target.perms.uid, vol->target.perms.gid,
createRawFileOpHook, &hdata,
VIR_FILE_OP_FORCE_PERMS |
(pool->def->type == VIR_STORAGE_POOL_NETFS
? VIR_FILE_OP_AS_UID : 0))) < 0) {
virReportSystemError(createstat,
_("cannot create path '%s'"),
vol->target.path);
goto cleanup;
}
ret = 0; ret = 0;
cleanup: cleanup:
if (fd != -1)
close(fd);
VIR_FREE(buf);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册