psilogic: (wpriz)
psilogic ([personal profile] psilogic) wrote2015-08-17 08:36 pm

Послание линуксоидам

А вот просветите прожженного вындузоида насчет одной вещи.

Есть ли в линухе хоть какой-нибудь ресурс, который саморазлочивается при грубом убийстве программы? Хочется сделать защиту от одновременного запуска двух instance. Перепробовал уже open(O_EXCL), flock, lockf, shm_open(O_EXCL), sem_open(O_EXCL), sem_trywait - всё либо жидко срёт на локи, либо виснет (lockf(...F_TEST...)), так как, видите ли, файловая система недоразвитая (nfs), либо в случае убиения через kill -9 оставляет ресурс в состоянии, неотличимом от залоченного.

Щито делать? Неужели уних в этом отношении дохлее выньды?

З.Ы. Есть, конечно, сокеты, но это значит юзать "магический номер" порта, что, мягко гойворя, не приветствуется корпоративными традициями кодопейсательства...

З.Ы.Ы. Спасибо всем за мозговой штурм, в конце-концов все заработало по принципу:
1) проверяем, есть ли нужный файл /tmp/чтототам.pid, читаем оттуда pid
2) если есть - проверяем запущен ли такой процесс через signal(pid, 0)
3) если запущен - дополнительно проверяем через readlink(..."/proc/<pid>/exe"...), что этот процесс имеет то же имя, что и текущий

З.Ы.Ы.Ы причины, почему блокируется lockf(...F_TEST...) и flock(...|LOCK_NB...) так и остались невыясненными: блокируется оно даже и не на nfs

[identity profile] theiced.livejournal.com 2015-08-17 05:41 pm (UTC)(link)
очевидно что нету. посему или пидфайл или говно и палки от системд.

[identity profile] psilogic.livejournal.com 2015-08-17 05:43 pm (UTC)(link)
что есть пидфайл и как он спасет аццов демократии?

[identity profile] theiced.livejournal.com 2015-08-17 05:48 pm (UTC)(link)
flock + записать пид залочившего в файл. при попытке нового запуска кроме самого пидфайла проверять ещё есть ли такой процесс. можно ещё ему сигналов послать на предмет жив ли он, всё вот это.

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

[identity profile] psilogic.livejournal.com 2015-08-17 05:56 pm (UTC)(link)
послать сигнал на предмет сдох ли он - вот эта вот идея выглядит очень антересно
а не подскажет ли уважаемый дон, который из сигналов считается "кошерным" для этой цели?
SIGUSR1 с предварительным signal(SIGUSR1, SIG_IGN)?

что я хочу - защиту от одновременного запуска двух instance, которая не требует танцев с бубном, если прога йопнулась или была йопнута через kill -9
Edited 2015-08-17 17:58 (UTC)

[identity profile] theiced.livejournal.com 2015-08-17 06:03 pm (UTC)(link)
я ж не линуксоид, откуда я помню как это говно внутре в деталях :)

[identity profile] psilogic.livejournal.com 2015-08-17 06:06 pm (UTC)(link)
ааа...
ну все равно хоть какой-то выход, спасибо! :)

[identity profile] afa-at-work.livejournal.com 2015-08-17 10:24 pm (UTC)(link)
ххе
"а руки то помнят!"

[identity profile] scholarpunk.livejournal.com 2015-08-17 06:14 pm (UTC)(link)
Молиться надо!..

[identity profile] psilogic.livejournal.com 2015-08-17 06:16 pm (UTC)(link)
тьфубля! :))))

[identity profile] metaclass.livejournal.com 2015-08-17 06:32 pm (UTC)(link)
Открыть pidfile и сделать ему сразу unlink при старте?

[identity profile] psilogic.livejournal.com 2015-08-17 06:37 pm (UTC)(link)
если unlink до открытия файла, то просто не будет никакого эффекта - второй инстанс успешно удалит файл из директории, потом успешно создаст другой с таким же именем, а файл, открытый первым инстансом, останется висеть в памяти и на диске, пока первый инстанс не завершится

винды не позволяют удалять открытый файл, никсы - позволяют

