cron und die Zeitumstellung

Dieses Thema im Forum "Geplauder, Fun und Chillzone" wurde erstellt von bananenBrot, 22 März 2012.

  1. bananenBrot

    bananenBrot Member

    Registriert seit:
    3 Juli 2008
    Beiträge:
    420
    Hi,

    mal eine Frage.

    Nehmen wir mal an, ich habe einen Cron-Job, der jede Nacht um 02:15 Uhr ein Script tues.sh aufruft.
    Wird dieses Script am kommenden Sonntag morgen laufen?

    Nehmen wir jetzt an, es ist ein Cron-Job, der jede Nacht um 02:15 Uhr und um 03:15 Uhr ausgelöst wird.
    Wird tues.sh um 03:15 Uhr 2x aufgerufen? (es wird ja kein 02:15 Uhr geben)

    Ich bin echt überfragt...
  2. unull

    unull Nervensäge

    Registriert seit:
    28 Februar 2005
    Beiträge:
    147
    Ort:
    ::1
    Das Sript um 02:15 wird laufen. Hier mal der passende Auszug aus cron(8):

    Code:
         -s      Enable special handling of situations when the GMT offset of the
                 local timezone changes, such as the switches between the standard
                 time and daylight saving time.
         
                 The jobs run during the GMT offset changes time as intuitively
                 expected.  If a job falls into a time interval that disappears
                 (for example, during the switch from standard time) to daylight
                 saving time or is duplicated (for example, during the reverse
                 switch), then it is handled in one of two ways:
    
                 The first case is for the jobs that run every at hour of a time
                 interval overlapping with the disappearing or duplicated inter?
                 val.  In other words, if the job had run within one hour before
                 the GMT offset change (and cron was not restarted nor the
                 crontab(5) changed after that) or would run after the change at
                 the next hour.  They work as always, skip the skipped time or run
                 in the added time as usual.
    
                 The second case is for the jobs that run less frequently.  They
                 are executed exactly once, they are not skipped nor executed
                 twice (unless cron is restarted or the user's crontab(5) is
                 changed during such a time interval).  If an interval disappears
                 due to the GMT offset change, such jobs are executed at the same
                 absolute point of time as they would be in the old time zone.
                 For example, if exactly one hour disappears, this point would be
                 during the next hour at the first minute that is specified for
                 them in crontab(5).
    
    Bei mir startet Cron auf per Default mit "-s", ohne dass ich das jemals explizit so gesetzt haette. Brauchst dir also keine Sorgen zu machen.
  3. Yamagi

    Yamagi Possessed With Psi Powers Mitarbeiter

    Registriert seit:
    14 April 2004
    Beiträge:
    7.494
    Ort:
    Schleswig-Holstein
    Bezogen auf FreeBSD, aber prinzipiell überall anwendbar: Intern wird die Uhr - wie auf allen unixoiden Systemen - in Sekunden seit "The Epoch" am 1.1.1970 angegeben, ist also linear fortlaufend. Die Realzeit für den Benutzer ergibt sich durch einen Übersetzungmechanismus, mittels in den Kernel geladener Zeitzonendateien. Diese Dateien enthalten Dinge wie Schaltsekunden, Schalttage, fehlende Schalttage und halt auch Sommer- und Winterzeitumstellungen. Jede Nacht wird zwischen 0 Uhr und 6 Uhr in der jeweils ersten und 31ten Minute jeder Stunde adjkerntz(1) ("Adjust Kernel Time Zone") ausgeführt und schaut nach, ob die aktuellen Angaben stimmen. Um 2:01 Uhr wird er also erkennen, dass die falsche Zeitzonendefinition geladen ist, dem Kernel die Neue übergeben und damit die Zeit umstellen. Die Zeitumstellung ist sofort wirksam.
    Cron schaut nun also nach wie spät es ist. Sieht, dass es 2 Uhr ist und tut nichts. Schaut wieder nach, es ist 3:01 Uhr und nichts passiert. Der erste Job läuft also nicht, der zweite Job um 3:15 Uhr schon. Steht auch in der crontab(5), was man aber zugegeben leicht übersieht:
    Code:
        If you are in one of the 70-odd countries that observe Daylight Savings
         Time, jobs scheduled during the rollback or advance will be affected.  In
         general, it is not a good idea to schedule jobs during this period.
    
         For US timezones (except parts of IN, AZ, and HI) the time shift occurs
         at 2AM local time.  For others, the output of the zdump(8) program's ver‐
         bose (-v) option can be used to determine the moment of time shift.
    
    Da gibt es mehrere Auswege. Der einfachste ist auf Vixie zu hören und dort keine Jobs hinzulegen. Eine andere ist "anachron" zu nutzen, was die beiden übersprungenen Jobs dann um 3:02 Uhr nachholen würde. Die Oracle-Methode ist, Standardgremien zu bearbeiten, um Schaltsekunden, Schalttage und Sommer-Winterzeitumstellungen grundsätzlich abzuschaffen.

    EDIT: Nun hat unull mich überholt und rausgefunden, dass sich crontab(5) und cron(8) widersprechen. Im Zweifel würde ich eher ihm Glauben, also vergiss das von mir geschriebene am besten...
  4. bananenBrot

    bananenBrot Member

    Registriert seit:
    3 Juli 2008
    Beiträge:
    420
    Also wird in dem Fall das script gestartet, wenn das System 03:15 Uhr zeigt.
    Sollte für 03:15 Uhr noch ein cron gesetzt worden sein, wird der nicht ausgeführt.

    Ist schon ganz schön nervig diese Sommer/Winterzeitgeschichte

    Aber das hier sagt doch, dass der 02:15 Uhr Job gerade doch läuft.
  5. Yamagi

    Yamagi Possessed With Psi Powers Mitarbeiter

    Registriert seit:
    14 April 2004
    Beiträge:
    7.494
    Ort:
    Schleswig-Holstein
    Es ist zu warm für mein Gehirn :/
  6. unull

    unull Nervensäge

    Registriert seit:
    28 Februar 2005
    Beiträge:
    147
    Ort:
    ::1
    Eventuell wurde hier vergessen, den Bug aus crontab(5) zu tilgen? Die Manpage von cron ist von 2008, die von crontab von 2005.

    Ich habe mal einen Bug-Report zu diesem Widerspruch ausgefuellt und mir auch mal "/usr/src/usr.sbin/cron/cron.c" dazu angesehen:

    Code:
    	if (dst_enabled && last_time != 0 
    	&& TargetTime > last_time /* exclude stepping back */
    	&& tm->tm_gmtoff != lasttm.tm_gmtoff ) {
    
    		diff = tm->tm_gmtoff - lasttm.tm_gmtoff;
    
    		if ( diff > 0 ) { /* ST->DST */
    			/* mark jobs for an earlier run */
    			difflimit = TargetTime + diff;
    			for (u = db->head;  u != NULL;  u = u->next) {
    				for (e = u->crontab;  e != NULL;  e = e->next) {
    					e->flags &= ~NOT_UNTIL;
    					if ( e->lastrun >= TargetTime )
    						e->lastrun = 0;
    					/* not include the ends of hourly ranges */
    					if ( e->lastrun < TargetTime - 3600 )
    						e->flags |= RUN_AT;
    					else
    						e->flags &= ~RUN_AT;
    				}
    			}
    		} else { /* diff < 0 : DST->ST */
    			/* mark jobs for skipping */
    			difflimit = TargetTime - diff;
    			for (u = db->head;  u != NULL;  u = u->next) {
    				for (e = u->crontab;  e != NULL;  e = e->next) {
    					e->flags |= NOT_UNTIL;
    					e->flags &= ~RUN_AT;
    				}
    			}
    		}
    	}
    
    Sieht also tatsaechlich so aus, als ob crontab(5) nicht auf dem aktuellen Stand ist.
  7. Crest

    Crest rm -rf /*

    Registriert seit:
    25 Juni 2008
    Beiträge:
    1.326
    Ort:
    /dev/random
    Ich löse das Problem dadurch meine Rechner in UTC laufen zu lassen und nur für Loginshells der User TZ=$timezone zu setzten.
  8. makenoob

    makenoob Active OpenBSD User

    Registriert seit:
    5 Januar 2007
    Beiträge:
    1.382
    Ort:
    /Germany/Düsseldorf
    das von unull beschriebene verhalten haben wir hier auch. mir fällt spontan aber auch kein cron ein, der das nicht nach dem genannten verhalten behandelt.
  9. unull

    unull Nervensäge

    Registriert seit:
    28 Februar 2005
    Beiträge:
    147
    Ort:
    ::1