Announcement

Collapse
No announcement yet.

Wrong time zone on your clock? Help Kubuntu devs create a fix

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Wrong time zone on your clock? Help Kubuntu devs create a fix

    Several posts here at KFN report a problem with the clock. Usually, it's off by an hour. In most cases, reconfiguring the tzdata package fixes the problem, as described in http://www.kubuntuforums.net/showthr...171#post324366. The bug appears to be upstream, and is reported in https://bugs.kde.org/show_bug.cgi?id=318709, but has so far received no activity.

    To fix the problem, Kubuntu developers have requested some information from folks having the problem. This information needs to be gathered before reconfiguring tzdata. If you notice the problem on your machine, please run the following command string in a console window:

    Code:
    ls -l /etc/timezone; cat /etc/timezone; echo""; echo ""; ls -l /etc/adjtime; cat /etc/adjtime; echo ""; ls -l /etc/localtime; cat `readlink /etc/localtime`
    Enter it as one single line. The final command, cat `readlink /etc/localtime`, should cause the shell to simply wait. Press Ctrl+C to terminate it. Once you've run the command, copy-paste all of the output into a reply here.

    As an example, here's what happens on my laptop, which is not affected by the timezone problem:

    Code:
    steve@t520:~$ ls -l /etc/timezone; cat /etc/timezone; echo""; echo ""; ls -l /etc/adjtime; cat /etc/adjtime; echo ""; ls -l /etc/localtime; cat `readlink /etc/localtime`
    -rw-r--r-- 1 root root 20 Apr 26 15:52 /etc/timezone
    America/Los_Angeles
    
    
    -rw-r--r-- 1 root root 44 Mar 15 04:44 /etc/adjtime
    0.000000 1363347848 0.000000
    1363347848
    UTC
    
    -rw-r--r-- 1 root root 2819 Apr 26 15:52 /etc/localtime
    ^C
    steve@t520:~$

    #2
    I have this problem too, but on Kubuntu 12.10 with KDE SC 4.10.2. I have reconfigured tzdata, but the clock shows UTC instead of CEST after some time/reboot.

    Code:
    ls -l /etc/timezone; cat /etc/timezone; echo""; echo ""; ls -l /etc/adjtime; cat /etc/adjtime; echo ""; ls -l /etc/localtime; cat `readlink /etc/localtime`
    -rw-r--r-- 1 root root 17 Jun  8 00:18 /etc/timezone
    Europe/Copenhagen
    
    -rw-r--r-- 1 root root 47 Jun  8 00:18 /etc/adjtime
    -173.006089 1370650720 0.000000
    1370650720
    UTC
    
    lrwxrwxrwx 2 root root 26 Jan  2 13:36 /etc/localtime -> ../posix/Europe/Copenhagen
    cat: ../posix/Europe/Copenhagen: No such file or directory

    Comment


      #3
      If it was yet another dpkg-reconfigure tzdata, or an update to KDE 4.10.4 that did it, I don't know, but it seems to work now after a reboot.

      Comment


        #4
        Originally posted by tanghus View Post
        Code:
        lrwxrwxrwx 2 root root 26 Jan  2 13:36 /etc/localtime -> ../posix/Europe/Copenhagen
        cat: ../posix/Europe/Copenhagen: No such file or directory
        This is where the problem lies, /etc/localtime being a broken link...The link would work if the path was correct (timezone data files can be found in /usr/share/zoneinfo).
        Tzdata reconfiguration seems to remove the link and replace it with a copy of the correct timezone file.
        Changing settings in kde's clock settings module might restore the (broken) link.

        Comment


          #5
          Originally posted by kubicle View Post
          This is where the problem lies, /etc/localtime being a broken link...The link would work if the path was correct (timezone data files can be found in /usr/share/zoneinfo). Tzdata reconfiguration seems to remove the link and replace it with a copy of the correct timezone file.
          I asked Harald about this on kubuntu-devel:
          I had started to write a forum post requesting people to provide the information in Harald's command. However, there appears to be a problem. /etc/localtime isn't a link on my machine, it's a normal file:

          steve at t520:~$ ls -l /etc/localtime
          -rw-r--r-- 1 root root 2819 Apr 26 15:52 /etc/localtime

          Because it's a normal file, readlink returns nothing:

          steve at t520:~$ readlink /etc/localtime
          steve at t520:~$

          And cat `readlink localtime` just causes the shell to wait until I press Ctrl+C.
          I was curious as to what should be expected, because on openSUSE and Arch, /etc/localtime is, in fact, a symlink. But apparently Ubuntu (and probably Debian) copy the zoneinfo file. Harald replied:
          that is the expected behavior on a proper system
          The question, then, is what's causing broken symlinks to appear? Has some script that expects the symlink behavior snuck into some Ubuntu package somewhere?

          Comment


            #6
            I think harald meant that 'readlink /etc/localtime' hanging (and requiring ctrl+c) if /etc/localtime is not a link is "the expected behavior on a proper system".

            As it were, there is a /usr/share/zoneinfo/localtime link that points to /etc/localtime...the "wrong" relative path (../posix/AREA/CITY) would actually be correct in relation to /usr/share/zoneinfo/localtime, but obviously not in /etc/localtime.

            EDIT: I'll take that back, it wouldn't work correctly even on /usr/share/zoneinfo/localtime...although it would be a lot closer :P)


            BTW, It shouldn't matter whether localtime is a symlink or a copy of the correct file, as long as the path for the symlink is correct, so I'd hunt down what writes the faulty path and fix it (my guess is the KDE systemsettings module for time settings).
            Last edited by kubicle; Jun 14, 2013, 12:41 AM.

            Comment


              #7
              Interesting. On my openSUSE build, there is no /usr/share/zoneinfo/localtime.

              Comment


                #8
                Here's what is in the source for the systemsettings module (4.10.4):
                Code:
                        QString tz = "/usr/share/zoneinfo/" + selectedzone;
                
                        QString zic = KStandardDirs::findExe("zic", exePath);
                        if (!zic.isEmpty()) {
                            KProcess::execute(zic, QStringList() << "-l" << selectedzone);
                        } else if (!QFile::remove("/etc/localtime")) {
                          ret |= TimezoneError;
                        } else if (!QFile::copy(tz, "/etc/localtime")) {
                          ret |= TimezoneError;
                        }
                Unfortunately, there doesn't seem to be anything wrong with it (at least on first glance)..."zic -l <timezone>" should do the job as expected.

                Comment


                  #9
                  I may have found where the "faulty paths" come from:

                  for example:
                  #zic -l America/Chicago
                  #ls -l /etc/localtime
                  lrwxrwxrwx 2 root root /etc/localtime -> ../US/Central == broken link (it copies the link /usr/share/zoneinfo/America/Chicago to /etc/localtime, not the link target)
                  #zic -l US/Central
                  #ls -l /etc/localtime
                  -rw-r--r-- 2 root root /etc/localtime == functioning copy of /usr/share/zoneinfo/US/Central

                  EDIT: So the time module issue seems to depend on whether your chosen timezone is a file or a link, which might explain why the issue only affects some users and not others?
                  Last edited by kubicle; Jun 17, 2013, 11:57 PM.

                  Comment


                    #10
                    I'm having the same issue.
                    Code:
                    ricky@ci5-Studio-XPS-1647:/etc$ ls -il ./localtime 
                    6964307 lrwxrwxrwx 2 root root 28 Mar 14 10:46 ./localtime -> ../posix/Australia/Melbourne
                    ricky@ci5-Studio-XPS-1647:/etc$ ls -il /usr/share/zoneinfo/Australia/Melbourne 
                    6964307 lrwxrwxrwx 2 root root 28 Mar 14 10:46 /usr/share/zoneinfo/Australia/Melbourne -> ../posix/Australia/Melbourne
                    Seems like the issue lies with zic. It creates a hard link of a soft link (/usr/share/zoneinfo/Australia/Melbourne). This wouldn't be a problem if it creates a soft link or the link() system call deferences soft links. I'm looking at the zic source code at the moment and there doesn't seem to be any check on whether the link target is a soft link or not:
                    Code:
                    static void
                    dolink(const char *const fromfield, const char *const tofield)
                    {
                    	register char *	fromname;
                    	register char *	toname;
                    
                    	if (fromfield[0] == '/')
                    		fromname = ecpyalloc(fromfield);
                    	else {
                    		fromname = ecpyalloc(directory);
                    		fromname = ecatalloc(fromname, "/");
                    		fromname = ecatalloc(fromname, fromfield);
                    	}
                    	if (tofield[0] == '/')
                    		toname = ecpyalloc(tofield);
                    	else {
                    		toname = ecpyalloc(directory);
                    		toname = ecatalloc(toname, "/");
                    		toname = ecatalloc(toname, tofield);
                    	}
                    	/*
                    	** We get to be careful here since
                    	** there's a fair chance of root running us.
                    	*/
                    	if (!itsdir(toname))
                    		(void) remove(toname);
                    	if (link(fromname, toname) != 0) {
                    		int	result;
                    
                    		if (mkdirs(toname) != 0)
                    			exit(EXIT_FAILURE);
                    
                    		result = link(fromname, toname);
                    #if HAVE_SYMLINK
                    		if (result != 0 &&
                    			access(fromname, F_OK) == 0 &&
                    			!itsdir(fromname)) {
                    				const char *s = tofield;
                    				register char * symlinkcontents = NULL;
                    
                    				while ((s = strchr(s+1, '/')) != NULL)
                    					symlinkcontents =
                    						ecatalloc(symlinkcontents,
                    						"../");
                    				symlinkcontents =
                    					ecatalloc(symlinkcontents,
                    					fromname);
                    				result = symlink(symlinkcontents,
                    					toname);
                    				if (result == 0)
                    warning(_("hard link failed, symbolic link used"));
                    				free(symlinkcontents);
                    		}
                    #endif /* HAVE_SYMLINK */
                    		if (result != 0) {
                    			const char *e = strerror(errno);
                    
                    			(void) fprintf(stderr,
                    				_("%s: Can't link from %s to %s: %s\n"),
                    				progname, fromname, toname, e);
                    			exit(EXIT_FAILURE);
                    		}
                    	}
                    	free(fromname);
                    	free(toname);
                    }
                    I think there should be a check on whether the link target is a soft link. If it is, create a soft link (/etc/localtime) to a soft link target (/usr/share/zoneinfo/Australia/Melbourne). Otherwise, create a hard link as usual.

                    Does this warrant a patch?

                    Comment


                      #11
                      Originally posted by mysticalzero View Post
                      I'm having the same issue.
                      I think there should be a check on whether the link target is a soft link. If it is, create a soft link (/etc/localtime) to a soft link target (/usr/share/zoneinfo/Australia/Melbourne). Otherwise, create a hard link as usual.

                      Does this warrant a patch?
                      Yes this warrants a patch. Thanks for this really good find, we'll have a look.
                      apachelogger, Kubuntu Core Developer and Master of the Minions.

                      Comment


                        #12
                        Originally posted by apachelogger View Post
                        Yes this warrants a patch. Thanks for this really good find, we'll have a look.
                        I did a few things few days ago. I thought it would be good to share this.

                        First of all, I've modified zic.c by doing the following:
                        Code:
                        --- a/timezone/zic.c	2012-11-18 04:50:14.000000000 +1100
                        +++ b/timezone/zic.c	2013-06-22 03:56:09.000000000 +1000
                        @@ -7,6 +7,8 @@
                         #include "private.h"
                         #include "locale.h"
                         #include "tzfile.h"
                        +#include <sys/types.h>
                        +#include <sys/stat.h>
                         
                         #define	ZIC_VERSION	'2'
                         
                        @@ -581,6 +583,8 @@
                         {
                         	register char *	fromname;
                         	register char *	toname;
                        +	
                        +	struct stat sb;
                         
                         	if (fromfield[0] == '/')
                         		fromname = ecpyalloc(fromfield);
                        @@ -602,42 +606,57 @@
                         	*/
                         	if (!itsdir(toname))
                         		(void) remove(toname);
                        -	if (link(fromname, toname) != 0) {
                        -		int	result;
                        +	if(lstat(fromname, &sb) == -1) {
                        +	  
                        +	  perror("stat");
                        +	  exit(EXIT_FAILURE);
                        +	  
                        +	}
                        +	/* If fromname refers to a symlink, create a symlink 
                        +	 * toname instead of a hard link.
                        +	 */
                        +	if((sb.st_mode & S_IFMT) == S_IFLNK) {
                        +	  
                        +	  symlink(fromname, toname);
                        +	  
                        +	} else {
                        +	  if (link(fromname, toname) != 0) {
                        +		  int	result;
                         
                        -		if (mkdirs(toname) != 0)
                        -			exit(EXIT_FAILURE);
                        +		  if (mkdirs(toname) != 0)
                        +			  exit(EXIT_FAILURE);
                         
                        -		result = link(fromname, toname);
                        +		  result = link(fromname, toname);
                         #if HAVE_SYMLINK
                        -		if (result != 0 &&
                        -			access(fromname, F_OK) == 0 &&
                        -			!itsdir(fromname)) {
                        -				const char *s = tofield;
                        -				register char * symlinkcontents = NULL;
                        -
                        -				while ((s = strchr(s+1, '/')) != NULL)
                        -					symlinkcontents =
                        -						ecatalloc(symlinkcontents,
                        -						"../");
                        -				symlinkcontents =
                        -					ecatalloc(symlinkcontents,
                        -					fromname);
                        -				result = symlink(symlinkcontents,
                        -					toname);
                        -				if (result == 0)
                        -warning(_("hard link failed, symbolic link used"));
                        -				free(symlinkcontents);
                        -		}
                        +		  if (result != 0 &&
                        +			  access(fromname, F_OK) == 0 &&
                        +			  !itsdir(fromname)) {
                        +				  const char *s = tofield;
                        +				  register char * symlinkcontents = NULL;
                        +
                        +				  while ((s = strchr(s+1, '/')) != NULL)
                        +					  symlinkcontents =
                        +						  ecatalloc(symlinkcontents,
                        +						  "../");
                        +				  symlinkcontents =
                        +					  ecatalloc(symlinkcontents,
                        +					  fromname);
                        +				  result = symlink(symlinkcontents,
                        +					  toname);
                        +				  if (result == 0)
                        +  warning(_("hard link failed, symbolic link used"));
                        +				  free(symlinkcontents);
                        +		  }
                         #endif /* HAVE_SYMLINK */
                        -		if (result != 0) {
                        -			const char *e = strerror(errno);
                        +		  if (result != 0) {
                        +			  const char *e = strerror(errno);
                         
                        -			(void) fprintf(stderr,
                        -				_("%s: Can't link from %s to %s: %s\n"),
                        -				progname, fromname, toname, e);
                        -			exit(EXIT_FAILURE);
                        -		}
                        +			  (void) fprintf(stderr,
                        +				  _("%s: Can't link from %s to %s: %s\n"),
                        +				  progname, fromname, toname, e);
                        +			  exit(EXIT_FAILURE);
                        +		  }
                        +	  }
                         	}
                         	free(fromname);
                         	free(toname);
                        It's not meant to be a general patch. It's just a quick fix to see if it worked. And, it does.
                        Code:
                        ricky@ci5-Studio-XPS-1647:~$ sudo zic -l Australia/Melbourne
                        ricky@ci5-Studio-XPS-1647:~$ ls -il /etc/localtime 
                        6964307 lrwxrwxrwx 2 root root 28 Mar 14 10:46 /etc/localtime -> ../posix/Australia/Melbourne
                        ricky@ci5-Studio-XPS-1647:~$ sudo zic_fixed -l Australia/Melbourne
                        ricky@ci5-Studio-XPS-1647:~$ ls -il /etc/localtime 
                        9209722 lrwxrwxrwx 1 root root 39 Jun 25 02:05 /etc/localtime -> /usr/share/zoneinfo/Australia/Melbourne
                        The second thing I want to mention is that zic -l <zone> failed on debian wheezy too.
                        Code:
                        ricky@debian:~$ lsb_release -a
                        No LSB modules are available.
                        Distributor ID: Debian
                        Description:    Debian GNU/Linux 7.1 (wheezy)
                        Release:        7.1
                        Codename:       wheezy
                        ricky@debian:~$ ls -il /etc/localtime 
                        262304 -rw-r--r-- 1 root root 2183 Jun 23 16:47 /etc/localtime
                        ricky@debian:~$ sudo zic -l Australia/Melbourne
                        [sudo] password for ricky: 
                        ricky@debian:~$ ls -il /etc/localtime 
                        401098 lrwxrwxrwx 2 root root 27 May 13 21:38 /etc/localtime -> ../posix/Australia/Victoria
                        ricky@debian:~$ ls -il /usr/share/zoneinfo/Australia/Melbourne 
                        401098 lrwxrwxrwx 2 root root 27 May 13 21:38 /usr/share/zoneinfo/Australia/Melbourne -> ../posix/Australia/Victoria
                        I guess it's a problem with zic after all.

                        Having said that, the KDE date and time module in debian wheezy has no issues with time change even though the direct usage of zic failed to configure the time correctly if the target is a soft link. This is attributed to the copying of the desired tz file to /etc/localtime whereas the kubuntu version creates a dangling hard link.

                        wheezy's KDE version:
                        Code:
                        Qt: 4.8.2
                        KDE Development Platform: 4.8.4 (4.8.4)
                        Konqueror: 4.8.4 (4.8.4)
                        raring's KDE version:
                        Code:
                        Qt: 4.8.4
                        KDE Development Platform: 4.10.3
                        Konqueror: 4.10.3
                        A diff of kcontrol/dateandtime/helper.cpp between the two version
                        Code:
                        --- wheezy/helper.cpp	2013-06-23 16:04:15.000000000 +1000
                        +++ raring/helper.cpp	2013-06-20 22:20:37.000000000 +1000
                        @@ -48,6 +48,10 @@
                         #include <sys/stat.h>
                         #endif
                         
                        +// We cannot rely on the $PATH environment variable, because D-Bus activation
                        +// clears it. So we have to use a reasonable default.
                        +static const QString exePath = QLatin1String("/usr/sbin:/usr/bin:/sbin:/bin");
                        +
                         int ClockHelper::ntp( const QStringList& ntpServers, bool ntpEnabled,
                                               const QString& ntpUtility )
                         {
                        @@ -96,8 +100,9 @@
                                 return DateError;
                             }
                         
                        -    if (!KStandardDirs::findExe("hwclock").isEmpty()) {
                        -        KProcess::execute("hwclock", QStringList() << "--systohc");
                        +    QString hwclock = KStandardDirs::findExe("hwclock", exePath);
                        +    if (!hwclock.isEmpty()) {
                        +        KProcess::execute(hwclock, QStringList() << "--systohc");
                             }
                             return 0;
                         }
                        @@ -172,8 +177,9 @@
                         #else
                                 QString tz = "/usr/share/zoneinfo/" + selectedzone;
                         
                        -        if( !KStandardDirs::findExe( "zic" ).isEmpty()) {
                        -            KProcess::execute("zic", QStringList() << "-l" << selectedzone);
                        +        QString zic = KStandardDirs::findExe("zic", exePath);
                        +        if (!zic.isEmpty()) {
                        +            KProcess::execute(zic, QStringList() << "-l" << selectedzone);
                                 } else if (!QFile::remove("/etc/localtime")) {
                                   ret |= TimezoneError;
                                 } else if (!QFile::copy(tz, "/etc/localtime")) {
                        What I can deduce is that the wheezy's version returns false for the conditional statement if( !KStandardDirs::findExe( "zic" ).isEmpty()) { and hence, copying is performed. False is return because it can't find zic in its $PATH perhaps(?) I can see the raring's version sets the search path explicitly though.

                        One way or another, I think the fix should be performed for zic.

                        Comment


                          #13
                          I fresh installed Kubuntu 13.04 & then immediately added in KDE 4.11 ppa on two different machines.
                          1 a Toshiba laptop (Corei5) & 2 a generic desktop built with Corei5.
                          The laptop had no issue, the custom box did. Resetting TZDATA fixed it.

                          I previously had Netrunner 13.04 (Kubuntu 13.04 derivative) on both machines without issue.

                          Comment


                            #14
                            This bug should be fixed with the latest kde-workspace package:
                            kde-workspace (4:4.11.1-0ubuntu5) saucy; urgency=low

                            * Add kubuntu_avoid_zic_and_deep_copy_timezone_data.diff
                            It does not use zic when available as zic is broken. Also adds symlink
                            handling, when a tz file is a symlink, it gets the link target and
                            copies that instead. This prevents broken symlinks. (LP: #1206199)

                            Comment

                            Working...
                            X