Сбой чтения файлов в папке scriptfiles
#1

Нужны советы. Внезапно произошёл какой-то сбой с файлами. В один миг перестались читаться все файлы (.txt, .bans, .ini, .db), которые находятся в папке scriptfiles.
Клиентский лог server_log.txt продолжил работу после сбоя, сервер не упал, продолжать работать, от игроков жалоб не было, анализ журнала фтп от хостера тоже ничего не дал.

Анализ server_log.txt:

перед сбоем
[17:32:28] [chat] [Nickname]: быстро там приступник был
[17:32:35] [chat] [Nickname]: где
[17:32:35] [chat] [Nickname]: спецназ я теперь не в лодке
[17:32:36] [chat] [Nickname]: на крышу
[17:32:41] Incoming connection: *.*.*.*:49640
[17:32:41] [join] Nickname has joined the server (8:*.*.*.*)
и вот началось отсюда
[17:32:41] Не удалось открыть файл 'bans/bans.ini'
[17:32:41] Не удалось создать файл лога 'log/2016/05/log_05.05.16.txt'
...
[00:25:46] Не удалось открыть конфиг 'config/news.ini'
[00:25:46] Не удалось открыть конфиг 'config/cmds.ini'
[00:25:46] Не удалось открыть конфиг 'config/rules.ini'
[00:25:46] Не удалось открыть конфиг 'config/faq.ini'
[00:25:46] Не удалось открыть конфиг 'config/phrases.ini'
[00:25:46] Не удалось открыть конфиг 'config/spawn.ini'
[00:25:47] Не удалось создать файл лога 'log/2016/05/log_07.05.16.txt'

Код. Практически все файлы мода создаются/читаются в созданной мною ф-ии ниже:
PHP Code:
ExampleFunc()
{
    if (!
fexist("config/news.ini"))
    {
        
printf("Конфиг '%s' не найден""config/news.ini");
        return;
    }
    new 
Filehandle fopen("config/news.ini"io_read);
    if (
handle)
    {
        
// Код...
        
fclose(handle);
    }
    else
    {
        
// Срабатывает именно вот эта часть кода
        
printf("Не удалось открыть конфиг '%s'""config/news.ini");
    }

За пол года работы сервера - такой сбой с файлами произошёл впервые. После выключения сервера (/rcon exit) все файлы вновь стали нормально читаться, что это за уязвимость в моде пока не ясно
Reply
#2

Серв на лине? Во время работы меняются права на файлы в системе?
Reply
#3

На лине да. На счёт прав если честно не знаю что там, я лично их не менял, и в изменение прав никогда не лезу.
Reply
#4

Просто из практики бывало, что юзеры сначала под рутом запускали серв, а потом через юзера и получали подобную ситуацию с файлами.

А ещё стоит проверить на то, что эти же файлы до момента вызова твоей функции уже закрылись (поискать не забыл ли где fclose()
Reply
#5

Спс, буду разбираться. Если есть ещё варианты, пишите. Файлы снова стали читаться после перезагрузки, но это же не выход, потому что есть вероятность - что сбой снова повторится не завтра, так через месяц)
Самое интересное, что всё перестало читаться из папки scriptfiles, даже базы .db, в которые я вообще не лез.
Reply
#6

Явно проблема с правами доступа.
Reply
#7

pawn Code:
return;
1 или 0 - сделай выбор)
Reply
#8

Quote:

1 или 0 - сделай выбор)

ахаах, мой выбор - вернуть ничего)
Quote:

Явно проблема с правами доступа.

Что мне нужно делать в этом случае?
Вот скрин с фтп FileZilla Client, все файлы в scriptfiles имеют числовое значение 644
Reply
#9

Quote:
Originally Posted by Diman777
View Post
ахаах, мой выбор - вернуть ничего)

Что мне нужно делать в этом случае?
Вот скрин с фтп FileZilla Client, все файлы в scriptfiles имеют числовое значение 644
Покажи вывод ls -l scriptfiles/
Reply
#10

Доступ к файлам мода, которые на Лине - я получаю только через фтп-клиент. Где ж я ввиду команду ls? Не особо шарю в таких тонкостях, поэтому хз
Reply
#11

Quote:
Originally Posted by Diman777
View Post
Доступ к файлам мода, которые на Лине - я получаю только через фтп-клиент. Где ж я ввиду команду ls? Не особо шарю в таких тонкостях, поэтому хз
Тогда покажи владельца этих файлов (можно посмотреть в FileZilla).
Reply
#12

