提交 9132badf 编写于 作者: J Julio Faracco 提交者: Michal Privoznik

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: NJulio Faracco <jcfaracco@gmail.com>
Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
Reviewed-by: NMichal Privoznik <mprivozn@redhat.com>
上级 cab36221
......@@ -2465,7 +2465,7 @@
being modified, and can be one of
"platform" (currently unsupported),
"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"
(qemu - <span class="since">since 1.2.2</span>) or
"armvtimer" (qemu - <span class="since">since 6.1.0</span>).
......
......@@ -333,6 +333,46 @@ static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def,
VIR_CGROUP_DEVICE_RWM) < 0)
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");
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
virLXCControllerSetupHostdevSubsysUSB(virDomainDefPtr vmDef,
virDomainHostdevDefPtr def,
......@@ -2321,6 +2388,9 @@ virLXCControllerRun(virLXCControllerPtr ctrl)
if (virLXCControllerPopulateDevices(ctrl) < 0)
goto cleanup;
if (virLXCControllerSetupTimers(ctrl) < 0)
goto cleanup;
if (virLXCControllerSetupAllDisks(ctrl) < 0)
goto cleanup;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册