GNU/Linux >> Znalost Linux >  >> Linux

Chybí události inotify (v adresáři .git)

Mohu spekulovat, že Git většinu času používá atomický aktualizace souborů, které se provádějí takto:

  1. Obsah souboru je načten do paměti (a upraven).
  2. Upravený obsah je zapsán do samostatného souboru (obvykle umístěného ve stejném adresáři jako původní a s náhodným výběrem (mktemp -style) jméno.
  3. Nový soubor je pak rename(2) d -d nad původní; tato operace zaručuje, že každý pozorovatel, který se pokusí otevřít soubor pomocí jeho názvu, získá buď starý obsah, nebo nový.

Takové aktualizace vidí inotify(7) jako moved_to události – protože soubor se „znovu objeví“ v adresáři.


Chcete-li odpovědět na vaši otázku samostatně pro git 2.24.1 v systému Linux 4.19.95:

  • Proč tyto události v těchto souborech chybí?

Nevidíte IN_MODIFY /IN_CLOSE_WRITE události, protože git clone se vždy pokusí použít pevné odkazy pro soubory pod .git/objects adresář. Při klonování přes síť nebo přes hranice systému souborů se tyto události objeví znovu.

  • Co se s tím dá dělat? Jak konkrétně mohu reagovat na dokončení zápisů do těchto souborů? Poznámka:v ideálním případě bych rád odpověděl, když je psaní „dokončeno“, abych se vyhnul zbytečnému/(nesprávnému) nahrávání „nedokončeného“ psaní.

Abyste mohli zachytit modifikaci pevných odkazů, musíte nastavit handler pro inotify CREATE událost, která tyto odkazy sleduje a sleduje. Upozorňujeme, že jednoduchý CREATE může také znamenat, že byl vytvořen prázdný soubor. Poté na IN_MODIFY /IN_CLOSE_WRITE u kteréhokoli ze souborů musíte spustit stejnou akci také u všech propojených souborů. Samozřejmě musíte také odstranit tento vztah na DELETE událost.

Jednodušší a robustnější přístup by pravděpodobně byl pouze periodicky hashovat všechny soubory a kontrolovat, zda se obsah souboru nezměnil.

Oprava

Po kontrole git zdrojový kód a běžící git s strace , zjistil jsem, že git používá soubory mapované v paměti, ale většinou pro čtení obsahu. Viz použití xmmap který se vždy volá s PROT_READ pouze.. Moje předchozí odpověď níže je proto NE správná odpověď. Nicméně pro informační účely bych to zde rád ponechal:

  • Nevidíte IN_MODIFY události, protože packfile.c používá mmap pro přístup k souboru a inotify nehlásí změny pro mmap ed souborů.

    Z manuálové stránky inotify:

    Rozhraní inotify API nehlásí přístupy k souborům a změny, ke kterým může dojít kvůli mmap(2), msync(2) a munmap(2).


Na základě této přijaté odpovědi bych předpokládal, že může existovat nějaký rozdíl v událostech na základě používaného protokolu (tj. ssh nebo https).

Pozorujete stejné chování při monitorování klonování z místního souborového systému pomocí --no-hardlinks možnost?

$ git clone [email protected]:user/repo.git
# set up watcher for new dir
$ git clone --no-hardlinks repo new-repo

Vaše pozorované chování při spuštění experimentu na hostiteli linux i Mac pravděpodobně eliminuje tento otevřený problém, který je příčinou https://github.com/docker/for-mac/issues/896, ale přidává jen zapouzdřit.


Linux
  1. Cheat sheet pro oprávnění k souborům/adresáři pro Linux

  2. Odeberte symbolický odkaz na adresář

  3. Najděte soubor a poté cd do tohoto adresáře v Linuxu

  1. Jediný souborový svazek připojený jako adresář v Dockeru

  2. Bash:Žádný takový soubor nebo adresář?

  3. sys/types.h:Žádný takový soubor nebo adresář

  1. Správce souborů Java

  2. Získejte nejnovější soubor v adresáři v systému Linux

  3. Zachování oprávnění k souboru s Git