From: Arnd Bergmann Date: Thu, 13 Oct 2016 18:04:39 +0000 (-0400) Subject: LU-4423 libcfs: tracefile document seconds overflow X-Git-Tag: 2.9.52~71 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=a05ff6f7a0377bb1c2f9b1699f9b08ae9e981e1e LU-4423 libcfs: tracefile document seconds overflow The lustre tracefile has a timestamp defined as __u32 ph_sec; __u64 ph_usec; which seems completely backwards, as the microsecond portion of a time stamp will always fit into a __u32 value, while the second portion will overflow in 2038 or 2106 (in case of unsigned seconds). Changing this would unfortunately change the format in an incompatible way, breaking all existing user space tools that access the data. This uses ktime_get_real_ts64() to replace the insufficient do_gettimeofday() and then truncates the seconds portion to an u32 type, along with comments to explain the result. A possible alternative would be the use of ktime_get_ts64() to read a monotonic timestamp that never overflows, but this would trigger a check in user space 'hdr->ph_sec < (1 << 30)' that attempts to ensure that the values are within a reasonable range. Linux-commit: 65f28840e4c653b7d78feabcb65280c09d3d0d23 Signed-off-by: Arnd Bergmann Change-Id: I5fdf6d09d39fbb4da8ccba51a745b00996f116f7 Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/23137 Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Frank Zago Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin --- diff --git a/libcfs/include/libcfs/libcfs_debug.h b/libcfs/include/libcfs/libcfs_debug.h index 7ee1951..1f23b60 100644 --- a/libcfs/include/libcfs/libcfs_debug.h +++ b/libcfs/include/libcfs/libcfs_debug.h @@ -70,6 +70,7 @@ struct ptldebug_header { __u32 ph_mask; __u16 ph_cpu_id; __u16 ph_type; + /* time_t overflow in 2106 */ __u32 ph_sec; __u64 ph_usec; __u32 ph_stack; diff --git a/libcfs/libcfs/linux/linux-tracefile.c b/libcfs/libcfs/linux/linux-tracefile.c index 38edb50..6e08612 100644 --- a/libcfs/libcfs/linux/linux-tracefile.c +++ b/libcfs/libcfs/linux/linux-tracefile.c @@ -188,16 +188,19 @@ cfs_set_ptldebug_header(struct ptldebug_header *header, struct libcfs_debug_msg_data *msgdata, unsigned long stack) { - struct timeval tv; + struct timespec64 ts; - do_gettimeofday(&tv); + ktime_get_real_ts64(&ts); header->ph_subsys = msgdata->msg_subsys; header->ph_mask = msgdata->msg_mask; header->ph_cpu_id = smp_processor_id(); header->ph_type = cfs_trace_buf_idx_get(); - header->ph_sec = (__u32)tv.tv_sec; - header->ph_usec = tv.tv_usec; + /* y2038 safe since all user space treats this as unsigned, but + * will overflow in 2106 + */ + header->ph_sec = (u32)ts.tv_sec; + header->ph_usec = ts.tv_nsec / NSEC_PER_USEC; header->ph_stack = stack; header->ph_pid = current->pid; header->ph_line_num = msgdata->msg_line;