Tutaj napisano, że możesz przepisać plik wykonywalny, a proces będzie działał dobrze - zostanie ponownie odczytany po ponownym uruchomieniu procesu.
Jednak gdy próbuję zastąpić plik binarny podczas procesu (za pomocą scp, od dewelopera do serwera testowego), mówi „plik zajęty”. A jeśli zastąpię plik biblioteki współdzielonej (* .so), wszystkie procesy, które go łączą, ulegają awarii.
Dlaczego tak? Czy coś brakuje? Jak mogę zamienić pliki binarne bez zatrzymywania / zawieszania procesu?
.so
plik za pomocą,ldd filename.so
aby sprawdzić zależnościstop app && create symlink of .so && start app
Odpowiedzi:
Jak wspomniano w Dlaczego pakiet oprogramowania działa dobrze, nawet gdy jest aktualizowany? , blokada jest umieszczona na i-węźle, a nie na nazwie pliku. Po załadowaniu i uruchomieniu pliku binarnego plik jest oznaczony jako zajęty - dlatego podczas próby zapisania pojawia się błąd ETXTBSY (plik zajęty).
Teraz w przypadku bibliotek współdzielonych jest nieco inaczej: biblioteki mapują pamięć do przestrzeni adresowej procesu za pomocą
mmap()
. ChociażMAP_DENYWRITE
może być określony, przynajmniej Glibc w systemie Linux dyskretnie go ignoruje (zgodnie ze stroną podręcznika, sprawdź źródła) - sprawdź ten wątek . W związku z tym możesz zapisać plik, a ponieważ jest on zamapowany w pamięci, wszelkie zmiany są widoczne niemal natychmiast - co oznacza, że jeśli spróbujesz wystarczająco mocno, możesz udaremnić swój komputer, nadpisując bibliotekę.Dlatego poprawnym sposobem aktualizacji jest:
usunięcie pliku, który usuwa odniesienie do danych z systemu plików, dzięki czemu nie jest dostępny dla żadnych nowo powstałych aplikacji, które mogą chcieć z niego korzystać, jednocześnie zachowując dostęp do danych dla każdego, kto już go otworzył (lub zmapował) ;
tworzenie nowego pliku ze zaktualizowaną zawartością.
Nowo utworzone procesy będą korzystać ze zaktualizowanej zawartości, uruchomione aplikacje będą miały dostęp do starej wersji. Tak właśnie działa każde rozsądne narzędzie do zarządzania pakietami. Pamiętaj jednak, że nie jest to całkowicie pozbawione niebezpieczeństwa - na przykład aplikacje dynamicznie ładujące kod (używające
dlsym()
i znajomych) będą miały problemy, jeśli API biblioteki zmieni się po cichu.Jeśli chcesz być po naprawdę, naprawdę bezpiecznej stronie, zamknij system, zamontuj system plików z innej instancji systemu operacyjnego, zaktualizuj i ponownie uruchom zaktualizowany system.
źródło
Aktualizacja rpm robi to samo - z uruchomionymi plikami binarnymi i bibliotekami, gdy nic się nie zawiesza.
Jaka jest różnica:
NIE spowoduje to zastąpienia pliku w miejscu: i-węzeł odnoszący się do pliku binarnego w użyciu jest nadal „zajęty”, dopóki ostatni obiekt trzymający go nie otworzy się. Nowy plik zostanie utworzony z nowym numerem i-węzła.
Teraz
scp
lubcp
spróbuje zastąpić plik w miejscu - co zmieniłoby treść, do której odnosi się i-węzeł. To nie działa - jak opisano.źródło