Što je zadatak jednostavniji, češće griješim

Što je zadatak jednostavniji, češće griješim

Ovaj trivijalni zadatak nastao je jednog petka popodne i trebao je oduzeti 2-3 minute vremena. Generalno, kao i uvek.

Kolega me je zamolio da popravim skriptu na njegovom serveru. Uradio sam to, dao mu je i nehotice ispustio: „Vreme je brzo 5 minuta“. Neka server sam upravlja sinhronizacijom. Prošlo je pola sata, sat, a on je i dalje puhao i tiho psovao.

“Glupo! — pomislio sam, prebacujući se na serversku konzolu — u redu, napraviću pauzu još nekoliko minuta.”

da vidimo ntp, rdate, sdwdate nije instalirano timesyncd onemogućen i ne radi.

# timedatectl
      Local time: Sun 2019-08-25 20:44:39 +03
  Universal time: Sun 2019-08-25 17:44:39 UTC
        RTC time: Sun 2019-08-25 17:39:52
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: no
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

Ovdje ću odmah primijetiti da je hardversko vrijeme ispravno: bit će lakše navigirati dalje.

Tu je počeo niz grešaka.

Prva greška. Samopouzdanje

Klik-klak...

# systemctl enable systemd-timesyncd.service && systemctl start systemd-timesyncd.service && ntpdate 0.ru.pool.ntp.org && timedatectl set-ntp on && timedatectl
25 Aug 21:00:10 ntpdate[28114]: adjust time server 195.210.189.106 offset -249.015251 sec
      Local time: Sun 2019-08-25 21:00:10 +03
  Universal time: Sun 2019-08-25 18:00:10 UTC
        RTC time: Sun 2019-08-25 18:00:10
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

Sve je u redu, vrijeme je sinhronizovano, sistemsko vrijeme odgovara hardverskom. „Uzmi“, rekao sam i vratio se svom poslu.

„Uzeti šta? - ogorčen je kolega. “Isto je vrijeme!”

Što više rješavate tipične probleme, vaše razmišljanje postaje bliještenije i više ne mislite da će stota ili hiljaditi situacija biti drugačija, ali ne ovaj put.

# timedatectl
      Local time: Sun 2019-08-25 21:09:15 +03
  Universal time: Sun 2019-08-25 18:09:15 UTC
        RTC time: Sun 2019-08-25 18:05:04
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: yes
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

Sistemsko vrijeme je opet pogrešno.

Pokušajmo ponovo:

# ntpdate 0.ru.pool.ntp.org && timedatectl && sleep 1 && timedatectl
25 Aug 21:07:37 ntpdate[30350]: step time server 89.175.20.7 offset -249.220828 sec
      Local time: Sun 2019-08-25 21:07:37 +03
  Universal time: Sun 2019-08-25 18:07:37 UTC
        RTC time: Sun 2019-08-25 18:07:37
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a
      Local time: Sun 2019-08-25 21:11:46 +03
  Universal time: Sun 2019-08-25 18:11:46 UTC
        RTC time: Sun 2019-08-25 18:07:37
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: yes
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

Uradimo to drugačije:

# date -s "2019-08-25 21:10:30" && date && sleep 1 && timedatectl
Sun Aug 25 21:10:30 +03 2019
Sun Aug 25 21:10:30 +03 2019
      Local time: Sun 2019-08-25 21:14:36 +03
  Universal time: Sun 2019-08-25 18:14:36 UTC
        RTC time: Sun 2019-08-25 18:10:30
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: yes
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

i ovako:

# hwclock --hctosys && timedatectl && sleep 1 && timedatectl
      Local time: Sun 2019-08-25 21:11:31 +03
  Universal time: Sun 2019-08-25 18:11:31 UTC
        RTC time: Sun 2019-08-25 18:11:31
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a
      Local time: Sun 2019-08-25 21:15:36 +03
  Universal time: Sun 2019-08-25 18:15:36 UTC
        RTC time: Sun 2019-08-25 18:11:32
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: yes
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

Vrijeme se postavlja na djelić sekunde i odmah počinje ponovo da "juri".

Istovremeno, u zapisnicima, u vrijeme takve ručne promjene, vidimo samo sistemske izvještaje da se vrijeme promijenilo, odnosno u pravom/pogrešnom smjeru i povremeno Resincing iz systemd-timesyncd.

Aug 25 21:18:51 wisi systemd[1]: Time has been changed
Aug 25 21:18:51 wisi systemd-timesyncd[29258]: System time changed. Resyncing.
Aug 25 21:18:51 wisi systemd[1187]: Time has been changed
Aug 25 21:18:51 wisi systemd[1]: Time has been changed
Aug 25 21:18:51 wisi systemd[1187]: Time has been changed

