Oglądam pliki pod kątem zmian za pomocą zdarzeń inotify (jak to się dzieje, z Pythona, wywołującego libc).
W przypadku niektórych plików podczas a git clone
widzę coś dziwnego: widzę IN_CREATE
zdarzenie i widzę, ls
że plik ma treść, jednak nigdy nie widzę IN_MODIFY
ani IN_CLOSE_WRITE
. Powoduje to problemy, ponieważ chciałbym odpowiedzieć IN_CLOSE_WRITE
na pliki, a konkretnie zainicjować przesyłanie zawartości pliku.
Pliki, które zachowują się dziwnie, znajdują się w .git/objects/pack
katalogu i kończą się na .pack
lub .idx
. Inne pliki, które tworzy git, mają bardziej regularny IN_CREATE
-> IN_MODIFY
-> IN_CLOSE_WRITE
łańcuch (nie szukam IN_OPEN
wydarzeń).
Jest to wewnątrz okna dokowanego w systemie MacOS, ale widziałem dowody tego samego w oknie dokowanym w systemie Linux w zdalnym systemie, więc moje podejrzenie, że aspekt MacOS nie jest istotny. Widzę to, jeśli oglądam i git clone
są w tym samym kontenerze dokera.
Moje pytania:
Dlaczego w tych plikach brakuje tych zdarzeń?
Co można z tym zrobić? W szczególności, jak mogę zareagować na zakończenie zapisu do tych plików? Uwaga: idealnie chciałbym odpowiedzieć, gdy pisanie jest „zakończone”, aby uniknąć niepotrzebnego / (niepoprawnego) przesyłania „niedokończonego” pisania.
Edycja: Czytanie https://developer.ibm.com/tutorials/l-inotify/ wygląda na to, że to, co widzę, jest zgodne z
- oddzielny plik tymczasowy o nazwie podobnej
tmp_pack_hBV4Alz
, tworzony, modyfikowany i zamykany; - trudny związek jest tworzony do tego pliku, o ostatecznej
.pack
nazwie; - pierwotna
tmp_pack_hBV4Alz
nazwa zostanie usunięta.
Wydaje mi się, że mój problem polega na tym, że próbuję użyć inotify jako wyzwalacza do przesyłania plików, a następnie sprowadza się do zauważenia, że .pack
plik jest twardym linkiem do innego pliku, i przesłanie w tym przypadku?
Odpowiedzi:
Aby odpowiedzieć na pytanie osobno dla
git
2.24.1 w Linuksie 4.19.95:Nie widzisz
IN_MODIFY
/IN_CLOSE_WRITE
events, ponieważgit clone
zawsze będzie próbował użyć twardych linków do plików w.git/objects
katalogu. Podczas klonowania przez sieć lub przez granice systemu plików zdarzenia te pojawią się ponownie.Aby złapać modyfikację twardych linków, musisz skonfigurować moduł obsługi
CREATE
zdarzenia inotify , które następuje i śledzi te linki. Pamiętaj, że prostyCREATE
może również oznaczać, że utworzono niepusty plik. Następnie naIN_MODIFY
/IN_CLOSE_WRITE
do dowolnego pliku musisz również wywołać tę samą akcję na wszystkich połączonych plikach. Oczywiście musisz również usunąć tę relację zDELETE
wydarzenia.Prostszym i bardziej niezawodnym podejściem byłoby prawdopodobnie okresowe mieszanie wszystkich plików i sprawdzanie, czy zawartość pliku się zmieniła.
Korekta
Po dokładnym sprawdzeniu
git
kodu źródłowego i uruchomieniugit
z nimstrace
zauważyłem, żegit
używa plików odwzorowanych w pamięci, ale głównie do odczytu zawartości. Zobacz, którego użyciexmmap
jest zawsze wywoływanePROT_READ
tylko z . . Dlatego moja poprzednia odpowiedź poniżej NIE jest poprawną odpowiedzią. Niemniej jednak w celach informacyjnych chciałbym zachować to tutaj:Nie widzisz
IN_MODIFY
zdarzeń, ponieważpackfile.c
używammap
dostępu do plików iinotify
nie zgłasza zmian dlammap
plików ed.Z strony inotify :
źródło
IN_CLOSE_WRITE
, co, jak sądzę, nadal byłoby wywoływane podczas zamykania pliku, który został zapisany przy użyciummap
, ponieważ plik musiałby zostać otwarty w trybie zapisu?mmap
plik jest niepoprawny . Na przykład nadal można zapisywać do zamkniętego deskryptora pliku, gdy plik jest mapowany do pamięci.CLOSE_WRITE_CLOSE
nawet, jeśli usunęclose
imunmap
na końcu. Muszę głębiej zagłębić się w rzeczywistą implementację git.inotifywait
igit clone
(2.24.1) dostajęOPEN
->CLOSE_NOWRITE,CLOSE
dla*.idx
plików. Może zapomniałeś skonfigurować moduł obsługiCLOSE_NOWRITE,CLOSE
? Uwaga: Otrzymasz,*NOWRITE*
ponieważ wszystkie zapisy miały miejsce w zmapowanej pamięci.CLOSE_NOWRITE
: problem polega na tym, że nie widzęIN_CLOSE_WRITE
i chciałbym odpowiedzieć na „zmiany” pliku, aby uruchomić przesyłanie, ale zignoruj „odczyt”. Uwaga, myślę, że obecnie uważam, że ograniczenie mmap + inotify jest trochę czerwone. Wydaje mi się, że problem polega na tym, że pliki.pack
/.idx
są początkowo tworzone jako twarde linki do innego pliku, a zatem wyzwalają tylkoIN_CREATE
(aOPEN
->CLOSE_NOWRITE
dzieje się później, gdy git faktycznie czyta pliki).Mogę spekulować, że Git przez większość czasu używa aktualizacji plików atomowych , które są wykonywane w następujący sposób:
mktemp
-stylową) nazwę.rename(2)
d -d nad oryginalnym; ta operacja gwarantuje, że każdy obserwator próbujący otworzyć plik przy użyciu jego nazwy otrzyma starą lub nową zawartość.Takie aktualizacje są postrzegane
inotify(7)
jakomoved_to
zdarzenia - ponieważ plik „pojawia się ponownie” w katalogu.źródło
IN_MOVED_FROM
iIN_MOVED_TO
wydarzenia. Nie widzę tego jednak w przypadku plików.pack
i.idx
Na podstawie tej zaakceptowanej odpowiedzi zakładam, że mogą istnieć pewne różnice w zdarzeniach w zależności od używanego protokołu (tj. Ssh lub https).
Czy obserwujesz to samo zachowanie podczas monitorowania klonowania z lokalnego systemu plików z
--no-hardlinks
opcją?Twoje zaobserwowane zachowanie podczas uruchamiania eksperymentu zarówno na hoście Linux, jak i Mac prawdopodobnie eliminuje ten otwarty problem, który jest przyczyną https://github.com/docker/for-mac/issues/896, ale dodaje się tylko incase.
źródło
Istnieje inna możliwość (od man inotify):
I chociaż
git clone
może generować duży przepływ zdarzeń, może się to zdarzyć.Jak tego uniknąć:
źródło
Może popełniłeś ten sam błąd, który popełniłem lata temu. Użyłem inotify tylko dwa razy. Za pierwszym razem mój kod po prostu zadziałał. Później nie miałem już tego źródła i zacząłem od nowa, ale tym razem brakowało mi wydarzeń i nie wiedziałem, dlaczego.
Okazuje się, że kiedy czytałem jakieś wydarzenie, naprawdę czytałem małą porcję wydarzeń. Analizowałem ten, którego się spodziewałem, myśląc, że to było to wszystko. W końcu odkryłem, że jest więcej w otrzymywanych danych, a kiedy dodałem mały kod do parsowania wszystkich zdarzeń otrzymanych z jednego odczytu, nie było więcej zdarzeń utraconych.
źródło