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

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

Ovaj trivijalni zadatak nastao je jednog petka poslijepodne i trebao je oduzeti 2-3 minute vremena. Općenito, kao i uvijek.

Kolega me zamolio da popravim skriptu na njegovom serveru. Učinio sam to, pružio mu ga i nenamjerno ispustio: "Vrijeme je 5 minuta brzo." Neka poslužitelj sam upravlja sinkronizacijom. Prošlo je pola sata, sat, a on i dalje puhne i tiho psuje.

“Glupače! — pomislio sam, prebacujući se na serversku konzolu — u redu, napravit ć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 točno: bit će lakše kretati se dalje.

Tu je počela serija 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 sinkronizirano, sistemsko vrijeme odgovara hardverskom. “Uzmi”, rekao sam i vratio se svom poslu.

“Uzeti što? - ogorčen je kolega. "Isto je vrijeme!"

Što više rješavate tipične probleme, to vam razmišljanje postaje zamršenije i više ne mislite da će stota ili tisućita 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 opet je 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

Učinimo 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 je postavljeno na djelić sekunde i odmah ponovno počinje "juriti".

Istodobno, u zapisima, u vrijeme takve ručne promjene, vidimo samo izvješća sustava da se vrijeme promijenilo, odnosno, u pravom/pogrešnom smjeru i povremeno Ponovna sinkronizacija 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

здесь

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

U ovom trenutku već je bilo potrebno tražiti razlog, ali tijekom 18 godina administracije, mozak je nakupio statistiku o "vremenskim" pogreškama i, iz navike, opet krivi sinkronizaciju.
Isključimo ga potpuno.

# 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 kladama

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

Ponovna sinkronizacija nestao i inače su cjepanice netaknute.

Provjera zaključaka tcpdump na portu 123 na svim sučeljima. Zahtjeva nema, ali vrijeme bježi.

Greška dva. Žuriti

Ostalo je sat vremena do kraja radnog tjedna, a ja ne želim otići za vikend s trivijalnim neriješenim problemom (ne obraćajte pažnju na vrijeme u kodu, članak je napisan sljedećih dana ).
I ovdje sam opet, umjesto da tražim razlog, počeo pokušavati smisliti objašnjenje za rezultat. Kažem "izmisliti" jer koliko god objašnjenje rezultata bilo logično, to je pogrešan pristup rješavanju problema.

Ovaj poslužitelj je streaming poslužitelj i pretvara DVB-S2 stream u IP. DVB-S stream sadrži vremenske oznake, pa ih prijamnici, multiplekseri, kodirani uređaji i televizori često koriste za sinkronizaciju sata sustava. Upravljački programi za DVB-S ploču ugrađeni su u kernel, tako da je najbrži način da se osigura uklanjanje DVB-S2 streama isključivanje kabela koji dolaze iz "ploča". Srećom, server je iza zida, pa neka bude tako.

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

Pa kad smo već uklonili sve satelitske signale, uklonit ćemo i zemaljske - ujedno izvlačimo sve mrežne kabele. Poslužitelj postaje odsječen od vanjskog svijeta i radi potpuno autonomno, ali sistemski sat i dalje žuri.

Radni tjedan je završio, a sam problem datuma/vremena nije kritičan, tako da možete jednostavno otići kući, ali ovdje radim novu grešku.

Pogreška tri. savjetnici

Nikada! Nikada ne postavljajte pitanja na forumima i općenito specijaliziranim (a la stackoverflow) stranicama ako odgovor na njih zahtijeva više od proučavanja prve stranice Googlea i čitanja jedne stranice priručnika.

Vratit će vas na Google, pročitati isti čovjek i popularno objasniti pravila foruma/stranice, ali vam neće dati odgovor.

Evo nekoliko objektivnih čimbenika:

  • nitko osim vas ne može znati problem;
  • nitko ne može provoditi testove pod istim uvjetima kao vaši

i subjektivno:

  • možda nećete dati sve inpute za rješavanje problema, jer ste već došli do "pravog" smjera i predstavljate bit problema fokusirajući se na njega;
  • predradnik (moderator, oldtimer, admin) je uvijek u pravu, ako je predradnik u krivu... pa znaš...

Ako ste, odgovarajući na komentare, ostali u granicama cenzuriranog rječnika, onda imate jake živce.

odluka

Nema potrebe dijeliti zadatke na jednostavne i složene.

Prestajemo se oslanjati na svoje iskustvo, statistiku, savjetnike i počinjemo ne “objašnjavati” krajnji rezultat, već dosljedno tražiti razlog.

Budući da netko postavlja vrijeme, mora se dogoditi odgovarajući sistemski poziv.

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

Trenutak sumnjeProšao sam kroz manu, ali nisam bio posve siguran da se vrijeme u Linuxu može samo postaviti clock_settime и settimeofday, pa sam za prvi test odabrao 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, prvo 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 zapisa na lokacijama zapisa koje me zanimaju sistemski pozivi Osim ova dva, samo sam njih koristio dalje.

Pokretanje revizije poziva sustava 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

Dodaje se odgoda od pet sekundi kako bi naš "parazit" zajamčeno ispravio vrijeme.

Pogledajmo izvješće:

# 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 podaci a nama nepoznata chkcache_processes. Završio je u gornjem izvješću jer je aureport razvrstao izlaz po datumu prilikom pretvaranja iz binarnog, a događaj se dogodio u vrijeme koje smo postavili datum -s "2019-08-22 12:10:00".
Tko 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. Unatoč njegovom "zlonamjernom" ponašanju, nemoguće je odbiti sustav uvjetnog pristupa, ali ipak bih želio znati oscam, što?

Odgovor se brzo nalazi 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 ovdje komentirao crta upozorenje...

Izvor: www.habr.com

Dodajte komentar