mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 14:57:42 +00:00
lxc: Add Real Time Clock device into allowed devices
This commit share host Real Time Clock device (rtc) into LXC containers to support hardware clock. This should be available setting up a `rtc` timer under clock section. Since this option is not emulated, it should be available only for `localtime` clock. This option should be readonly due to security reasons. Before: root# hwclock --verbose hwclock from util-linux 2.32.1 System Time: 1581877557.598365 Trying to open: /dev/rtc0 Trying to open: /dev/rtc Trying to open: /dev/misc/rtc No usable clock interface found. hwclock: Cannot access the Hardware Clock via any known method. Now: root# hwclock 2020-02-16 18:23:55.374134+00:00 root# hwclock -w hwclock: ioctl(RTC_SET_TIME) to /dev/rtc to set the time failed: Permission denied Signed-off-by: Julio Faracco <jcfaracco@gmail.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
cab3622119
commit
9132badf27
@ -2465,7 +2465,7 @@
|
|||||||
being modified, and can be one of
|
being modified, and can be one of
|
||||||
"platform" (currently unsupported),
|
"platform" (currently unsupported),
|
||||||
"hpet" (libxl, xen, qemu), "kvmclock" (qemu),
|
"hpet" (libxl, xen, qemu), "kvmclock" (qemu),
|
||||||
"pit" (qemu), "rtc" (qemu), "tsc" (libxl, qemu -
|
"pit" (qemu), "rtc" (qemu, lxc), "tsc" (libxl, qemu -
|
||||||
<span class="since">since 3.2.0</span>), "hypervclock"
|
<span class="since">since 3.2.0</span>), "hypervclock"
|
||||||
(qemu - <span class="since">since 1.2.2</span>) or
|
(qemu - <span class="since">since 1.2.2</span>) or
|
||||||
"armvtimer" (qemu - <span class="since">since 6.1.0</span>).
|
"armvtimer" (qemu - <span class="since">since 6.1.0</span>).
|
||||||
|
@ -333,6 +333,46 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def,
|
|||||||
VIR_CGROUP_DEVICE_RWM) < 0)
|
VIR_CGROUP_DEVICE_RWM) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
VIR_DEBUG("Allowing timers char devices");
|
||||||
|
|
||||||
|
/* Sync'ed with Host clock */
|
||||||
|
for (i = 0; i < def->clock.ntimers; i++) {
|
||||||
|
virDomainTimerDefPtr timer = def->clock.timers[i];
|
||||||
|
const char *dev = NULL;
|
||||||
|
|
||||||
|
/* Check if "present" is set to "no" otherwise enable it. */
|
||||||
|
if (!timer->present)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch ((virDomainTimerNameType)timer->name) {
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_TSC:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_PIT:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_HPET:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_LAST:
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_RTC:
|
||||||
|
dev = "/dev/rtc0";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!virFileExists(dev)) {
|
||||||
|
VIR_DEBUG("Ignoring non-existent device %s", dev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virCgroupAllowDevicePath(cgroup, dev,
|
||||||
|
VIR_CGROUP_DEVICE_READ,
|
||||||
|
false) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
VIR_DEBUG("Device whitelist complete");
|
VIR_DEBUG("Device whitelist complete");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1530,6 +1530,73 @@ static int virLXCControllerPopulateDevices(virLXCControllerPtr ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
virLXCControllerSetupTimers(virLXCControllerPtr ctrl)
|
||||||
|
{
|
||||||
|
virDomainDefPtr def = ctrl->def;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
/* Not sync'ed with Host clock */
|
||||||
|
if (def->clock.offset != VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < def->clock.ntimers; i++) {
|
||||||
|
virDomainTimerDefPtr timer = def->clock.timers[i];
|
||||||
|
g_autofree char *path = NULL;
|
||||||
|
const char *timer_dev = NULL;
|
||||||
|
struct stat sb;
|
||||||
|
dev_t dev;
|
||||||
|
|
||||||
|
/* Check if "present" is set to "no" otherwise enable it. */
|
||||||
|
if (!timer->present)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch ((virDomainTimerNameType)timer->name) {
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_PLATFORM:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_TSC:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_PIT:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_HPET:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_ARMVTIMER:
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_LAST:
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("unsupported timer type (name) '%s'"),
|
||||||
|
virDomainTimerNameTypeToString(timer->name));
|
||||||
|
return -1;
|
||||||
|
case VIR_DOMAIN_TIMER_NAME_RTC:
|
||||||
|
timer_dev = "/dev/rtc0";
|
||||||
|
path = g_strdup_printf("/%s/%s.dev/%s", LXC_STATE_DIR,
|
||||||
|
def->name, "/rtc");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!timer_dev)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (stat(timer_dev, &sb) < 0) {
|
||||||
|
virReportSystemError(errno, _("Unable to access %s"),
|
||||||
|
timer_dev);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = makedev(major(sb.st_rdev), minor(sb.st_rdev));
|
||||||
|
if (mknod(path, S_IFCHR, dev) < 0 ||
|
||||||
|
chmod(path, sb.st_mode)) {
|
||||||
|
virReportSystemError(errno,
|
||||||
|
_("Failed to make device %s"),
|
||||||
|
path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lxcContainerChown(def, path) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virLXCControllerSetupHostdevSubsysUSB(virDomainDefPtr vmDef,
|
virLXCControllerSetupHostdevSubsysUSB(virDomainDefPtr vmDef,
|
||||||
virDomainHostdevDefPtr def,
|
virDomainHostdevDefPtr def,
|
||||||
@ -2321,6 +2388,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
|
|||||||
if (virLXCControllerPopulateDevices(ctrl) < 0)
|
if (virLXCControllerPopulateDevices(ctrl) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virLXCControllerSetupTimers(ctrl) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
if (virLXCControllerSetupAllDisks(ctrl) < 0)
|
if (virLXCControllerSetupAllDisks(ctrl) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user