storage: fs: Fill in permissions on pool refresh

This means pool XML actually reports accurate user/group/mode/label.

This uses UpdateVolTargetInfoFD in a bit of a hackish way, but it works
This commit is contained in:
Cole Robinson 2015-04-27 16:48:05 -04:00
parent 27a4c492f5
commit d6f8b35db5

View File

@ -811,12 +811,6 @@ virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED,
goto error; goto error;
} }
/* Reflect the actual uid and gid to the config. */
if (pool->def->target.perms.uid == (uid_t) -1)
pool->def->target.perms.uid = geteuid();
if (pool->def->target.perms.gid == (gid_t) -1)
pool->def->target.perms.gid = getegid();
if (flags != 0) { if (flags != 0) {
ret = virStorageBackendMakeFileSystem(pool, flags); ret = virStorageBackendMakeFileSystem(pool, flags);
} else { } else {
@ -840,18 +834,21 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
DIR *dir; DIR *dir;
struct dirent *ent; struct dirent *ent;
struct statvfs sb; struct statvfs sb;
struct stat statbuf;
virStorageVolDefPtr vol = NULL; virStorageVolDefPtr vol = NULL;
virStorageSourcePtr target = NULL;
int direrr; int direrr;
int fd = -1, ret = -1;
if (!(dir = opendir(pool->def->target.path))) { if (!(dir = opendir(pool->def->target.path))) {
virReportSystemError(errno, virReportSystemError(errno,
_("cannot open path '%s'"), _("cannot open path '%s'"),
pool->def->target.path); pool->def->target.path);
goto error; goto cleanup;
} }
while ((direrr = virDirRead(dir, &ent, pool->def->target.path)) > 0) { while ((direrr = virDirRead(dir, &ent, pool->def->target.path)) > 0) {
int ret; int err;
if (virStringHasControlChars(ent->d_name)) { if (virStringHasControlChars(ent->d_name)) {
VIR_WARN("Ignoring file with control characters under '%s'", VIR_WARN("Ignoring file with control characters under '%s'",
@ -860,37 +857,37 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
} }
if (VIR_ALLOC(vol) < 0) if (VIR_ALLOC(vol) < 0)
goto error; goto cleanup;
if (VIR_STRDUP(vol->name, ent->d_name) < 0) if (VIR_STRDUP(vol->name, ent->d_name) < 0)
goto error; goto cleanup;
vol->type = VIR_STORAGE_VOL_FILE; vol->type = VIR_STORAGE_VOL_FILE;
vol->target.format = VIR_STORAGE_FILE_RAW; /* Real value is filled in during probe */ vol->target.format = VIR_STORAGE_FILE_RAW; /* Real value is filled in during probe */
if (virAsprintf(&vol->target.path, "%s/%s", if (virAsprintf(&vol->target.path, "%s/%s",
pool->def->target.path, pool->def->target.path,
vol->name) == -1) vol->name) == -1)
goto error; goto cleanup;
if (VIR_STRDUP(vol->key, vol->target.path) < 0) if (VIR_STRDUP(vol->key, vol->target.path) < 0)
goto error; goto cleanup;
if ((ret = virStorageBackendProbeTarget(&vol->target, if ((err = virStorageBackendProbeTarget(&vol->target,
&vol->target.encryption)) < 0) { &vol->target.encryption)) < 0) {
if (ret == -2) { if (err == -2) {
/* Silently ignore non-regular files, /* Silently ignore non-regular files,
* eg '.' '..', 'lost+found', dangling symbolic link */ * eg '.' '..', 'lost+found', dangling symbolic link */
virStorageVolDefFree(vol); virStorageVolDefFree(vol);
vol = NULL; vol = NULL;
continue; continue;
} else if (ret == -3) { } else if (err == -3) {
/* The backing file is currently unavailable, its format is not /* The backing file is currently unavailable, its format is not
* explicitly specified, the probe to auto detect the format * explicitly specified, the probe to auto detect the format
* failed: continue with faked RAW format, since AUTO will * failed: continue with faked RAW format, since AUTO will
* break virStorageVolTargetDefFormat() generating the line * break virStorageVolTargetDefFormat() generating the line
* <format type='...'/>. */ * <format type='...'/>. */
} else { } else {
goto error; goto cleanup;
} }
} }
@ -908,32 +905,65 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
} }
if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0) if (VIR_APPEND_ELEMENT(pool->volumes.objs, pool->volumes.count, vol) < 0)
goto error; goto cleanup;
} }
if (direrr < 0) if (direrr < 0)
goto error; goto cleanup;
closedir(dir); closedir(dir);
dir = NULL;
vol = NULL;
if (VIR_ALLOC(target))
goto cleanup;
if ((fd = open(pool->def->target.path, O_RDONLY)) < 0) {
virReportSystemError(errno,
_("cannot open path '%s'"),
pool->def->target.path);
goto cleanup;
}
if (fstat(fd, &statbuf) < 0) {
virReportSystemError(errno,
_("cannot stat path '%s'"),
pool->def->target.path);
goto cleanup;
}
if (virStorageBackendUpdateVolTargetInfoFD(target, fd, &statbuf) < 0)
goto cleanup;
/* VolTargetInfoFD doesn't update capacity correctly for the pool case */
if (statvfs(pool->def->target.path, &sb) < 0) { if (statvfs(pool->def->target.path, &sb) < 0) {
virReportSystemError(errno, virReportSystemError(errno,
_("cannot statvfs path '%s'"), _("cannot statvfs path '%s'"),
pool->def->target.path); pool->def->target.path);
return -1; goto cleanup;
} }
pool->def->capacity = ((unsigned long long)sb.f_frsize * pool->def->capacity = ((unsigned long long)sb.f_frsize *
(unsigned long long)sb.f_blocks); (unsigned long long)sb.f_blocks);
pool->def->available = ((unsigned long long)sb.f_bfree * pool->def->available = ((unsigned long long)sb.f_bfree *
(unsigned long long)sb.f_frsize); (unsigned long long)sb.f_frsize);
pool->def->allocation = pool->def->capacity - pool->def->available; pool->def->allocation = pool->def->capacity - pool->def->available;
return 0; pool->def->target.perms.mode = target->perms->mode;
pool->def->target.perms.uid = target->perms->uid;
pool->def->target.perms.gid = target->perms->gid;
VIR_FREE(pool->def->target.perms.label);
if (VIR_STRDUP(pool->def->target.perms.label, target->perms->label) < 0)
goto cleanup;
error: ret = 0;
cleanup:
if (dir) if (dir)
closedir(dir); closedir(dir);
VIR_FORCE_CLOSE(fd);
virStorageVolDefFree(vol); virStorageVolDefFree(vol);
virStorageSourceFree(target);
if (ret < 0)
virStoragePoolObjClearVols(pool); virStoragePoolObjClearVols(pool);
return -1; return ret;
} }