LINUX.ORG.RU

Стандартная проблема с mount/umount «device or recourse is busy»


0

1

Всем привет!

Есть одна проблемка, думаю, для неё должно быть стандартное решение. Сразу упомяну - речь идёт о встроенной системе, где максимум, что есть - busybox. Так вот задачка в двух словах: есть устройство с SD-слотом, когда карточка вставлена, надо её примонтировать и сказать другой программе, что карта есть и можно на неё писать, ну и когда карту вытащили, надо соответственно её отмонтировать и сказать другой программе, что карты собсна нету.
Контролирую, что карта вставлена, по появлению /sys/block/mmcblk0. Когда директория, появляется монтирую с:
mount( /dev/mmcblk0p1, /mnt/SD, «vfat», MS_SYNCHRONOUS, NULL);

Когда системная директория пропадает, то отмонтирую с:
umount2( /mnt/SD, MNT_FORCE );

Всё работает хорошо, пока карта не вытаскивается во время записи другой программой. В этом случае карту невозможно отмонтировать. Максимум, что нашёл в гугле это то, что в таком случае надо «убить» программу с открытым доступом к карте, а после этого отмонтировать. Неужели нет другого решения?

Спасибо
velik


Ответ на: комментарий от anon_666

>Подскажите пожалуйста, по завершении таймаута write вернёт ошибку, ноль или как? Просто проверить сейчас не могу.
По идее (смю man) должен вернуть количество записанных байт, которое != тому, что мы хотели записать. Возможно и 0.
Я, кстати, для своего приложения выбрал fwrite_unlocked()

Да, и ещё. Kernel panic выдавал мне ещё тучу всякой инфы. В инфе проскакивало несколько ссылок на ошибки в dma. Я отключил поддержку DMA при записи на SD в своём 2.6.30 ядре. Пока эксперименты с выдёргиванием карточки не ведут к полному обвалу системы. Этакая врЕменная заплата.

velikS
() автор топика
Ответ на: комментарий от Alan_Steel

> Текущий kernel panic связан с багом в ядре, не в приложении (-ях).
kernel panic всегда связан с багом в ядре =) согласен, да

Все прочие предложения типа «пусть нам драйвер скажет, куда мы пишем и мы сами будем решать, что делать» не выдерживают никакой критики.

Я с этим даже не спорю, понятно что программе должно быть до лампочки причина неудачного write, мне просто показалось что вы утверждаете что обрабатывать ошибку в этом случае вообще не нужно.

Nao ★★★★★
()
Ответ на: комментарий от Nao

Я в дискуссии с момента, когда начали обсуждать недоступность корня в силу «железных» проблем (вытащить хард итп)

Так вот: если недоступен /, приложению лучше тихо сдохнуть и не доставать пользователя воплями и том, что его файл не может быть сохранён. Обрабатывать тут нечего и незачем.

Это моё ИМХО, конечно.

Alan_Steel ★★
()
Ответ на: комментарий от Viglim
Почему же? Попробуй при записи чего-нибудь на жёсткий диск вытащить его. Получишь то же самое.

Ты не поверишь, но я пробовал - http://www.linux.org.ru/jump-message.jsp?msgid=3944366&cid=3944929 =).

И что, будешь говорить, драйвер виноват?

Если ядро валится без серьёзной причины, то да, это бага в драйвере (или в самом «ядре ядра»). Без вариантов.

Deleted
()
Ответ на: комментарий от anon_666

Ещё раз: «при записи чего-нибудь на жёсткий диск вытащить его».

Уж не думаешь ли ты, что ситуация «был диск, работал, а тут ВНЕЗАПНО его нету и записать на него ничего нельзя» описывает исправное железо?

hint: ВНЕЗАПНО = without umout-ing

Viglim
()
Ответ на: комментарий от Viglim

Вполне исправное железо, диск то может быть подключен очень далеко через кучу промежуточных железяк. И kernel panic тут не нужен. Ошибка записи. И пусть приложение само думает, что делать, если не выполнился write().

mky ★★★★★
()
Ответ на: комментарий от Viglim

>был диск, работал, а тут ВНЕЗАПНО его нету и записать на него ничего нельзя" описывает исправное железо?

Да, в случае, как у ТС.

