14 нояб. 2012 г.

semget errno=ENOSPC -- check system limit for sysv semaphores.

Странное название этой записи изначально может и ничего не говорит о ее содержании, но тем не менее с этой вещью столкнуться можно и надо знать как ее излечить.
Раньше я с такими вещами не сталкивался, но на днях занимался (в который раз) отладкой работы программы GAMESS и при многочисленном тестовом запуске появилась ошибка типа:

 DDI Process 25: semget return an error.
 semget errno=ENOSPC -- check system limit for sysv semaphores.
 DDI Process 9: semget return an error.
 semget errno=ENOSPC -- check system limit for sysv semaphores.
 DDI Process 10: error code 911
 DDI Process 8: error code 911
 DDI Process 13: error code 911
 DDI Process 15: error code 911
 DDI Process 23: error code 911
 DDI Process 28: error code 911
 DDI Process 29: error code 911
 DDI Process 31: error code 911



Речь здесь идет о том, что количество semaphores превышает максимальное, и поэтому программа не может быть запущена. Объяснять что это такое я не буду, т.к. сам не совсем понимаю, но почитать об этом можно, например, здесь: http://www.embeddedheaven.com/linux-semaphore-tutorial.htm
Итак, для борьбы с этим делом нужно, что логично видно из описания ошибки, увеличить системный предел для количества вызовов этих самых семафоров, либо же удалить из памяти запущенные. Более правильным, мне кажется, будет удалить запущенные, которые не смогли уйти из памяти после экстренного завершения работы GAMESS. По идее, если программа заканчивает работу без ошибок, то все будет нормально, но если же она была прервана и потом запущена, и это было сделано неоднократно, то семафоры не будут уходить из памяти, а будут там висеть, занимая место, поэтому их надо убрать.
Блуждая по интернету в поисках решения, я нашел хорошую подсказку (http://stackoverflow.com/questions/2143404/delete-all-shared-memory-and-semaphores-on-linux).
Опишу, в чем же суть. А суть состоит в том, чтобы написать небольшой скрипт, который бы сам убирал все неубранные семафоры данного пользователя из памяти. Проверить есть ли запущенные семафоры в памяти можно командой:

ipcs

Соответственно, всю информацию по этой команде можно посмотреть в ее мануале

man ipcs

Это все хорошо, но в случае GAMESS-а семафоров создается очень много, и убирать их вручную не представляется никакой возможности. Для этого нужен скрипт. Сейчас я приведу текст скрипта, который автоматом убирает все из памяти:


#!/bin/bash

ME=`whoami`

IPCS_S=`ipcs -s | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`
IPCS_M=`ipcs -m | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`
IPCS_Q=`ipcs -q | egrep "0x[0-9a-f]+ [0-9]+" | grep $ME | cut -f2 -d" "`


for id in $IPCS_M; do
  ipcrm -m $id;
done

for id in $IPCS_S; do
  ipcrm -s $id;
done

for id in $IPCS_Q; do
  ipcrm -q $id;
done

Я сохранил этот скрипт у себя в домашней директории и сделал ссылку в bashrc на нее вида:

alias kill_ipcs='/home/user/kill_ipcs.sh'

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

3 комментария:

  1. Отлично. Недавно напоролся на точно такую же канитель, не знал, что делать. Спасибо.

    ОтветитьУдалить
  2. Thank you very much! This post has been extremely helpful in fixing my GAMESS crash.

    Большое спасибо! Этот пост был чрезвычайно полезен для исправления моего сбоя GAMESS. (From Google Translate!)

    ОтветитьУдалить