[identity profile] theiced.livejournal.com 2015-08-17 06:54 pm (UTC)(link)
не обращай внимания, метакласс деградирует в текущем круге общения.

[identity profile] psilogic.livejournal.com 2015-08-17 08:15 pm (UTC)(link)
ты как всегда человеколюбив =)))

[identity profile] theiced.livejournal.com 2015-08-18 07:34 am (UTC)(link)
это не я, это реальность такая. к сожалению.

[identity profile] afa-at-work.livejournal.com 2015-08-17 10:33 pm (UTC)(link)
унлинк кильнет имя. файл на диске еще размещен. но надо ж имя лочить.

[identity profile] ujo.livejournal.com 2015-08-17 06:53 pm (UTC)(link)
Дык как все

http://stackoverflow.com/questions/5339200/how-to-create-a-single-instance-application-in-c-or-c

#include <sys/file.h>
#include <errno.h>

int pid_file = open("/var/run/whatever.pid", O_CREAT | O_RDWR, 0666);
int rc = flock(pid_file, LOCK_EX | LOCK_NB);
if(rc) {
if(EWOULDBLOCK == errno)
; // another instance is running
}
else {
// this is the first instance
}
Edited 2015-08-17 18:54 (UTC)

[identity profile] theiced.livejournal.com 2015-08-17 06:55 pm (UTC)(link)
просто flock очевидно не работает. потому что.

[identity profile] ujo.livejournal.com 2015-08-17 06:56 pm (UTC)(link)
На NFS это всё плохо совсем будет, да - но вообще это считается вроде как достаточным методом.

[identity profile] theiced.livejournal.com 2015-08-17 06:57 pm (UTC)(link)
к несчастью считается. ну просто пионерская поделка - сколько ты в неё бабла и людей не вбухивай, останется пионерской поделкой.

[identity profile] psilogic.livejournal.com 2015-08-17 08:14 pm (UTC)(link)
это ты про nfs, про alt-linux или про оба? :)))

[identity profile] theiced.livejournal.com 2015-08-18 07:32 am (UTC)(link)
про линупс вообще.

[identity profile] psilogic.livejournal.com 2015-08-17 08:13 pm (UTC)(link)
такой код не хочет работать на alt-linux с nfs: выглядит так, будто LOCK_NB игнорируется, второй инстанс виснет на системном вызове "futex"

[identity profile] afa-at-work.livejournal.com 2015-08-17 10:35 pm (UTC)(link)
насколько помню, в нфс работа с блокировками странная. изначально отсутствовала - фигли, стэйтлес файлуха.

[identity profile] ujo.livejournal.com 2015-08-18 03:56 am (UTC)(link)

NFS плохо работает с блокировками. Холмс, но зачем же для локальных процессов делать файл блокировки на NFS? Тем более что есть специальное место /var/lock/subsys.

[identity profile] psilogic.livejournal.com 2015-08-18 08:06 am (UTC)(link)
Что значит зачем - у меня выбора нет. Работать должно по возможности везде.

А /var/lock/subsys - он в этом смысле отличается от прочих мест?

[identity profile] ujo.livejournal.com 2015-08-18 10:07 am (UTC)(link)

Var lock subsys размещается на локальной (иногда временной) файловой системе, и ограничений нфс не имеет.


А пидфайлы, если это важно, кладут в var run

[identity profile] psilogic.livejournal.com 2015-08-18 04:42 pm (UTC)(link)
В общем, на другом компе sfdisk показывает тип файл. системы 83 ("Linux") и все равно тот же глюк. В конце-концов прога заработала через пид-файл и signal(pid, 0).

[identity profile] ujo.livejournal.com 2015-08-18 05:29 pm (UTC)(link)

sfdisk вообще не о том показывает, не надо туда смотреть. Тип файлухи можно увидеть например командой mount без параметров.

[identity profile] psilogic.livejournal.com 2015-08-18 06:03 pm (UTC)(link)
OK, завтра посмотрю