anon_666
()
Ответ на: комментарий от Deleted

>Ты не поверишь, но я пробовал

Мой прошлый опыт говорит, что выдёргивание винта с rootfs --- фигня, а проблемма в том, что на этом же винте обычно лежит swap.

mky ★★★★★
()
Ответ на: комментарий от Viglim

>ВНЕЗАПНО = without umout-ing

Ну это на фряхе 7.x без отмонтирования паник, а у нас linux.

anon_666
()
Ответ на: комментарий от Viglim

Ключевая фраза «при записи чего-нибудь».

А теперь ещё раз пройди по ссылке и прочитай внимательно мои посты.

Deleted
()
Ответ на: комментарий от Alan_Steel

> если недоступен /, приложению лучше тихо сдохнуть
А почему именно / ? Приложение писало куда-то (неважно на корень или нет, программе вообще незачем знать на какой девайс физически) и это куда-то исчезло. Корень мог остаться работоспособным, а запись велась на какой-нибудь /media/flash.

И вообще, из сообщений ТС, я не понял что флешка это /. Разве он где-то такое говорил?

Nao ★★★★★
()
Ответ на: комментарий от Nao

>И вообще, из сообщений ТС, я не понял что флешка это /. Разве он где-то такое говорил?

Если вы под «Он» имеете в виду меня, то я такого не говорил. У меня SD карточка - обычное устройство. Карточку воткнули, одна программа её опознала, примонтировала и сообщила другой. Та, другая, копирует накопленные в приборе данные на карточку. Карточку выдернули, первая программа её отмонтировала. Вот и всё (в этом месте).

Кстати, я вчера экспериментировал. С отключённым DMA всё работает стабильно. Проблема и верно в драйвере. Будем ждать 2.6.36 - мож там поправят.

velikS
() автор топика
Ответ на: комментарий от velikS

Карточку выдернули, первая программа её отмонтировала.

На всякий случай ещё раз повторюсь: отмонтировать нужно до выдёргивания карточки. Иначе есть риск потерять данные из-за того, что они «осели» в каком-либо кеше, который не успел сброситься на карточку. Т.е. отмонтировать надо сразу после того, как вторая программа запишет на неё все необходимые данные. В венде та же логика, и это не зависит от ОС.

Проблема и верно в драйвере. Будем ждать 2.6.36 - мож там поправят.

Лучше всё-таки написать багрепорт.

Deleted
()
Ответ на: комментарий от velikS

Кто?

Тут уже писали и не раз, что отмонтировать нужно перед выдёргиванием, а ты это делаешь после и удивляешся, что у тебя проблемы в связи с этим возникают.

Viglim
()
Ответ на: комментарий от Viglim

>Тут уже писали и не раз, что отмонтировать нужно перед выдёргиванием, а ты это делаешь после и удивляешся, что у тебя проблемы в связи с этим возникают.

Вы попробуйте врачам упомянуть, что выдёргивание карточки может привести к обвалу системы, поэтому её трогать низя. И посмотрите на реакцию ;-)

Лучше всё-таки написать багрепорт.

Не, я лучше подожду )

У меня тут сейчас другая проблемка. Довыдёргивался я эту карточку. Теперь, похоже, на ней не всё в порядке. НО! карточку вставляю, монтирую без проблем. Начинаю писать, fwrite() возвращает, что записалось ровно столько байт, сколько я хотел, а на экране туча сообщений, что
FAT: Filesystem panic (dev mmcblk0p1)
cluster badly computed (1104 != 1102)

и в каждом сообщении другие номера кластеров. Причём, что интересно, что по mount вижу, что устройство стало ro, но не пойму, почему fwrite() не возвращает ошибки.

velikS
() автор топика
Ответ на: комментарий от velikS

Вы попробуйте врачам упомянуть, что выдёргивание карточки может привести к обвалу системы, поэтому её трогать низя. И посмотрите на реакцию ;-)

Я сейчас не про обвал системы, а про механизмы кеширования. Смысл в том, что вызов close на дескрипторе записываемого файла не гарантирует, что он будет записан на физическое устройство. По этому, перед тем как разрешить пользователю выдёргивать карточку, нужно её отмонтировать. Ясно?

Deleted
()
Ответ на: комментарий от Viglim