ovdje

# ps afx | grep "[1]187"
 1187 ?        Ss     0:02 /lib/systemd/systemd --user

U ovom trenutku je već bilo potrebno tražiti razlog, ali za 18 godina administracije, mozak je nakupio statistiku o greškama „vremena“ i, po navici, opet krivi sinhronizaciju.
Hajde da ga potpuno isključimo.

# timedatectl set-ntp off && systemctl stop systemd-timesyncd.service
# hwclock --hctosys && timedatectl && sleep 1 && timedatectl
      Local time: Sun 2019-08-25 21:25:40 +03
  Universal time: Sun 2019-08-25 18:25:40 UTC
        RTC time: Sun 2019-08-25 18:25:40
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: no
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a
      Local time: Sun 2019-08-25 21:29:31 +03
  Universal time: Sun 2019-08-25 18:29:31 UTC
        RTC time: Sun 2019-08-25 18:25:41
       Time zone: Europe/Minsk (+03, +0300)
     NTP enabled: no
NTP synchronized: no
 RTC in local TZ: no
      DST active: n/a

i u dnevnikima

Aug 25 21:25:40 wisi systemd[1]: Time has been changed
Aug 25 21:25:40 wisi systemd[1187]: Time has been changed
Aug 25 21:29:30 wisi systemd[1]: Time has been changed
Aug 25 21:29:30 wisi systemd[1187]: Time has been changed

Resincing nestao i inače su trupci netaknuti.

Provjeravamo zaključke tcpdump na portu 123 na svim interfejsima. Nema zahtjeva, ali vrijeme i dalje teče.

Greška dva. Rush

Ostalo je još sat vremena do kraja radne nedelje, a ne želim da odem za vikend sa trivijalnim nerešenim problemom (ne obraćajte pažnju na vreme u kodu, članak je pisan narednih dana ).
I evo opet, umjesto da tražim razlog, počeo sam pokušavati da smislim objašnjenje za rezultat. Kažem „izmisliti“ jer bez obzira koliko je logično objašnjenje za rezultat, to je pogrešan pristup rješavanju problema.

Ovaj server je streaming server i pretvara DVB-S2 tok u IP. DVB-S stream sadrži vremenske oznake, tako da ih prijemnici, multiplekseri, skrembleri i televizori često koriste za sinhronizaciju sistemskog sata. Drajveri za DVB-S ploču ugrađeni su u kernel, tako da je najbrži način da osigurate da je DVB-S2 tok uklonjen je da isključite kablove koji dolaze iz „ploča“. Srećom, server je iza zida, neka bude tako.

Naravno, da je u zapisnicima bilo šta bi trebalo biti, to se ne bi dogodilo, ali o tome, opet, na kraju članka.

Pa, pošto smo već uklonili sve satelitske signale, uklonit ćemo i zemaljske - istovremeno izvlačimo sve mrežne kablove. Server postaje odsječen od vanjskog svijeta i radi potpuno autonomno, ali sistemski sat je i dalje u žurbi.

Radna sedmica je gotova, a sam problem datuma/vremena nije kritičan, tako da možete jednostavno ići kući, ali evo ja pravim novu grešku.

Greška tri. Savjetnici

Nikad! Nikada ne postavljajte pitanja na forumima i generalno specijalizovanim (a la stackoverflow) sajtovima ako odgovor na njih zahteva više od proučavanja prve stranice Google-a i čitanja jedne man stranice.

Vratiće te na Google, pročitati istog čovjeka i popularno objasniti pravila foruma/stranice, ali ti neće dati odgovor.

Evo nekih objektivnih faktora:

  • niko osim vas ne može znati problem;
  • niko ne može vršiti testove pod istim uslovima kao i vi

i subjektivno:

  • možda nećete dati sav input za rješavanje problema, jer ste već došli do „pravog“ smjera i predstavljate suštinu problema fokusirajući se na njega;
  • predradnik (moderator, oldtajmer, admin) je uvek u pravu, ako predradnik nije u pravu... pa znate...

Ako ste prilikom odgovaranja na komentare ostali u granicama cenzurisanog rečnika, onda imate jake živce.

odluka

Nema potrebe dijeliti zadatke na jednostavne i složene.

Prestajemo da se oslanjamo na svoje iskustvo, statistiku, savetnike i počinjemo da ne „objašnjavamo” krajnji rezultat, već da dosledno tražimo razlog.

Pošto neko postavlja vreme, mora se desiti odgovarajući sistemski poziv.

