bool delDevice = false;
bool isLink = S_ISLNK(data->sb.st_mode);
bool isDev = S_ISCHR(data->sb.st_mode) || S_ISBLK(data->sb.st_mode);
+ bool isReg = S_ISREG(data->sb.st_mode);
qemuSecurityPostFork(data->driver->securityManager);
} else {
delDevice = true;
}
+ } else if (isReg) {
+ /* We are not cleaning up disks on virDomainDetachDevice
+ * because disk might be still in use by different disk
+ * as its backing chain. This might however clash here.
+ * Therefore do the cleanup here. */
+ if (umount(data->file) < 0 &&
+ errno != ENOENT) {
+ virReportSystemError(errno,
+ _("Unable to umount %s"),
+ data->file);
+ goto cleanup;
+ }
+ if (virFileTouch(data->file, data->sb.st_mode) < 0)
+ goto cleanup;
+ delDevice = true;
+ /* Just create the file here so that code below sets
+ * proper owner and mode. Move the mount only after that. */
} else {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("unsupported device type %s 0%o"),
goto cleanup;
}
+ /* Symlinks don't have mode */
+ if (!isLink &&
+ chmod(data->file, data->sb.st_mode) < 0) {
+ virReportSystemError(errno,
+ _("Failed to set permissions for device %s"),
+ data->file);
+ goto cleanup;
+ }
+
/* Symlinks don't have ACLs. */
if (!isLink &&
virFileSetACLs(data->file, data->acl) < 0 &&
}
#endif
+ /* Finish mount process started earlier. */
+ if (isReg &&
+ virFileMoveMount(data->target, data->file) < 0)
+ goto cleanup;
+
ret = 0;
cleanup:
if (ret < 0 && delDevice)
size_t ndevMountsPath,
unsigned int ttl)
{
+ virQEMUDriverConfigPtr cfg = NULL;
struct qemuDomainAttachDeviceMknodData data;
int ret = -1;
char *target = NULL;
bool isLink;
+ bool isReg;
if (!ttl) {
virReportSystemError(ELOOP,
}
isLink = S_ISLNK(data.sb.st_mode);
+ isReg = S_ISREG(data.sb.st_mode);
- if (isLink) {
+ if (isReg && STRPREFIX(file, DEVPREFIX)) {
+ cfg = virQEMUDriverGetConfig(driver);
+ if (!(target = qemuDomainGetPreservedMountPath(cfg, vm, file)))
+ goto cleanup;
+
+ if (virFileBindMountDevice(file, target) < 0)
+ goto cleanup;
+
+ data.target = target;
+ } else if (isLink) {
if (virFileReadLink(file, &target) < 0) {
virReportSystemError(errno,
_("unable to resolve symlink %s"),
freecon(data.tcon);
#endif
virFileFreeACLs(&data.acl);
+ if (isReg && target)
+ umount(target);
VIR_FREE(target);
+ virObjectUnref(cfg);
return ret;
}
char **devMountsPath = NULL;
size_t ndevMountsPath = 0;
virStorageSourcePtr next;
- struct stat sb;
int ret = -1;
if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
continue;
}
- if (stat(next->path, &sb) < 0) {
- virReportSystemError(errno,
- _("Unable to access %s"), next->path);
- goto cleanup;
- }
-
- if (!S_ISBLK(sb.st_mode))
- continue;
-
if (qemuDomainAttachDeviceMknod(driver,
vm,
next->path,