Здраствуйте господа!
Позвольте я пропущу лирику и изложу суть.
за три дня роутер на базе OpenBsd 4.6 (от ноября 2009) перестал работать три раза.
Симптомы:
все сервисы (в том числе sshd, smb) на роутере перестают отвечать на запросы удалённого администратора. Аналогично перестают работать сервисы pptpd, и пользователи в момент сбоя лишаются доступа в интернет.
Примерно в момент сбоя перестаёт работать журнал логов openbsd. То есть по времени последней записи в /var/log/deamons, /var/log/messages можно определить примерное время, после которого следует сбой. Причём последние записи в этих журналах ничего особенного не представляют(то есть появляются регулярно).
Из локальной сети !!!Можно пропинговать все IP назначенные злополучному роутеру! Но только пропинговать и только из локальной сети.
Запущенные сервисы:
на роутере работают (и всегда работали) sshd, smb сервисы, mysqld, pptpd для клиентов локальной сети. pppoe клиент для соединения с провайдером. httpd (простой и с ssl), ну cron и ещё кучка разной мелочи, которая работает обычно в openbsd.
Месяцами всё работало отменно. За два дня до первого сбоя я в крон установил запуск php скрипта, который обрабатывал записи камер наблюдения, сжимал и конвертировал их в flv для просмотра через веб-админку. Скрипт использует ffmpeg для обработки видео роликов. Несколько раз уже проверял этот скрипт на предмет косяков, но ничего вроде не нашёл. Думал сначала что это этот скрипт виноват, но ведь с ним всё работало пару дней...
Просьба.
Господа, подскажите, где ещё можно посмотреть что происходило с системой в момент сбоя, кроме тех двух лог файлов, которые я привёл выше.. Буду признателен за посильную помощь.
PS: проблем с электричеством на момент сбоев не было.
*.* /var/log/debug
*.* /var/log/debug -дабы не собирать по частям инфу то тут, то там.
в man systat перечислено куда ещё можно глянуть
что на console
что на console видно в это время?
что за железяка - CPU, RAM, disk space?
запусти этот скрипт мануально. сравни поедание ресурсов.
Даже очень интересно!!
Даже очень интересно!! Отключил я из крона скрипт обработки видео. Сервер перестал отключаться.
Я PHP знаю на уровне "когда что-то надо - напишу".... Но всё равно не пойму в чём косяк скрипта. Господа - по мне дак это головоломка. Если кто знаком с PHP - скажите, пожалуйста, в чём есть косяк.
Вот скрипт:
#!/usr/local/bin/php
<?php
##### Подключаемся к базе данных
$dbhost = "127.0.0.1";
$dbname = "traffic";
$dbuser = "operator";
$dbpass = "password";
$dbconnect = @mysql_connect($dbhost,$dbuser,$dbpass);
@mysql_select_db($dbname,$dbconnect);
function scan_dir($dirname)
{
# путь для сохранения FLV и JPG дубликатов
$save_dir = "/var/www/cam-vids";
# путь для apache
$apache_vids_path = "/cam-vids";
# Открываем текущую директорию
$dir = opendir($dirname);
# Читаем в цикле директорию
while (($file = readdir($dir)) !== false)
{
# Если файл обрабатываем его содержимое
if($file != "." && $file != "..")
{
# Если имеем дело с файлом - производим конвертацию
if(is_file($dirname."/".$file))
{
##### Основной блок обработки файла
$currentFile = $dirname."/".$file;
### Определим время создания файла
# Отделим расширение AVI файла
$fileNameArr = explode(".", $file);
### Нам нужны только AVI файлы, остальные пропускаем
if ($fileNameArr[1] != 'avi')
{
continue;
}
# Отделим дату и время создания AVI файла
$avi_file_name = $fileNameArr[0];
$avi_file_name_arr = explode("-", $avi_file_name);
# Разбор даты создания
$avi_year = substr($avi_file_name_arr[0], 0, 4);
$avi_month = substr($avi_file_name_arr[0], 4, 2);
$avi_day = substr($avi_file_name_arr[0], 6, 2);
# Составим дату создания AVI файла в формате YYYY-MM-DD
$avi_create_date = $avi_year.'-'.$avi_month.'-'.$avi_day;
# Разбор времени создания
$avi_hours = substr($avi_file_name_arr[1], 0, 2);
$avi_minutes = substr($avi_file_name_arr[1], 2, 2);
$avi_seconds = substr($avi_file_name_arr[1], 4, 2);
# Составим время создания AVI файла в формате HH:MM:SS
$avi_create_time = $avi_hours.':'.$avi_minutes.':'.$avi_seconds;
# Определим время создания AVI файла в UNIX формате
$avi_create_unixtime = mktime($avi_hours, $avi_minutes, $avi_seconds, $avi_month, $avi_day, $avi_year);
### Определим присутствует ли уже данный файл в базе данных
# Делаем запрос в таблицу camera и проверим результат
$find_current_avi_query = mysql_query("SELECT * FROM camera WHERE unix_time='$avi_create_unixtime' AND avi_path_file='$currentFile';");
$find_current_avi_array = mysql_fetch_array($find_current_avi_query);
# Проверяем.... Переходим к следующему файлу, если искомый файл найден в базе данных
if ($find_current_avi_array)
{
continue;
}
# Проверям файл на предмет того не производится ли в него сейчас запись
# Вычисляем разницу реального времени и времени последней модификации файла
# Это на случай, если в проверямый файл в данный момент идёт запись с камеры наблюдения
$mod_time = filectime($currentFile);
$current_time = time();
$time_different = $current_time - $mod_time;
if ($time_different < 75)
{
continue;
}
### Начинаем конвертацию AVI файла в FLV и создание JPG заглушки
$avi_size = filesize($currentFile);
$snapshot_time = floor(($avi_size / 800000) * 0.29);
# приводим все значения $snapshot_time к виду 00
if ($snapshot_time < 10)
{
$snapshot_time = "0".$snapshot_time;
}
# Создаём FLV файл
$ffmpeg_convert_to_flv = "/usr/local/bin/ffmpeg -i ".$currentFile." -ar 44100 -ab 64k -b 250k -f flv -r 15 -s 640x480 ".$save_dir."/".$fileNameArr[0].".flv > /dev/null 2>&1";
exec($ffmpeg_convert_to_flv);
# проверим созданный файл
$flv_file = $save_dir."/".$fileNameArr[0].".flv";
$flv_size = filesize($flv_file);
if ($flv_size == 0 or !$flv_size)
{
@unlink($flv_file);
continue;
}
# Путь FLV файла для использования APACHE
$flv_file_apache_path = $apache_vids_path."/".$fileNameArr[0].".flv";
# Создаём JPG заглушку
$ffmpeg_create_snapshot = "/usr/local/bin/ffmpeg -i ".$currentFile." -an -ss 00:00:".$snapshot_time." -r 1 -vframes 1 -s 640x480 -y -f mjpeg ".$save_dir."/".$fileNameArr[0].".jpg > /dev/null 2>&1";
exec($ffmpeg_create_snapshot);
# проверяем созданную заглушку
$jpg_file = $save_dir."/".$fileNameArr[0].".jpg";
$jpg_size = filesize($jpg_file);
if ($jpg_size == 0 or !$jpg_size)
{
@unlink($jpg_file);
@unlink($flv_file);
continue;
}
# Путь JPG файла для использования APACHE
$jgp_file_apache_path = $apache_vids_path."/".$fileNameArr[0].".jpg";
# Создаём JPG иконку
$ffmpeg_create_thumb = "/usr/local/bin/ffmpeg -i ".$currentFile." -an -ss 00:00:".$snapshot_time." -r 1 -vframes 1 -s 120x90 -y -f mjpeg ".$save_dir."/".$fileNameArr[0]."-thumb.jpg > /dev/null 2>&1";
exec($ffmpeg_create_thumb);
# проверяем созданную заглушку
$thumb_file = $save_dir."/".$fileNameArr[0]."-thumb.jpg";
$thumb_size = filesize($thumb_file);
if ($thumb_size == 0 or !$thumb_size)
{
@unlink($thumb_file);
@unlink($jpg_file);
@unlink($flv_file);
continue;
}
# Путь JPG файла для использования APACHE
$thumb_file_apache_path = $apache_vids_path."/".$fileNameArr[0]."-thumb.jpg";
### Вновь созданные файлы проверены. Переходим к обновлению базы данных
$completed_vid_query = "INSERT INTO camera VALUES('',
'$avi_create_date',
'$avi_create_time',
'$avi_hours',
$avi_create_unixtime,
'$currentFile',
'$flv_file_apache_path',
'$jgp_file_apache_path',
'$thumb_file_apache_path');";
$completed_vid = mysql_query($completed_vid_query);
# Проверим корректность занесения новых данных в БД
if (!$completed_vid)
{
@unlink($jpg_file);
@unlink($flv_file);
@unlink($thumb_file);
continue;
}
}
# Если перед нами директория, вызываем рекурсивно
# функцию scan_dir
if(is_dir($dirname."/".$file))
{
scan_dir($dirname."/".$file);
}
}
}
# Закрываем директорию
closedir($dir);
}
# Теперь вызовем созданную функцию для директории с роликами
scan_dir("/smb/video-cam");
##### Закроем соединение с базой данных
@mysql_close($dbconnect);
?>
Вот жесть... Я его многократно тестировал... и всё равно какие-то грабли..
О да! скрипт исполняется по крону раз в минуту от root/wheel :-)
Процессор
Процессор интел двухядерный какой-то (775).
Память простая (без ECC). 1 гиг. Дешёвая, но без ошибок.
Жёсткий диск десктопный western digital.
Максимальная нагрузка на процессор в моменты обработки нескольких подряд AVI роликов объёмом от 50 до 150 мегабайт = 25%.
Вот я дубень!!! Действительно! Надо глянуть что выводится на консоль самого сервака в момент зависания.
Просто у сервака нет монитора штатного, поэтому я на нём (на локальной консоли ) не выполняю вход в систему. Поэтому когда я подключил монитор к серваку после очередного зависания, я увидел только предложение ввести логин и пароль. Ввёл логин. Нажал энтер. И всё ))) Дальше и консоль зависла...