Dlaczego pakiet oprogramowania działa dobrze, nawet gdy jest aktualizowany?

29

Załóżmy, że korzystam z oprogramowania, a następnie uruchamiam menedżera pakietów w celu uaktualnienia oprogramowania. Zauważyłem, że Linux nie wyłącza procesu aktualizacji pakietu - nadal działa poprawnie. Jak to robi Linux?

Howard
źródło

Odpowiedzi:

35

Powodem jest to, że Unix nie blokuje pliku wykonywalnego podczas jego wykonywania, a nawet jeśli działa podobnie jak Linux, ta blokada dotyczy i-węzła, a nie nazwy pliku. Oznacza to, że proces utrzymujący go w stanie otwiera dostęp do tych samych (starych) danych, nawet po usunięciu pliku (faktycznie odłączeniu) i zastąpieniu go nowym o tej samej nazwie, co jest zasadniczo tym, co robi aktualizacja pakietu.

To jedna z głównych różnic między Unixem a Windowsem. Ten ostatni nie może zaktualizować zablokowanego pliku, ponieważ brakuje warstwy między nazwami plików i i-węzłami, co utrudnia aktualizację, a nawet instalację niektórych pakietów, ponieważ zwykle wymaga pełnego ponownego uruchomienia.

jlliagre
źródło
10
Aby to wyjaśnić, w systemie Linux nie można modyfikować pliku wykonywalnego podczas jego działania. Możesz jednak odłączyć plik i zastąpić go nowym plikiem o tej samej nazwie.
cjm 30.04.13
W systemie Linux możesz zmodyfikować plik wykonywalny podczas jego działania. Wynik byłby prawdopodobnie nieprzewidywalny, chyba że naprawdę wiesz, co robisz. Dodano punkt „ta sama nazwa”, który nie został wyraźnie określony.
jlliagre 30.04.2013
4
@jlliagre O ile się nie mylę, nie możesz, o ile mi wiadomo: sprunge.us/egiR
Chris Down
2
Jedna fajna rzecz w NFTS - jeśli zmienisz nazwę z wiersza poleceń lub innego programu, możesz umieścić tam plik o tej samej nazwie i nie wpłynie to na programy, które mają otwarty plik oryginalny. (polecenie zmiany nazwy w Eksploratorze nie działa w tym przypadku)
Steffan Donal
1
@cjm Masz rację co do ochrony „zajętości plików tekstowych” pod Linuksem, odpowiedź zaktualizowana. W Solarisie nie ma takich ograniczeń, z którymi jestem bardziej zaznajomiony. Nadal jednak możesz modyfikować biblioteki współdzielone w obu systemach operacyjnych.
jlliagre 30.04.2013
18

Pliki wykonywalne są na ogół otwierane raz, dołączane do deskryptora pliku i nie mają deskryptora pliku do pliku binarnego ponownie otwieranego podczas jednego okresu wykonywania. Na przykład, jeśli wykonasz polecenie bash, exec()generalnie tworzy on tylko deskryptor pliku dla i-węzła wskazywanego przez /bin/bashjednorazowe wywołanie.

Często oznacza to, że w przypadku prostych plików binarnych, które nie podejmują próby ponownego odczytania się podczas wykonywania (przy użyciu ścieżki, którą zostały wywołane), zawartość w pamięci podręcznej pozostaje ważna jako wiszący i-węzeł. Oznacza to, że istnieje zasadniczo replika poprzedniej wersji pliku wykonywalnego.

W bardziej skomplikowanych przypadkach może to powodować problemy. Na przykład plik konfiguracyjny może zostać zaktualizowany, a następnie ponownie odczytany, lub program może się ponownie uruchomić za pomocą ścieżki, z której został wykonany. Mogą również występować problemy, jeśli programy są ze sobą połączone, a jeden jest wykonywany przed aktualizacją, a drugi po (ewentualnie przez pierwszy program). Dotyczy to również niektórych bibliotek.

W przypadku prostych przypadków użycia uaktualnienie jest bezpieczne bez ponownego uruchamiania procesu.

Chris Down
źródło
1
Drugim niebezpieczeństwem, nawet w prostych przypadkach, jest to, że ponieważ działająca aplikacja korzysta z kopii pliku binarnego w pamięci podręcznej, do czasu ręcznego ponownego uruchomienia aplikacji nadal działa stara wersja kodu. Chociaż nie powinno to mieć większego znaczenia; jeśli aktualizacja zawiera poprawki bezpieczeństwa, pomimo instalowania łaty, twój system jest nadal podatny na zagrożenia, ponieważ stara wersja nadal działa.
Dan Neely
1
Obawiam się, że twój pierwszy akapit jest niedokładny. Jądra Unix / Linux nie ładują programów wykonywalnych jednocześnie, ale mapują je. Oznacza to, że tylko faktycznie używane strony trafiają do pamięci RAM. To jest sedno ochrony „zajętości pliku tekstowego” w systemie Linux. Nie ma gwarancji, że część pliku wykonywalnego nie zostanie odczytana długo po uruchomieniu. Co więcej, niektóre strony nigdy nie będą ładowane dla wystarczająco dużych programów, a jest to jeszcze bardziej prawdziwe w przypadku bibliotek ładowanych dynamicznie. Na przykład bashplik binarny ma około 200 stron 4K, nie jestem pewien, czy wszystkie są używane podczas przeciętnej sesji.
jlliagre 30.04.13
@ jlliagre Mówiłem o wejściu ialloc()do struktury jądra podczas odczytu, a nie o mapowaniu pamięci samych stron. Czy nie mam racji, sądząc, że w nowoczesnych systemach plików ext * i-węzeł jest ostatecznie spójny w jądrze (i wewnątrz podsystemu VM)?
Chris Down,
Nie ma żadnej gwarancji, że części pliku wykonywalnego nie będą czytane długo po jego uruchomieniu, a także nie ma gwarancji, że te same strony nie zostaną ponownie odczytane po pewnym czasie w czasie wykonywania.
jlliagre
@jlliagre Racja, ale nie o to mi chodziło. Być może trochę rozdrobniłem moje słowa w odpowiedzi, postaram się wyjaśnić to, co miałem na myśli.
Chris Down