[Devel] [PATCH rh9 v2] kmsg: Virtualize timestamps in /dev/ksmg output
Alexander Atanasov
alexander.atanasov at virtuozzo.com
Mon Feb 13 11:23:30 MSK 2023
On 8.02.23 14:27, Konstantin Khorenko wrote:
> Internally log messages contain the timestamps relative to the Host boot
> time, while Container could start much later than the Host boots and the
> timestamps should be shifted accordingly.
>
> Otherwise "dmesg -H" reports data from the future.
>
> Note:
> * time_ns->offsets.boottime is (ve_uptime - host_uptime),
> i.e. negative for Containers created on this Host
> * ring buffer contains timestamps relative to the Host boot
>
> => we have to add the .boottime offset to the timestamp of Host
> to get the msg entry timestamp relative to Container boottime.
>
> Note 2: we cannot use timespec64_to_ns() in ve_timens_sub_boottime_ns()
> to convert .boottime to nsec because timespec64_to_ns() is not
> designed to handle negative offsets, it tries to avoid the
> overflow and returns KTIME_MAX instead for negative offsets.
>
> Based on the vz7 commit
> e20414197aef ("kmsg: Virtualize timestamps in /dev/ksmg output")
>
> https://jira.sw.ru/browse/PSBM-145313
>
> Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
>
> v2 changes:
> * ve_timens_add_boottime_ns() should return "nsec", not 0 in case
> Container is not started yet
>
> ---
> kernel/printk/printk.c | 21 +++++++++++++++++++++
> 1 file changed, 21 insertions(+)
>
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index c68e3b468ab7..57a8b708ecb3 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -600,6 +600,25 @@ static void append_char(char **pp, char *e, char c)
> *(*pp)++ = c;
> }
>
> +static inline u64 ve_timens_add_boottime_ns(u64 nsec)
> +{
> + struct time_namespace *ve_time_ns;
> + struct timens_offsets *ns_offsets;
> +
> + ve_time_ns = ve_get_time_ns(get_exec_env());
> + if (unlikely(!ve_time_ns)) {
> + /* container not yet started */
> + return nsec;
> + }
> +
> + ns_offsets = &ve_time_ns->offsets;
> + nsec += ns_offsets->boottime.tv_sec * NSEC_PER_SEC;
> + nsec += ns_offsets->boottime.tv_nsec;
> + put_time_ns(ve_time_ns);
> +
> + return nsec;
> +}
> +
> static ssize_t info_print_ext_header(char *buf, size_t size,
> struct printk_info *info)
> {
> @@ -614,6 +633,8 @@ static ssize_t info_print_ext_header(char *buf, size_t size,
> caller[0] = '\0';
> #endif
>
> + /* shift the timestamp on the Container uptime value */
> + ts_usec = ve_timens_add_boottime_ns(ts_usec);
> do_div(ts_usec, 1000);
>
> return scnprintf(buf, size, "%u,%llu,%llu,%c%s;",
LGTM
--
Regards,
Alexander Atanasov
More information about the Devel
mailing list