У всех файлов ftp владелец
Reply
#13

Quote:
Originally Posted by Diman777
View Post
У всех файлов ftp владелец
Поменяй владельца на того, от которого пытаешься запустить сервер. Или добавь своего пользователя в группу ftp. Если не знаешь как это сделать, обратись к своему хостинг провайдеру.
Reply
#14

Собственно получил ответ от тех. поддержки:
Quote:

Работа по FTP производится под тем же пользователем, под которым работает игровой сервер.
Никаких изменений прав не нужно - это ничего не исправит, однако может вызвать проблемы при их неправильной установке.
В Вашем сообщении на форуме указано "Файлы снова стали читаться после перезагрузки" - это однозначно указывает на проблемы в моде, которые были убраны перезагрузкой. Очевидно, в случае сбоя ОС и/или файловой системы перезапуск программы никак бы не исправил ситуацию.

Также пояснили, что проблема скорей всего в моде (указали на fclose) и посоветовали провести подробный дебаг.
Reply
#15

Я бы проверил, сколько/какие файлы открыты, когда начинаются проблемы
Reply
#16

Quote:

сколько/какие файлы открыты

Приведи пример такого способа, или в чём принцип
Reply
#17

Quote:
Originally Posted by Diman777
View Post
Приведи пример такого способа, или в чём принцип
Надо полагать, что как-то так

PHP Code:
#define MAX_OPENED_FILES     (508) //на виндовс получилось открыть 507
#define MAX_PATH_LEN        (64) //это от балды: я не знаю, что тут должно быть
enum of_enum
{
    
filepath[MAX_PATH_LEN],
    
Filefilehandle
}
new 
opened_files[MAX_OPENED_FILES][of_enum];
new 
opened_files_count;
stock Filetemp_fopen(path[], filemode:mode io_readwrite)
{
    new 
Filehandle fopen(pathmode);
    if(
handle)
    {
        if(
opened_files_count MAX_OPENED_FILES)
        {
            
strmid(opened_files[opened_files_count][filepath], path0MAX_PATH_LEN 2MAX_PATH_LEN);
            
opened_files[opened_files_count][filehandle] = handle;
            
opened_files_count ++;
        }
        else
        {
            
printf("temp_fopen: слишком много открытых файлов (%s)"path);
        }
    }
    return 
handle;
}
#define fopen temp_fopen
stock temp_fclose(Filehandle)
{
    new 
ret fclose(handle);
    if(
ret == 1)
    {
        for(new 
iopened_files_counti++)
        {
            if(
opened_files[i][filehandle] == handle)
            {
                
opened_files_count--;
                
                if(
!= opened_files_count)
                {
                    
strmid(opened_files[i][filepath], opened_files[opened_files_count][filepath], 0MAX_PATH_LEN 2MAX_PATH_LEN);
                    
opened_files[i][filehandle] = opened_files[opened_files_count][filehandle];
                }
            
                break;
            }
        }
    }
    
    return 
ret;
}
#define fclose temp_fclose
COMMAND:openedfiles(playerid)
{
    
printf("На данный момент открыто файлов: %d"opened_files_count);
    
    for(new 
iopened_files_counti++)
    {
        
printf("%d) %s"iopened_files[i][filepath]);
    }
    
    return 
1;

Это надо добавить в самый верх. Команда /openedfiles выводит в лог список открытых файлов.

И да, следует заметить, что это не сработает, если файлы открываются еще где-либо кроме основного мода.
Reply
#18

Ого, буду тестить, спс)
Reply
#19

Вообщем наблюдал за модом, и эта фигня с файлами повторялась уже раз 5, причём есть небольшая особенность - файлы перестают работать ~ через 5-6 дней работы мода (если мод не перезагружать конечно же).
Попробывал сделать следующее - отключал файлы по одному, что выявить где проблема, и теперь на 95% уверен, что проблема в моём логе. После его добавления началась эта проблема скорей всего.

Код
PHP Code:
// Макс. длина одной строки в логе (время + группа + текст)
const MAXLEN_STR_LOG 300;
new 
str_log[STRING_256];
#define Log(%1,%2,%3);\
    
