[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