mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-07-11 12:25:52 +00:00
qemu_domain_namespace: Drop unused functions
After previous cleanup, creating /dev nodes from pre-exec hook is no longer needed and thus can be removed. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
40592f168f
commit
a83a2041eb
@ -185,254 +185,6 @@ qemuDomainGetPreservedMounts(virQEMUDriverConfigPtr cfg,
|
||||
}
|
||||
|
||||
|
||||
struct qemuDomainCreateDeviceData {
|
||||
const char *path; /* Path to temp new /dev location */
|
||||
char * const *devMountsPath;
|
||||
size_t ndevMountsPath;
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainCreateDeviceRecursive(const char *device,
|
||||
const struct qemuDomainCreateDeviceData *data,
|
||||
bool allow_noent,
|
||||
unsigned int ttl)
|
||||
{
|
||||
g_autofree char *devicePath = NULL;
|
||||
g_autofree char *target = NULL;
|
||||
GStatBuf sb;
|
||||
int ret = -1;
|
||||
bool isLink = false;
|
||||
bool isDev = false;
|
||||
bool isReg = false;
|
||||
bool isDir = false;
|
||||
bool create = false;
|
||||
#ifdef WITH_SELINUX
|
||||
char *tcon = NULL;
|
||||
#endif
|
||||
|
||||
if (!ttl) {
|
||||
virReportSystemError(ELOOP,
|
||||
_("Too many levels of symbolic links: %s"),
|
||||
device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (g_lstat(device, &sb) < 0) {
|
||||
if (errno == ENOENT && allow_noent) {
|
||||
/* Ignore non-existent device. */
|
||||
return 0;
|
||||
}
|
||||
virReportSystemError(errno, _("Unable to stat %s"), device);
|
||||
return ret;
|
||||
}
|
||||
|
||||
isLink = S_ISLNK(sb.st_mode);
|
||||
isDev = S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode);
|
||||
isReg = S_ISREG(sb.st_mode) || S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode);
|
||||
isDir = S_ISDIR(sb.st_mode);
|
||||
|
||||
/* Here, @device might be whatever path in the system. We
|
||||
* should create the path in the namespace iff it's "/dev"
|
||||
* prefixed. However, if it is a symlink, we need to traverse
|
||||
* it too (it might point to something in "/dev"). Just
|
||||
* consider:
|
||||
*
|
||||
* /var/sym1 -> /var/sym2 -> /dev/sda (because users can)
|
||||
*
|
||||
* This means, "/var/sym1" is not created (it's shared with
|
||||
* the parent namespace), nor "/var/sym2", but "/dev/sda".
|
||||
*
|
||||
* TODO Remove all `.' and `..' from the @device path.
|
||||
* Otherwise we might get fooled with `/dev/../var/my_image'.
|
||||
* For now, lets hope callers play nice.
|
||||
*/
|
||||
if (STRPREFIX(device, QEMU_DEVPREFIX)) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < data->ndevMountsPath; i++) {
|
||||
if (STREQ(data->devMountsPath[i], "/dev"))
|
||||
continue;
|
||||
if (STRPREFIX(device, data->devMountsPath[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == data->ndevMountsPath) {
|
||||
/* Okay, @device is in /dev but not in any mount point under /dev.
|
||||
* Create it. */
|
||||
devicePath = g_strdup_printf("%s/%s", data->path,
|
||||
device + strlen(QEMU_DEVPREFIX));
|
||||
|
||||
if (virFileMakeParentPath(devicePath) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Unable to create %s"),
|
||||
devicePath);
|
||||
goto cleanup;
|
||||
}
|
||||
VIR_DEBUG("Creating dev %s", device);
|
||||
create = true;
|
||||
} else {
|
||||
VIR_DEBUG("Skipping dev %s because of %s mount point",
|
||||
device, data->devMountsPath[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (isLink) {
|
||||
g_autoptr(GError) gerr = NULL;
|
||||
|
||||
/* We are dealing with a symlink. Create a dangling symlink and descend
|
||||
* down one level which hopefully creates the symlink's target. */
|
||||
if (!(target = g_file_read_link(device, &gerr))) {
|
||||
virReportError(VIR_ERR_SYSTEM_ERROR,
|
||||
_("failed to resolve symlink %s: %s"), device, gerr->message);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (create &&
|
||||
symlink(target, devicePath) < 0) {
|
||||
if (errno == EEXIST) {
|
||||
ret = 0;
|
||||
} else {
|
||||
virReportSystemError(errno,
|
||||
_("unable to create symlink %s"),
|
||||
devicePath);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Tricky part. If the target starts with a slash then we need to take
|
||||
* it as it is. Otherwise we need to replace the last component in the
|
||||
* original path with the link target:
|
||||
* /dev/rtc -> rtc0 (want /dev/rtc0)
|
||||
* /dev/disk/by-id/ata-SanDisk_SDSSDXPS480G_161101402485 -> ../../sda
|
||||
* (want /dev/disk/by-id/../../sda)
|
||||
* /dev/stdout -> /proc/self/fd/1 (no change needed)
|
||||
*/
|
||||
if (!g_path_is_absolute(target)) {
|
||||
g_autofree char *devTmp = g_strdup(device);
|
||||
char *c = NULL, *tmp = NULL;
|
||||
|
||||
if ((c = strrchr(devTmp, '/')))
|
||||
*(c + 1) = '\0';
|
||||
|
||||
tmp = g_strdup_printf("%s%s", devTmp, target);
|
||||
VIR_FREE(target);
|
||||
target = g_steal_pointer(&tmp);
|
||||
}
|
||||
|
||||
if (qemuDomainCreateDeviceRecursive(target, data,
|
||||
allow_noent, ttl - 1) < 0)
|
||||
goto cleanup;
|
||||
} else if (isDev) {
|
||||
if (create) {
|
||||
unlink(devicePath);
|
||||
if (mknod(devicePath, sb.st_mode, sb.st_rdev) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to make device %s"),
|
||||
devicePath);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
} else if (isReg) {
|
||||
if (create &&
|
||||
virFileTouch(devicePath, sb.st_mode) < 0)
|
||||
goto cleanup;
|
||||
/* Just create the file here so that code below sets
|
||||
* proper owner and mode. Bind mount only after that. */
|
||||
} else if (isDir) {
|
||||
if (create &&
|
||||
virFileMakePathWithMode(devicePath, sb.st_mode) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Unable to make dir %s"),
|
||||
devicePath);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
|
||||
_("unsupported device type %s 0%o"),
|
||||
device, sb.st_mode);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!create) {
|
||||
ret = 0;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (lchown(devicePath, sb.st_uid, sb.st_gid) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to chown device %s"),
|
||||
devicePath);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Symlinks don't have mode */
|
||||
if (!isLink &&
|
||||
chmod(devicePath, sb.st_mode) < 0) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to set permissions for device %s"),
|
||||
devicePath);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Symlinks don't have ACLs. */
|
||||
if (!isLink &&
|
||||
virFileCopyACLs(device, devicePath) < 0 &&
|
||||
errno != ENOTSUP) {
|
||||
virReportSystemError(errno,
|
||||
_("Failed to copy ACLs on device %s"),
|
||||
devicePath);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (lgetfilecon_raw(device, &tcon) < 0 &&
|
||||
(errno != ENOTSUP && errno != ENODATA)) {
|
||||
virReportSystemError(errno,
|
||||
_("Unable to get SELinux label from %s"),
|
||||
device);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (tcon &&
|
||||
lsetfilecon_raw(devicePath, (const char *)tcon) < 0) {
|
||||
VIR_WARNINGS_NO_WLOGICALOP_EQUAL_EXPR
|
||||
if (errno != EOPNOTSUPP && errno != ENOTSUP) {
|
||||
VIR_WARNINGS_RESET
|
||||
virReportSystemError(errno,
|
||||
_("Unable to set SELinux label on %s"),
|
||||
devicePath);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Finish mount process started earlier. */
|
||||
if ((isReg || isDir) &&
|
||||
virFileBindMountDevice(device, devicePath) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
#ifdef WITH_SELINUX
|
||||
freecon(tcon);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int G_GNUC_UNUSED
|
||||
qemuDomainCreateDevice(const char *device,
|
||||
const struct qemuDomainCreateDeviceData *data,
|
||||
bool allow_noent)
|
||||
{
|
||||
long symloop_max = sysconf(_SC_SYMLOOP_MAX);
|
||||
|
||||
return qemuDomainCreateDeviceRecursive(device, data,
|
||||
allow_noent, symloop_max);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainPopulateDevices(virQEMUDriverConfigPtr cfg,
|
||||
char ***paths)
|
||||
|
Loading…
Reference in New Issue
Block a user