{format(str_logSTRING_256, %2, %3);\
    
_Log(%1str_log);}
_Log(group[], text[])
{
    new 
daymonthyearhourminutesecond;
    
getdate(yearmonthday);
    
gettime(hourminutesecond);
    new 
name_log[STRING_64];
    
format
    
(
        
name_logSTRING_64,
        
"log/%d/%02d/log_%02d.%02d.%02d.txt",
        
yearmonthdaymonthyear-2000
    
);
    new 
File:handle;
    if (!
fexist(name_log))
    {
        
handle fopen(name_logio_write);
        if (
handle)
        {
            
fclose(handle);
        }
    }
    
handle fopen(name_logio_append);
    if (
handle)
    {
        new 
str_fmt_log[MAXLEN_STR_LOG];
        
format
        
(
            
str_fmt_logMAXLEN_STR_LOG"%02d.%02d.%02d %02d:%02d:%02d <%s> %s\r\n",
            
daymonthyear-2000hourminutesecondgrouptext
        
);
        for (new 
0strlen(str_fmt_log); i++)
        {
            
fputchar(handlestr_fmt_log[i], false);
        }
        
fclose(handle);
    }
    else
    {
        
printf
        
(
            
"Не удалось создать файл лога '%s'\n\
            Возможные причины:\n\
            1) отсутствует папка с именем 'log';\n\
            2) отсутствует папка с текущим годом;\n\
            3) отсутствует папка с текущим месяцем."
,
            
name_log
        
);
    }

Использование
PHP Code:
Log("деньги""%s (%d) передал игроку %s (%d) $%d"GetPlayerNameEx(from_id), from_idGetPlayerNameEx(him_id), him_idmoney);
Log("жалобы""%s (%d) отправил ЖБ на %s (%d): %s"GetPlayerNameEx(senderid), senderidGetPlayerNameEx(intruderid), intruderidcmd_dest); 
Записи
02.07.16 00:00:08 <пикап> Nickname (3) купил 'Гранаты' цена $3500 патроны 1
02.07.16 00:11:08 <чат/общий> Nickname (1): ок спасибо

Казалось бы - лог записывает всё на ура, 1 день = 1 файл. Но в чём может быть тут проблема? Срабатывает printf, который приведён в коде.

stabker через твой код попробывал сделать дебаг (таймер поставил в OnGameModeInit вместо команды, ибо вводить постоянно команду - это лольство). В клиентский лог постоянно выводит, что открыто 0 файлов, хотя ясен перец, что при входе в игру какие-то файлы открывались для чтения/записи. Код поключил разумеется сразу после a_samp.inc, в самый верх.
Reply
#20

Хз, в коде все нормально, насколько я разбираюсь. Только вот это не обязательно:

PHP Code:
if (!fexist(name_log)) 

    
handle fopen(name_logio_write); 
    if (
handle
    { 
        
fclose(handle); 
    } 

io_append же все равно создаст файл, если его не существует.

---

Попробуй добавить

PHP Code:
printf("На данный момент открыто файлов: %d"opened_files_count); 
     
for(new 
iopened_files_counti++) 

    
printf("%d) %s"iopened_files[i][filepath]); 

сюда

PHP Code:
else 

    
printf 
    

        
"Не удалось создать файл лога '%s'\n\ 
        Возможные причины:\n\ 
        1) отсутствует папка с именем 'log';\n\ 
        2) отсутствует папка с текущим годом;\n\ 
        3) отсутствует папка с текущим месяцем."

        
name_log 
    
); 

По крайней мере будет известно, сколько файлов открыто на момент возникновения проблемы. Даже если 0, то это тоже важный результат.

Quote:
Originally Posted by Diman777
View Post
stabker через твой код попробывал сделать дебаг (таймер поставил в OnGameModeInit вместо команды, ибо вводить постоянно команду - это лольство). В клиентский лог постоянно выводит, что открыто 0 файлов, хотя ясен перец, что при входе в игру какие-то файлы открывались для чтения/записи. Код поключил разумеется сразу после a_samp.inc, в самый верх.
Ну так они же сразу закрываются, поэтому и 0. Либо проблема в чем-то другом, либо она еще не проявилась, когда ты тестил через мой код. Надо подождать достаточно долго или воспользоваться советом, который я написал выше.

---

Как создаются папки под логи?
Reply


Forum Jump:


Users browsing this thread: 5 Guest(s)