Co Linux robi inaczej, co pozwala mi usuwać / zastępować pliki, w przypadku których system Windows narzekałby, że plik jest obecnie używany?

29

Przykładem jest Minecraft. Podczas uruchamiania Bukkit w systemie Linux mogę usunąć lub zaktualizować pliki .jar w folderze / plugins i po prostu uruchomić polecenie „przeładuj”.

W systemie Windows muszę wyłączyć cały proces serwera, ponieważ narzeka on, że plik .jar jest aktualnie używany, gdy próbuję go usunąć lub zastąpić.

To jest dla mnie niesamowite, ale dlaczego tak się dzieje? Co Linux robi tutaj inaczej?

MetaGuru
źródło

Odpowiedzi:

34

Linux usuwa plik zupełnie inaczej niż system Windows. Po pierwsze, krótkie wyjaśnienie dotyczące sposobu zarządzania plikami w rodzimych systemach plików * unix.

Plik jest przechowywany na dysku w wielopoziomowej strukturze o nazwie i-node. Każdy i-węzeł ma unikalny numer w jednym systemie plików. Struktura i-węzła przechowuje różne informacje o pliku, takie jak jego rozmiar, bloki danych przydzielone do pliku itp., Ale dla tej odpowiedzi najważniejszym elementem danych jest link counter. Są directoriesto pliki, które przechowują zapisy dotyczące plików. Każdy rekord ma numer i-węzła, do którego się odnosi, długość nazwy pliku i samą nazwę pliku. Ten schemat pozwala mieć „wskaźniki”, tj. „Linki” do tego samego pliku w różnych miejscach o różnych nazwach. Licznik łączy i-węzła faktycznie zachowuje liczbę łączy, które odnoszą się do tego i-węzła.

Co się stanie, gdy jakiś proces otworzy plik? Najpierw open()funkcja szuka rekordu pliku. Następnie sprawdza, czy struktura i-węzła w pamięci dla tego i-węzła już istnieje. Może się tak zdarzyć, jeśli jakiś program już otworzył ten plik. W przeciwnym razie system zainicjuje nową strukturę i-węzłów w pamięci. Następnie system zwiększa licznik otwartych struktur i-węzłów w pamięci i zwraca do aplikacji deskryptor pliku.

Wywoływane jest wywołanie biblioteki Linux w celu usunięcia pliku unlink. Ta funkcja usuwa rekord pliku z katalogu i zmniejsza licznik łączy i-węzła. Jeśli system wykryje, że istnieje struktura i-węzła w pamięci, a jej otwarty licznik nie jest równy zero, wówczas to wywołanie zwraca sterowanie do aplikacji. W przeciwnym razie sprawdza, czy licznik łączy stał się zerowy, a jeśli tak, to system zwalnia wszystkie bloki przydzielone dla i-węzła i samego i-węzła i wraca do aplikacji.

Co się dzieje, że aplikacja zamyka plik? Funkcja close()zmniejsza otwarty licznik i sprawdza jego wartość. Jeśli wartość jest niezerowa, funkcja wraca do aplikacji. W przeciwnym razie sprawdza, czy licznik łączy i-węzła wynosi zero. Jeśli wynosi zero, zwalnia wszystkie bloki pliku i i-node przed powrotem do aplikacji.

Ten mechanizm pozwala „usunąć” plik podczas jego otwierania. Jednocześnie aplikacja, która otworzyła plik, nadal ma dostęp do danych w tym pliku. Tak więc JRE w twoim przykładzie nadal utrzymuje otwartą wersję pliku, podczas gdy na dysku jest inna, zaktualizowana wersja.

Co więcej, ta funkcja umożliwia aktualizację glibc (libc) - podstawowej biblioteki wszystkich aplikacji - w systemie bez przerywania jego normalnej pracy.

Windows

20 lat temu pod DOSem nie znaliśmy żadnego innego systemu plików niż FAT. Ten system plików ma inną strukturę i zasady zarządzania. Te zasady nie pozwalają na usunięcie pliku, gdy jest on otwarty, więc DOS i ostatnio Windows muszą odrzucić wszelkie żądania usunięcia pliku, który jest otwarty. Prawdopodobnie NTFS pozwoliłby na takie samo zachowanie jak w systemach plików * nix, ale Microsoft zdecydował się utrzymać nawykowe usuwanie plików.

Oto odpowiedź. Nie krótko, ale teraz masz pomysł.

Edycja : Dobra lektura na temat źródeł Win32bałaganu: https://blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993 Kredyty dla @Jon

Serge
źródło
1
Próbowałem zmienić nazwę pliku wtyczki podczas działania serwera: i.imgur.com/xibyF.png
MetaGuru,
otwórz okno cmd, przejdź do tego katalogu i użyj ren MonsterB.jar MonsterB.ja_- powinno działać. Zdecydowanie działa na pliki dll i exe.
Serge
1
nie, Windows mapuje fragmenty pliku wykonywalnego do pamięci
Serge
9
NTFS rzeczywiście czyni ją wspierać, ale C Library fopenrozmowy poleceń CreateFilez FILE_SHARE_DELETEflagą, więc uniemożliwia to dla większości programów otwierane pliki.
Random832
2
Obowiązkowy link Raymond Chen: blogs.msdn.microsoft.com/oldnewthing/20040607-00/?p=38993
Jon