All of lore.kernel.org
 help / color / mirror / Atom feed
From: JWP <elseifthen@gmx.com>
To: "Noé Rubinstein" <nrubinstein@aldebaran.com>, util-linux@vger.kernel.org
Cc: "Noé Rubinstein" <noe.rubinstein@gmail.com>
Subject: Re: [RFC PATCH] hwclock: --offset: Use offset instead of writing clock
Date: Tue, 07 Oct 2014 07:28:08 -0400	[thread overview]
Message-ID: <5433CE48.7060507@gmx.com> (raw)
In-Reply-To: <1412673336-13299-1-git-send-email-nrubinstein@aldebaran.com>

Hello Noé,
 I just submitted a patch on 14-09-27 that adds this functionality
without creating a new state file.

On 10/07/2014 05:15 AM, Noé Rubinstein wrote:
> From: Noé Rubinstein <noe.rubinstein@gmail.com>
> 
> This option is useful for systems that have a working hardware clock, but do
> not provide a way to write to it. Instead of setting the hardware clock, write
> the difference between hardware and system clock to a file; when getting the
> hardware clock, add the offset from this file to obtain the correct time.
> 
> I have not checked how well this interacts with the adjtime mechanism, so
> this is an RFC patch.
> ---
>  sys-utils/hwclock.8.in |  6 ++++
>  sys-utils/hwclock.c    | 88 ++++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 92 insertions(+), 2 deletions(-)
> 
> diff --git a/sys-utils/hwclock.8.in b/sys-utils/hwclock.8.in
> index b11b45c..63fabda 100644
> --- a/sys-utils/hwclock.8.in
> +++ b/sys-utils/hwclock.8.in
> @@ -113,6 +113,12 @@ not reset.
>  .BR \-w , \ \-\-systohc
>  Set the Hardware Clock to the current System Time.
>  .TP
> +.BR \-\-offset[=filename]
> +This option is useful for systems that have a working hardware clock, but do
> +not provide a way to write to it. Instead of setting the hardware clock, write
> +the difference between hardware and system clock to a file; when getting the
> +hardware clock, add the offset from this file to obtain the correct time.
> +.TP
>  .BR \-V , \ \-\-version
>  Display version information and exit.
>  .TP
> diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c
> index e780158..c7deab9 100644
> --- a/sys-utils/hwclock.c
> +++ b/sys-utils/hwclock.c
> @@ -98,6 +98,7 @@ struct clock_ops *ur;
>  #define MAX_DRIFT 2145.0
>  
>  const char *adj_file_name = NULL;
> +const char *offset_file_name = NULL;
>  
>  struct adjtime {
>  	/*
> @@ -234,6 +235,35 @@ hw_clock_is_utc(const bool utc, const bool local_opt,
>  	return ret;
>  }
>  
> +static int read_offset(struct timeval *offset)
> +{
> +	FILE *f;
> +	int rc;
> +	f = fopen(offset_file_name, "r");
> +	if (!f)
> +		return -errno;
> +
> +	rc = fread(offset, sizeof(*offset), 1, f);
> +	fclose(f);
> +
> +	return rc == 1 ? 0 : -EINVAL;
> +}
> +
> +static int write_offset(struct timeval offset)
> +{
> +	FILE *f;
> +	int rc;
> +	f = fopen(offset_file_name, "w");
> +	if (!f)
> +		return -errno;
> +
> +	rc = fwrite(&offset, sizeof(offset), 1, f);
> +	fclose(f);
> +
> +	return rc == 1 ? 0 : -EINVAL;
> +}
> +
> +
>  /*
>   * Read the adjustment parameters out of the /etc/adjtime file.
>   *
> @@ -1290,6 +1320,8 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
>  	bool no_auth;
>  	/* The time at which we read the Hardware Clock */
>  	struct timeval read_time;
> +	/* The offset between system time and hardware time */
> +	struct timeval offset = {0};
>  	/*
>  	 * The Hardware Clock gives us a valid time, or at
>  	 * least something close enough to fool mktime().
> @@ -1320,6 +1352,11 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
>  		adjtime.dirty = FALSE;
>  	}
>  
> +	if ((hctosys || show) && offset_file_name)
> +	{
> +		read_offset(&offset);
> +	}
> +
>  	universal = hw_clock_is_utc(utc, local_opt, adjtime);
>  
>  	if ((set || systohc || adjust) &&
> @@ -1328,7 +1365,8 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
>  		adjtime.dirty = TRUE;
>  	}
>  
> -	if (show || adjust || hctosys || (!noadjfile && !systz && !predict)) {
> +	if (show || adjust || hctosys || (!noadjfile && !systz && !predict) ||
> +	    offset_file_name) {
>  		/* data from HW-clock are required */
>  		rc = synchronize_to_clock_tick();
>  
> @@ -1358,8 +1396,20 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
>  	}
>  
>  	if (show) {
> -		display_time(hclock_valid, hclocktime,
> +		display_time(hclock_valid, hclocktime + offset.tv_sec,
>  			     time_diff(read_time, startup_time));
> +	} else if (set && offset_file_name) {
> +		if (!hclock_valid) {
> +			printf(_("Hardware clock invalid, not writing offset.\n"));
> +		} else {
> +			offset.tv_sec = set_time - hclocktime;
> +			rc = write_offset(offset);
> +			if (rc) {
> +				printf(_("Unable to write offset: %s."), strerror(-rc));
> +				return rc;
> +			}
> +		}
> +
>  	} else if (set) {
>  		set_hardware_clock_exact(set_time, startup_time,
>  					 universal, testing);
> @@ -1371,6 +1421,18 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
>  	} else if (adjust) {
>  		do_adjustment(&adjtime, hclock_valid,
>  			      hclocktime, read_time, universal, testing);
> +	} else if (systohc && offset_file_name) {
> +		if (!hclock_valid) {
> +			printf(_("Hardware clock invalid, not writing offset.\n"));
> +		} else {
> +			gettimeofday(&offset, NULL);
> +			offset.tv_sec -= hclocktime;
> +			rc = write_offset(offset);
> +			if (rc) {
> +				printf(_("Unable to write offset: %s."), strerror(-rc));
> +				return rc;
> +			}
> +		}
>  	} else if (systohc) {
>  		struct timeval nowtime, reftime;
>  		/*
> @@ -1390,6 +1452,17 @@ manipulate_clock(const bool show, const bool adjust, const bool noadjfile,
>  					    reftime.tv_sec,
>  					    hclock_valid, hclocktime, (double)
>  					    read_time.tv_usec / 1E6);
> +	} else if (hctosys && offset_file_name) {
> +		if (!hclock_valid) {
> +			printf(_("Hardware clock invalid, not setting time.\n"));
> +		} else {
> +			offset.tv_sec += hclocktime;
> +			rc = settimeofday(&offset, NULL);
> +			if (rc) {
> +				printf(_("Unable to set system clock.\n"));
> +				return rc;
> +			}
> +		}
>  	} else if (hctosys) {
>  		rc = set_system_clock(hclock_valid, hclocktime, testing);
>  		if (rc) {
> @@ -1547,6 +1620,7 @@ static void out_version(void)
>  	printf(UTIL_LINUX_VERSION);
>  }
>  
> +#define DEFAULT_OFFSET_FILE "/etc/time_offset"
>  /*
>   * usage - Output (error and) usage information
>   *
> @@ -1577,6 +1651,10 @@ static void usage(const char *fmt, ...)
>  		"     --adjust         adjust the RTC to account for systematic drift since\n"
>  		"                        the clock was last set or adjusted\n"), usageto);
>  	fputs(_(" -c, --compare        periodically compare the system clock with the CMOS clock\n"), usageto);
> +	fprintf(usageto,
> +	      _("     --offset [file]  instead of setting the clock, write an offset to file.\n"
> +	        "                      when reading the time, add this offset to the hardware time.\n"
> +		"                         (default: %s)\n"), DEFAULT_OFFSET_FILE);
>  #ifdef __linux__
>  	fputs(_("     --getepoch       print out the kernel's hardware clock epoch value\n"
>  		"     --setepoch       set the kernel's hardware clock epoch value to the \n"
> @@ -1653,6 +1731,7 @@ int main(int argc, char **argv)
>  	/* Long only options. */
>  	enum {
>  		OPT_ADJFILE = CHAR_MAX + 1,
> +		OPT_OFFSET,
>  		OPT_BADYEAR,
>  		OPT_DATE,
>  		OPT_DIRECTISA,
> @@ -1698,6 +1777,7 @@ int main(int argc, char **argv)
>  		{"test",	0, 0, OPT_TEST},
>  		{"date",	1, 0, OPT_DATE},
>  		{"epoch",	1, 0, OPT_EPOCH},
> +		{"offset",	2, 0, OPT_OFFSET},
>  #ifdef __linux__
>  		{"rtc",		1, 0, 'f'},
>  #endif
> @@ -1837,6 +1917,10 @@ int main(int argc, char **argv)
>  		case OPT_PREDICT_HC:
>  			predict = TRUE;		/* --predict-hc */
>  			break;
> +		case OPT_OFFSET:
> +			offset_file_name =	/* --offset */
> +				optarg ? optarg : DEFAULT_OFFSET_FILE;
> +			break;
>  #ifdef __linux__
>  		case 'f':
>  			rtc_dev_name = optarg;	/* --rtc */
> 

  reply	other threads:[~2014-10-07 11:28 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-07  9:15 [RFC PATCH] hwclock: --offset: Use offset instead of writing clock Noé Rubinstein
2014-10-07 11:28 ` JWP [this message]
2014-10-07 11:52   ` Noé RUBINSTEIN
2014-10-07 12:13     ` JWP
2014-10-07 12:48       ` Noé RUBINSTEIN
2014-10-07 15:19         ` JWP
2014-10-07 15:50         ` JWP
2014-10-09  8:51           ` Noé RUBINSTEIN
2014-10-09 11:15             ` JWP
2014-10-09 15:05               ` Noé RUBINSTEIN
2014-10-10  0:11                 ` JWP

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5433CE48.7060507@gmx.com \
    --to=elseifthen@gmx.com \
    --cc=noe.rubinstein@gmail.com \
    --cc=nrubinstein@aldebaran.com \
    --cc=util-linux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.