Ta rename()funkcja jest równoważna w przypadku zwykłych plików z funkcją zdefiniowaną w standardzie ISO C. Jego włączenie tutaj rozszerza tę definicję o działania na katalogach i określa zachowanie, gdy nowy parametr nazywa plik, który już istnieje. Ta specyfikacja wymaga, aby działanie funkcji było atomowe.
#include <stdio.h>
int rename(const char *old, const char *new);
Opis
Ta renamefunkcja powoduje, że plik, którego nazwa jest ciągiem wskazanym przez, oldjest odtąd znany pod nazwą podaną przez ciąg wskazany przez new. Nazwany plik oldnie jest już dostępny pod tą nazwą. Jeśli plik o nazwie wskazywanej przez ciąg znaków newistnieje przed wywołaniem renamefunkcji, zachowanie jest zdefiniowane w implementacji.
Zwroty
Że renamefunkcja zwraca zero, jeśli operacja się powiedzie, niezerowe, jeśli nie, w takim przypadku, jeśli plik istniał wcześniej wciąż jest znany ze swej pierwotnej nazwy.
Co zaskakujące, zauważ, że nie ma wyraźnego wymogu atomowości. Może być wymagany gdzieś indziej w najnowszym publicznie dostępnym standardzie C, ale nie udało mi się go znaleźć. Jeśli ktoś może znaleźć takie wymaganie, zmiany i komentarze są mile widziane.
Jeśli newpathjuż istnieje, zostanie on zastąpiony atomowo, tak że nie będzie punktu, w którym inny proces próbujący uzyskać dostęp
newpathbędzie go brakować. Jednakże, prawdopodobnie pojawi się okno, w którym zarówno oldpathi newpathodnoszą się do pliku jest zmieniona.
Strona podręcznika systemu Linux twierdzi, że zamiana pliku będzie niepodzielna.
Testowanie i weryfikowanie atomowości może być jednak bardzo trudne, jeśli tak daleko trzeba się posunąć. Nie masz jasności co do tego, co masz na myśli mówiąc „Jak mogę sprawdzić, czy mv jest atomowy”. Czy potrzebujesz wymagań / specyfikacji / dokumentacji, że jest atomowa, czy faktycznie musisz to przetestować ?
Należy również zauważyć, że powyższe zakłada, że nazwy dwóch argumentów operacji znajdują się w tym samym systemie plików. Nie mogę znaleźć żadnego standardowego ograniczenia mvnarzędzia, które by je egzekwowało.
Muszę upewnić się, że ruch jest atomowy. czy testowanie wystarcza, aby to zaakceptować? Nie umiem powiedzieć Tak, pracuję na tym samym fs (ext4 do ext4).
Tizianoreica,
1
POSIX również nie gwarantuje atomowości, ale Linux, podobnie jak większość wariantów unixowych, robi to dla „rodzimych” systemów plików, takich jak ext4.
Gilles „SO- przestań być zły”
1
Biorąc pod uwagę, że ISO C określa zachowanie tylko jednego programu, a nie całego systemu, byłoby dziwne, gdyby mówił o renameatomowości.
Gilles „SO- przestań być zły”
3
Przeczytałem „tę specyfikację” jako odniesienie do poprzedniego zdania („Jej włączenie tutaj ... określa zachowanie, gdy nowy parametr nazywa plik, który już istnieje”), który odnosi się do wcześniejszych części dokumentu POSIX („link o nazwie new powinien pozostają widoczne dla innych wątków w całym ... i odnoszą się do pliku, do którego odnosi się nowy lub stary ... "). Innymi słowy, POSIX obiecuje wdrożyć standard ISO C i daje dodatkowe gwarancje poza tym, co zapewnia ISO C. Czy ta interpretacja pomaga?
SimonJ
1
@Tizianoreica Wiem, że to starożytny post, ale właśnie zobaczyłem twój komentarz i pomyślałem, że powinienem wyjaśnić: Rzeczywisty system plików musi być taki sam, aby nazwa mogła być atomowa. Nie tylko ten sam typ systemu plików. np. jeśli masz /jako ext4 fs i /tmpjako inny ext4 fs, to nie możesz atomowo mv od jednego do drugiego.
Wodin
0
mvopiera się na renamewywołaniu systemowym i rename()jest atomowy. Możesz spojrzeć na stronę podręcznika rename(2).
Oprócz sprawdzania wywołań systemowych i ich atomowości może inotify-toolsmoże służyć jako test, chociaż nie jestem pewien, czy jest to gwarantowany dowód atomowości.
Otwórz 2 pociski. Obejrzyj katalog docelowy przenoszenia w jednym z nich:
inotifywait -m target/
Przenieś plik do katalogu w drugim:
mv foobar target/
inotifywaitPowinien pokazać tylko jedną linię:
target/ MOVED_TO foobar
Wydaje się atomowy w porównaniu do odpowiedzi na ls target/i touch target/a, które generują wiadomości wielowierszowe, takie jak:
# the response to ls target/
target/ OPEN,ISDIR
target/ ACCESS,ISDIR
target/ CLOSE_NOWRITE,CLOSE,ISDIR
PS
Myślę, że przynajmniej pokazuje, że asynchroniczna wieloprocesowa współpraca na plikach jest bezpieczna inotify(praktycznie atomowa): w każdym razie odpowiedziałbyś dopiero po podaniu inotifykońcowego sygnału po operacji. Na przykład konfiguracja producent-konsument może być łatwo i bezpiecznie zaimplementowana inotify.
strace
?unlink
lubrename
przenośny i atomowylink
zawiodą?Odpowiedzi:
Co ciekawe, wydaje się, że odpowiedź może brzmieć: „To zależy”.
Aby być jasnym,
mv
jest określony naSpecyfikacja funkcji zmiany nazwy stanowi:
Ale najnowsza specyfikacja ISO C dla
rename()
stanów:Co zaskakujące, zauważ, że nie ma wyraźnego wymogu atomowości. Może być wymagany gdzieś indziej w najnowszym publicznie dostępnym standardzie C, ale nie udało mi się go znaleźć. Jeśli ktoś może znaleźć takie wymaganie, zmiany i komentarze są mile widziane.
Zobacz także Czy rename () jest atomowy?
Na stronie podręcznika systemu Linux :
Strona podręcznika systemu Linux twierdzi, że zamiana pliku będzie niepodzielna.
Testowanie i weryfikowanie atomowości może być jednak bardzo trudne, jeśli tak daleko trzeba się posunąć. Nie masz jasności co do tego, co masz na myśli mówiąc „Jak mogę sprawdzić, czy mv jest atomowy”. Czy potrzebujesz wymagań / specyfikacji / dokumentacji, że jest atomowa, czy faktycznie musisz to przetestować ?
Należy również zauważyć, że powyższe zakłada, że nazwy dwóch argumentów operacji znajdują się w tym samym systemie plików. Nie mogę znaleźć żadnego standardowego ograniczenia
mv
narzędzia, które by je egzekwowało.źródło
rename
atomowości./
jako ext4 fs i/tmp
jako inny ext4 fs, to nie możesz atomowo mv od jednego do drugiego.mv
opiera się narename
wywołaniu systemowym irename()
jest atomowy. Możesz spojrzeć na stronę podręcznikarename(2)
.Możesz znaleźć odpowiedź na Czy rename () jest atomowy? przy przepełnieniu stosu.
Jakiego rodzaju fs używałeś?
źródło
Oprócz sprawdzania wywołań systemowych i ich atomowości może
inotify-tools
może służyć jako test, chociaż nie jestem pewien, czy jest to gwarantowany dowód atomowości.Otwórz 2 pociski. Obejrzyj katalog docelowy przenoszenia w jednym z nich:
Przenieś plik do katalogu w drugim:
inotifywait
Powinien pokazać tylko jedną linię:Wydaje się atomowy w porównaniu do odpowiedzi na
ls target/
itouch target/a
, które generują wiadomości wielowierszowe, takie jak:PS
Myślę, że przynajmniej pokazuje, że asynchroniczna wieloprocesowa współpraca na plikach jest bezpieczna
inotify
(praktycznie atomowa): w każdym razie odpowiedziałbyś dopiero po podaniuinotify
końcowego sygnału po operacji. Na przykład konfiguracja producent-konsument może być łatwo i bezpiecznie zaimplementowanainotify
.źródło