static int createFileDir(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, unsigned int flags ATTRIBUTE_UNUSED) { int err; if (inputvol) { virStorageReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot copy from volume to a directory volume")); return -1; } uid_t uid = (vol->target.perms.uid == -1) ? getuid() : vol->target.perms.uid; gid_t gid = (vol->target.perms.gid == -1) ? getgid() : vol->target.perms.gid; if ((err = virDirCreate(vol->target.path, vol->target.perms.mode, uid, gid, VIR_DIR_CREATE_FORCE_PERMS | (pool->def->type == VIR_STORAGE_POOL_NETFS ? VIR_DIR_CREATE_AS_UID : 0))) != 0) { virReportSystemError(err, _("cannot create path '%s'"), vol->target.path); return -1; } return 0; }
/* * qemuTPMCreateEmulatorStorage * * @storagepath: directory for swtpm's persistent state * @created: a pointer to a bool that will be set to true if the * storage was created because it did not exist yet * @swtpm_user: The uid that needs to be able to access the directory * @swtpm_group: The gid that needs to be able to access the directory * * Unless the storage path for the swtpm for the given VM * already exists, create it and make it accessible for the given userid. * Adapt ownership of the directory and all swtpm's state files there. */ static int qemuTPMCreateEmulatorStorage(const char *storagepath, bool *created, uid_t swtpm_user, gid_t swtpm_group) { int ret = -1; char *swtpmStorageDir = qemuTPMGetTPMStorageDir(storagepath); if (!swtpmStorageDir) return -1; if (qemuTPMEmulatorInitStorage(swtpmStorageDir) < 0) goto cleanup; *created = false; if (!virFileExists(storagepath)) *created = true; if (virDirCreate(storagepath, 0700, swtpm_user, swtpm_group, VIR_DIR_CREATE_ALLOW_EXIST) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not create directory %s as %u:%d"), storagepath, swtpm_user, swtpm_group); goto cleanup; } if (virFileChownFiles(storagepath, swtpm_user, swtpm_group) < 0) goto cleanup; ret = 0; cleanup: VIR_FREE(swtpmStorageDir); return ret; }
/* * qemuTPMEmulatorPrepareHost: * * @tpm: tpm definition * @logDir: directory where swtpm writes its logs into * @vmname: name of the VM * @swtpm_user: uid to run the swtpm with * @swtpm_group: gid to run the swtpm with * @swtpmStateDir: directory for swtpm's persistent state * @qemu_user: uid that qemu will run with; we share the socket file with it * @shortName: short and unique name of the domain * * Prepare the log directory for the swtpm and adjust ownership of it and the * log file we will be using. Prepare the state directory where we will share * the socket between tss and qemu users. */ static int qemuTPMEmulatorPrepareHost(virDomainTPMDefPtr tpm, const char *logDir, const char *vmname, uid_t swtpm_user, gid_t swtpm_group, const char *swtpmStateDir, uid_t qemu_user, const char *shortName) { int ret = -1; if (qemuTPMEmulatorInit() < 0) return -1; /* create log dir ... allow 'tss' user to cd into it */ if (virFileMakePathWithMode(logDir, 0711) < 0) return -1; /* ... and adjust ownership */ if (virDirCreate(logDir, 0730, swtpm_user, swtpm_group, VIR_DIR_CREATE_ALLOW_EXIST) < 0) goto cleanup; /* create logfile name ... */ if (!tpm->data.emulator.logfile && virAsprintf(&tpm->data.emulator.logfile, "%s/%s-swtpm.log", logDir, vmname) < 0) goto cleanup; /* ... and make sure it can be accessed by swtpm_user */ if (virFileExists(tpm->data.emulator.logfile) && chown(tpm->data.emulator.logfile, swtpm_user, swtpm_group) < 0) { virReportSystemError(errno, _("Could not chown on swtpm logfile %s"), tpm->data.emulator.logfile); goto cleanup; } /* create our swtpm state dir ... - QEMU user needs to be able to access the socket there - swtpm group needs to be able to create files there - in privileged mode 0570 would be enough, for non-privileged mode we need 0770 */ if (virDirCreate(swtpmStateDir, 0770, qemu_user, swtpm_group, VIR_DIR_CREATE_ALLOW_EXIST) < 0) goto cleanup; /* create the socket filename */ if (!tpm->data.emulator.source.data.nix.path && !(tpm->data.emulator.source.data.nix.path = qemuTPMCreateEmulatorSocket(swtpmStateDir, shortName))) goto cleanup; tpm->data.emulator.source.type = VIR_DOMAIN_CHR_TYPE_UNIX; ret = 0; cleanup: return ret; }
/** * @conn connection to report errors against * @pool storage pool to build * * Build a directory or FS based storage pool. * * - If it is a FS based pool, mounts the unlying source device on the pool * * Returns 0 on success, -1 on error */ static int virStorageBackendFileSystemBuild(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, unsigned int flags ATTRIBUTE_UNUSED) { int err, ret = -1; char *parent; char *p; if ((parent = strdup(pool->def->target.path)) == NULL) { virReportOOMError(); goto error; } if (!(p = strrchr(parent, '/'))) { virStorageReportError(VIR_ERR_INVALID_ARG, _("path '%s' is not absolute"), pool->def->target.path); goto error; } if (p != parent) { /* assure all directories in the path prior to the final dir * exist, with default uid/gid/mode. */ *p = '\0'; if ((err = virFileMakePath(parent)) != 0) { virReportSystemError(err, _("cannot create path '%s'"), parent); goto error; } } /* Now create the final dir in the path with the uid/gid/mode * requested in the config. If the dir already exists, just set * the perms. */ struct stat st; if ((stat(pool->def->target.path, &st) < 0) || (pool->def->target.perms.uid != -1)) { uid_t uid = (pool->def->target.perms.uid == -1) ? getuid() : pool->def->target.perms.uid; gid_t gid = (pool->def->target.perms.gid == -1) ? getgid() : pool->def->target.perms.gid; if ((err = virDirCreate(pool->def->target.path, pool->def->target.perms.mode, uid, gid, VIR_DIR_CREATE_FORCE_PERMS | VIR_DIR_CREATE_ALLOW_EXIST | (pool->def->type == VIR_STORAGE_POOL_NETFS ? VIR_DIR_CREATE_AS_UID : 0)) != 0)) { virReportSystemError(err, _("cannot create path '%s'"), pool->def->target.path); goto error; } } ret = 0; error: VIR_FREE(parent); return ret; }