• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

FUSE_MKDIR na Linuksie blokuje klienta

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
115 wizyt
pytanie zadane 27 marca 2021 w C i C++ przez overcq Pasjonat (22,150 p.)
edycja 28 marca 2021 przez overcq

Witam

Utworzyłem serwer wirtualnego systemu plików FUSE w Linuksie. Nie używam biblioteki libfuse, lecz w programie obsługuję przysyłane żądania klienta (kernela) do systemu plików, czyli zastępuję to, co robi libfuse, dla mojego systemu plików i komunikuję się bezpośrednio z kernelem. Nie ma prawie żadnej dokumentacji, tylko jakaś szczątkowa, więc często zaglądałem też do źródeł libfuse, która nie jest łatwa do zrozumienia ze względu na obecne w tej bibliotece warstwy abstrakcji.

Jednak teraz napotkałem na problem, którego przyczyny nie potrafię zlokalizować. Mianowicie w żądaniu FUSE_MKDIR (utwórz katalog) cały kod w moim serwerze systemu plików się wykonuje, następnie przechodzi do oczekiwania na kolejne żądanie (w funkcji read), ale klient tego żądania się blokuje w sposób niemożliwy do przerwania bez restartu systemu operacyjnego.

Przykładowo:

  1. Montuję mój system plików FUSE na jakimś katalogu, więc w terminalu uruchamia się serwer systemu plików i wypisuje komunikaty, co robi.
  2. Wydaję z drugiego terminala polecenie mkdir a z podaną odpowienią ścieżką do tego katalogu, w którym zamontowałem serwer, np mkdir /mnt/oth/a.
  3. Serwer wypisuje, że obsłużył żądanie FUSE_MKDIR i czeka na kolejne.
  4. Terminal, w którym wydałem polecenie `mkdir` blokuje się na tym poleceniu.
  5. umount -f z podaną ścieżką do katalogu zakańcza program serwera w sposób normalny (tak jak dla polecenia umount).

Debugowanie metodą logowania wykonywania się linii programu mojego serwera systemu plików FUSE wykazało, że mkdir blokuje się tylko wtedy, gdy odsyłam do klienta odpowiedź, jak w liniach następujących od: https://github.com/overcq/oux/blob/bb43e07448df89ded21adbd3b9d9a708ac3340bf/program/filesystem/mount/0.cx#L1934. Natomiast, jeśli zamiast odsyłania tej odpowiedzi do klienta odeślę komunikat błędu (tylko strukturę out_buf), to katalog zostanie utworzony poprawnie, mkdir zwróci komunikat błędu, ale się nie zablokuje.

Testowałem również, czy nie wysyłam zbyt mało danych i klient nie blokuje się na oczekiwaniu na dane, ale jeśli zwracam za dużo danych, to writev wraca z błędem wskazującym, że nieprawidłowy argument.

Czekam na każdą pomoc, jednak jeśli zamierzasz pobrać https://github.com/overcq/oux, skompilować i uruchomić polecenia mkfs i mount tego serwera plików FUSE, to nie rób tego na maszynie, której nie będziesz mógł zrestartować.

Do uruchomienia tego serwera plików FUSE potrzeba:

  1. Pobrać środowisko z https://github.com/overcq/oux.
  2. Przejść do katalogu program/filesystem/mkfs i wykonać polecenie make. (Pierwsza kompilacja musi zbudować bazę danych plików nagłówkowych z dokumentacji dostępnej w systemie, więc potrwa kilka minut.)
  3. Przejść do katalogu program/filesystem/mount i wykonać polecenie make.
  4. Przejść do katalogu program/filesystem i utworzyć plik dysku poleceniem dd if=/dev/zero of=dysk bs=4096 count=500.
  5. Utworzyć urządzenie blokowe z tego pliku dysku poleceniem losetup -f disk i sprawdzić wynik poleceniem losetup.
  6. Wykonać polecenie mkfs/a.out /dev/loop z odczytanym wyżej numerem loop, by utworzyć system plików na tym dysku.
  7. Wykonać polecenie mkdir mnt, by utworzyć punkt montowania, a następnie mount/a.out /dev/loop mnt z odczytanym wyżej numerem loop, by zamontować system plików.
  8. W drugim terminalu przejść do katalogu program/filesystem/mnt i można wylistować zawartość dysku poleceniem ls -al.
  9. Wydać polecenie mkdir a, by spróbować utworzyć katalog w systemie plików. Wtedy ten drugi terminal się zablokuje, jak również zablokowane do restartu systemu będzie użyte urządzenie /dev/loop z określonym numerem oraz katalog mnt.
  10. W trzecim terminalu przejść do katalogu program/filesystem i wydać polecenie umount -f mnt, które powinno zakończyć program serwera plików FUSE w pierwszym terminalu.

Po aktualizacji kernela Linuksa z wersji 5.11.2 na 5.11.9 problem zniknął.

komentarz 27 marca 2021 przez Oscar Nałogowiec (29,340 p.)

Nie robiłem nic z FUSE (aczkolwiek chyba spróbuje), więc na początek kilka ogólnych uwag;

  1. To że utworzył się katalog o niczym nie świadczy, to robi serwer.
  2. Jeśli wisi klient to pewnie jeszcze czeka na jakieś dane. Jak wyślesz komuniklat o błędzie to on kończy procedurę, natomiast w przypadku sukcesu pewnie chce więcej.
  3. writev raczej nie wie ile danych potrzebuje klient, po prostu sygnalizuje, że ma coś źle w parametrach.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

–1 głos
1 odpowiedź 463 wizyt
pytanie zadane 18 grudnia 2015 w Nasze projekty przez Mavimix Dyskutant (8,420 p.)
0 głosów
1 odpowiedź 272 wizyt
0 głosów
0 odpowiedzi 527 wizyt

93,086 zapytań

142,044 odpowiedzi

321,467 komentarzy

62,434 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...