Piszę kilka skryptów powłoki, aby obsłużyć niektóre obrazy dysków, i muszę korzystać z urządzeń pętlowych, aby uzyskać dostęp do niektórych obrazów dysków. Nie jestem jednak pewien, jak prawidłowo przydzielić urządzenie pętlowe bez narażania mojego programu na wyścig.
Wiem, że mogę użyć losetup -f
następnego nieprzydzielonego urządzenia pętli, a następnie przydzielić to urządzenie pętli w następujący sposób:
ld=$(losetup -f)
sudo losetup $ld myfile.img
dostuffwith $ld
Jednak w przypadku, gdy chcę uruchomić wiele instancji programu w tym samym czasie, jest to prawie podręcznikowy przykład warunków wyścigu, co mnie bardzo niepokoi. Gdybym miał uruchomione wiele wystąpień tego programu lub inne programy próbujące również uzyskać urządzenie pętlowe, to każdy proces może nie być w stanie przydzielić urządzenia pętlowego przed następnym wywołaniem losetup -f
, w którym to przypadku oba procesy będą myśleć, że ta sama pętla urządzenie jest dostępne, ale tylko jeden może je zdobyć.
Mógłbym do tego użyć zewnętrznej synchronizacji, ale chciałbym (jeśli to możliwe) uniknąć dodatkowej złożoności. Ponadto inne programy korzystające z urządzeń pętlowych prawdopodobnie nie będą szanować synchronizacji, jaką wymyślę.
Jak mogę uniknąć tego potencjalnego wyścigu? Idealnie chciałbym móc atomowo wykryć i powiązać urządzenie pętli, na przykład za pomocą polecenia:
ld=$(sudo losetup -f myfile.img)
dostuffwith $ld
Jednak gdy to robię, $ld
nie zostaje przypisany do ścieżki urządzenia pętli i przeniesienie się na sudo
zewnątrz, ponieważ w sudo ld=$(losetup -f myfile.img)
daje błędy uprawnień.
źródło
</dev/tty
za?losetup --find --show
wyścigi.for i in {1..100}; do losetup -f -s $i & done
nie dał mi 100 urządzeń z pętlą. Urządzenia pętlowe są na tyle rzadkie, że nie mają znaczenia normalnie; jeśli tak, jedyną opcją jest wykonanie własnych blokad i / lub sprawdzenie, czy poprawne urządzenie pętli zostało utworzone w późniejszym czasie.losetup
może się nie powieść (np. ponieważ zabrakło Ci wpisów w pętli), ale jeśli zgłasza nazwę urządzenia, to urządzenie, które pomyślnie przydzieliło. Czy wcześniejsze wersje zawierały błąd, który spowodował, że wypisała nazwę urządzenia, mimo że alokacja nie powiodła się? Widzę w kodzie źródłowym, że interfejs do alokacji w jądrze istnieje tylko od jądra 3.1. Czy to może być błąd w starszym interfejsie, który wymagalosetup
narzędzia do wyszukiwania?/dev/loop14
i takie, a na końcu może brakować urządzenia. Być może poprawka jest dostępna dzięki uprzejmości/dev/loop-control
, zwykła tylko patrzeć na/proc/partitions
...losetup
używa,/dev/loop-control
jeśli jest obecny, i to nie wygląda na to, że może mieć warunek wyścigu: alokacja odbywa się w jądrze, a drukowanie ścieżki urządzenia jest ostatnią rzeczą, jaką robi narzędzie.Rozgryzłem to. Chociaż nie jestem pewien, na czym polega problem z pozwoleniem, mogę zamiast tego najpierw strzelać i pytać w następujący sposób:
źródło
Możesz użyć
flock
:Chodzi o to, że próbujesz i
flock
plik urządzenia pętli; jeśli pierwsza instancja tego samego skryptu ją zdobędzie, najpierw zadzwonilosetup $ld myfile.img
iflock
zwróci 0. W przypadku skryptu, który przegra wyścig,losetup
nie zostanie wywołany iflock
zwróci 1, co spowoduje powtórzenie pętli.Więcej patrz
man flock
.źródło
Jeśli wszystko, co chcesz zrobić z obrazem jako urządzeniem pętli zwrotnej, to zamontuj go jako system plików i pracuj z zawartością,
mount
polecenie może zająć się tym automatycznie.źródło