[identity profile] psilogic.livejournal.com 2015-08-21 01:52 pm (UTC)(link)
как оказалось, на компе
/ = ext4 (lockf работает)
/tmp = tmpfs (lockf работает)
/home = nfs (lockf не работает)
ну и дело было в /home/xen...

[identity profile] ujo.livejournal.com 2015-08-21 05:42 pm (UTC)(link)
Ага, ну вот всё и выяснилось. Спасибо, мне было интересно в чём же дело.

[identity profile] afa-at-work.livejournal.com 2015-08-17 06:55 pm (UTC)(link)
unix socket?

[identity profile] psilogic.livejournal.com 2015-08-17 08:18 pm (UTC)(link)
Разве что в никсах существуют именованные сокеты, иначе придется занимать "well-known" порт, который может внезапно оказаться занят кем-то еще. А то и несколько сокетов, если я хочу иметь представление о состоянии нескольких "наших" процессов. Пока лучшей выглядит идея с созданием файла на старте, удалением на выходе и дополнительной проверкой через посылку signal-а, чтобы исключить краш/килл.

[identity profile] afa-at-work.livejournal.com 2015-08-17 10:31 pm (UTC)(link)
unix socket и есть именованный сокет. ограничение - работает в рамках хоста. ну как пидфайл. является этаким проколом реальности в сокетах. закрываются при краше. но вот применять как мутекс - неверно наверн. пидфайл, с чтением что там есть, по этому пиду, и проверкой на себя наверн лучше. библиотек для - наделано немеряно, в каждом скриптовом языке аналог можно найти.

[identity profile] psilogic.livejournal.com 2015-08-17 10:37 pm (UTC)(link)
А, вот оно что - unix socket ≠ socket in unix :) Учитывая, что интерфейс к сокетам сам по себе довольно инопланетный, наверное, через pid и впрямь дешевле будет.

[identity profile] afa-at-work.livejournal.com 2015-08-17 10:47 pm (UTC)(link)
ну да. заодно и аккуратно грохнуть из скрипта можно будет

[identity profile] russhatter.livejournal.com 2015-08-18 09:32 am (UTC)(link)
Не очень понятно, почему он "инопланетный". Он просто с древних времён остался, и, поскольку оказался достаточно хорошим, его и не причёсывали с тех времён. Как раз очень хорошая рекомендация. Всем хватает - Вам нет.
Открыть именованный сокет - самое правильное решение. А писать код с нуля - вовсе не обязательно. Простенький код для сервера доступен в более или любом фреймворке.

[identity profile] psilogic.livejournal.com 2015-08-18 09:43 am (UTC)(link)
Инопланетный потому, что больше нигде вы не найдете последовательностей инициализации типа socket->bind->listen->accept

[identity profile] russhatter.livejournal.com 2015-08-18 10:11 am (UTC)(link)
Ну я и говорю: это давно придумали, слишком давно. Но никому особенно не мешает до сих пор. Код на этом уровне пишется один раз, или даже не пишется. Какая разница: инопланетный-планетный, работает и хана.

[identity profile] ujo.livejournal.com 2015-08-18 04:01 am (UTC)(link)

Она видимо и есть лучшая, потому что традиционно её используют. Но вот процесс по пид файлу с PID лучше проверять по наличию в таблице процессов и сверять, тот ли это процесс, номер и заместить могут.

[identity profile] psilogic.livejournal.com 2015-08-18 08:14 am (UTC)(link)
Это мудрая мысль, тогда вопрос: это надо вывод [ ps -a ] парсить или есть более гуманный путь?

[identity profile] ujo.livejournal.com 2015-08-18 10:03 am (UTC)(link)

Если "везде" касалось только линуксов, тогда проверять /proc/pidnumber/args и /proc/pidnumber/exe

[identity profile] theiced.livejournal.com 2015-08-18 01:59 pm (UTC)(link)
пока очередной поттеринг там что нибудь не сломает, ага.

[identity profile] ujo.livejournal.com 2015-08-18 05:27 pm (UTC)(link)

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

[identity profile] theiced.livejournal.com 2015-08-18 10:11 pm (UTC)(link)
с какой одной? малыш, ты там часом не попутал?