>Так прогони fsck-ом. К этому и может приводить выдёргивание без отмонтирования.

Это - встроенная система с ограниченными ресурсами. Тут таких люксусов не предполагается. Надо корректно опознавать ошибку и сообщить пользователю о проблеме. Дальше - не наше дело.


Я сейчас не про обвал системы, а про механизмы кеширования. Смысл в том, что вызов close на дескрипторе записываемого файла не гарантирует, что он будет записан на физическое устройство. По этому, перед тем как разрешить пользователю выдёргивать карточку, нужно её отмонтировать. Ясно?


Нет, но это - само собой. После записи пропущу sync() и отмонтирую, примонтирую заново карту, чтоб сбросить все кэши. Но выдёргивать пользователь будет всё равно примонтированную карточку. Если он выдернет её после записи, что ничего страшного не жду, т.к. кэши уже там. Но никто не может исключить, что он выдернет карту во время записи. Вот тут пока грабли на стороне кернела. Я лучше подожду новый релиз для моей системы - время ещё есть.

Тут у меня новый вопрос появился, может, кто знает в какую сторону копать - как определить, что на SD-карте взведена защита от записи?

velikS
() автор топика
Ответ на: комментарий от velikS

> как определить, что на SD-карте взведена защита от записи?
ты про перемонтировку фс в режим только для чтения или про какую-то хардварную защиту?

Кстати, чтобы повысить надёжность может быть монтировать фс с sync ?

Nao ★★★★★
()
Ответ на: комментарий от velikS

И вообще, есть возможность использовать другую фс? А то fat в таком случае может быть не лучшим выбором...

Nao ★★★★★
()
Ответ на: комментарий от Nao

Привет!

ты про перемонтировку фс в режим только для чтения или про какую-то хардварную защиту?

Я вообще-то про этот «ключик» на самой карте, который можно переставить в положение «Lock». Кстати, сейчас пробовал перевести карту в этот Lock. Карта монтируется без проблем как rw, и я без проблем пишу на неё. По-моему это не здОрово. Этот Lock в Линуксе, похоже, просто игнорируется.


Кстати, чтобы повысить надёжность может быть монтировать фс с sync ?

Именно так и делаю. Вот кусок кода из программы, которая монтирует/демонтирует карту

if( mount( SD_NODE, SD_MOUNT_PATH, «vfat», MS_SYNCHRONOUS,
NULL) != 0 )
{
u8OkMounted = D_FALSE;
SD_LOG( syslog( LOG_DEBUG, «Control-SW: SD-card
inserted, but mount() problem. ErCode=%d», errno ) );
}
else
{
u8OkMounted = D_TRUE;
}


if( umount2( SD_MOUNT_PATH, MNT_DETACH ) != 0)
{
SD_LOG( syslog( LOG_DEBUG, «Control-SW: SD-card
rejected, but umount() problem. ErCode=%d», errno) );
}


Ну и пара строк записи на карту из другой (пока тестовой) програмы:

fp2 = open( «/mnt/SD/test», O_CREAT | O_SYNC | O_WRONLY | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH );

..............

Result = write( fp2, aBytes, uiWriteQuant );
if( Result != uiWriteQuant )
{
syslog( LOG_DEBUG, «Test-write: write problem» );
printf( «Write Problem. Stop copy. Write=%d \n», Result );
printf( «errno=%d \n», errno );

close( fp1 );
close( fp2 );
return 1;
}

velikS
() автор топика
Ответ на: комментарий от Nao

>И вообще, есть возможность использовать другую фс? А то fat в таком случае может быть не лучшим выбором...

Не, другую нельзя. Мы переписываем кое-какую статистику, которую потом надо послать по почте, сохранить и т.д. Соответственно, карта должна быть читаема как у нас, так и на Windows. В прибор могут вставить карту FAT, а возможно и с NFTS. Но с NTFS я пока не заморачиваюсь.

velikS
() автор топика
Ответ на: комментарий от velikS

> Не, другую нельзя. Мы переписываем кое-какую статистику, которую потом надо послать по почте, сохранить и т.д.

Просто выдёргивание карты без отмонтирования чревато повреждением файловой системы. Конечно может sync поможет...

Nao ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.