Kao što su u softverskoj dokumentaciji najbolji dokumenti izvori, tako je u sistemskoj administraciji najbolji pomoćnik revizija, u našem slučaju revidirano.

Trenutak sumnjeProšao sam kroz manu, ali nisam bio sasvim siguran da se vrijeme u Linuxu može samo podesiti clock_settime и settimeofday, pa sam za prvi test izabrao sve "prikladne" pozive:

# man syscalls | col | grep -F '(2)' | grep -vE '(:|;)' | grep -E '(time|date|clock)' | sed "s/(2).*//" | xargs -I SYSCALL echo "-S SYSCALL " | xargs echo
-S adjtimex -S clock_adjtime -S clock_getres -S clock_gettime -S clock_nanosleep -S clock_settime -S futimesat -S getitimer -S gettimeofday -S mq_timedreceive -S mq_timedsend -S rt_sigtimedwait -S s390_runtime_instr -S setitimer -S settimeofday -S stime -S time -S timer_create -S timer_delete -S timer_getoverrun -S timer_gettime -S timer_settime -S timerfd_create -S timerfd_gettime -S timerfd_settime -S times -S utime -S utimensat -S utimes

i odbacivanje s390_runtime_instr, stime, timerfd_create, koji auditctl nije prepoznao, u početku je pokrenuo reviziju u obliku:

auditctl -a exit,always -S adjtimex -S clock_adjtime -S clock_getres -S clock_nanosleep -S clock_settime -S futimesat -S getitimer -S gettimeofday -S mq_timedreceive -S mq_timedsend -S rt_sigtimedwait -S semtimedop -S setitimer -S settimeofday -S time -S timer_create -S timer_delete -S timer_getoverrun -S timer_gettime -S timer_settime -S timerfd_gettime -S timerfd_settime -S times -S utime -S utimensat -S utimes

Nakon što sam se uvjerio da nema drugih dnevnika na lokacijama dnevnika koje me zanimaju Syscalls Osim ova dva, dalje sam koristio samo njih.

Pokretanje revizije sistemskog poziva clock_settime и settimeofday i pokušajte promijeniti datum:

# auditctl -a exit,always -S clock_settime -S settimeofday && date -s "2019-08-22 12:10:00" && sleep 5 && auditctl -D

Dodano je kašnjenje od pet sekundi kako bi naš "parazit" zajamčeno ispravio vrijeme.

Pogledajmo izvještaj:

# aureport -s -i

Syscall Report
=======================================
# date time syscall pid comm auid event
=======================================
Warning - freq is non-zero and incremental flushing not selected.
1. 08/22/2019 12:10:00 settimeofday 3088 chkcache_proces root 479630
2. 08/26/2019 09:37:06 clock_settime 1538 date root 479629

Ovdje vidimo naše datum i nama nepoznati chkcache_processes. Završilo je u izvještaju iznad jer je aureport sortirao izlaz po datumu prilikom konverzije iz binarnog, a događaj se dogodio u vrijeme koje smo postavili datum -s "2019-08-22 12:10:00".
Ko ga je rodio?

# ausearch -sc settimeofday --comm "chkcache_proces"
----
time->Thu Aug 22 12:10:00 2019
type=PROCTITLE msg=audit(1566465000.000:479630): proctitle="/usr/local/bin/oscam"
type=SYSCALL msg=audit(1566465000.000:479630): arch=c000003e syscall=164 success=yes exit=0 a0=7fde0dfc6e60 a1=0 a2=136cf a3=713ba56 items=0 ppid=3081 pid=3088 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts20 ses=68149 comm="chkcache_proces" exe="/usr/local/bin/oscam" key=(null)

/usr/local/bin/oscam - naš parazit je pronađen. Uprkos njegovom „zlonamernom“ ponašanju, nemoguće je odbiti sistem uslovnog pristupa, ali bih ipak želeo da znam oscam, WTF?

Odgovor se brzo pronalazi u izvorni kodovi:

#if defined(CLOCKFIX)
if (tv.tv_sec > lasttime.tv_sec || (tv.tv_sec == lasttime.tv_sec && tv.tv_usec >= lasttime.tv_usec)) // check for time issues!
{
  lasttime = tv; // register this valid time
}
  else
{
  tv = lasttime;
  settimeofday(&tv, NULL); // set time back to last known valid time
  //fprintf(stderr, "*** WARNING: BAD TIME AFFECTING WHOLE OSCAM ECM HANDLING, SYSTEMTIME SET TO LAST KNOWN VALID TIME **** n");
}

Kako slatko izgleda ovde prokomentarisao linija upozorenje...

izvor: www.habr.com

Dodajte komentar