Bug 5402 - rsync --daemon sometimes hits its own RLIMIT_NPROC=1 setting
Summary: rsync --daemon sometimes hits its own RLIMIT_NPROC=1 setting
Status: CLOSED FIXED
Alias: None
Product: Sisyphus
Classification: Development
Component: rsync-server (show other bugs)
Version: unstable
Hardware: all Linux
: P2 major
Assignee: placeholder@altlinux.org
QA Contact: qa-sisyphus
URL: http://lists.altlinux.ru/pipermail/si...
Keywords:
Depends on:
Blocks:
 
Reported: 2004-10-26 17:57 MSD by Sergey Golovin
Modified: 2005-07-13 15:46 MSD (History)
3 users (show)

See Also:


Attachments
rsync-2.6.3-alt-setrlimit.patch (2.34 KB, patch)
2004-10-27 15:57 MSD, Dmitry V. Levin
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergey Golovin 2004-10-26 17:57:58 MSD
Разбираясь с проблемой по ссылке, обнаружил, что в альтовском пакете rsync есть
такие строчки, затрагивающие resource limits:
--------------------------------------------------
                 /* Enforce resource limits. */                                
                         
                rlim.rlim_cur = rlim.rlim_max = 1;                           
                if (setrlimit (RLIMIT_NPROC, &rlim)) {
--------------------------------------------------
Они добавляются патчем rsync-2.6.1-alt-setrlimit.patch. Опытным путем :-)
установлено, что описанная по ссылке проблема разрешается, если указать
--------------------------------------------------
              rlim.rlim_cur = rlim.rlim_max = 45;
--------------------------------------------------
или больше, и пересобрать пакет.
Поскольку без этого патча все работает, а на тестовой программке, никак с rsync
не связанной, наблюдается похожая проблема (при небольших значениях RLIMIT_NPROC
fork возвращает ошибку EAGAIN), то решил повесить багу на ядро.
Comment 1 Sergey Vlasov 2004-10-26 18:44:23 MSD
Так RLIMIT_NPROC - это как раз и есть средство для ограничения количества
процессов ;)

Ядро в данном случае ведёт себя совершенно правильно - запрещает fork(). А вот
почему rsync в данном случае собирается делать fork() - это вопрос. Вероятно,
предполагалось, что для rsync --daemon будет разрешено только чтение.

Перевешиваю на rsync-server.
Comment 2 Dmitry V. Levin 2004-10-26 18:52:34 MSD
Действительно, зачем ему fork?
Comment 3 Sergey Golovin 2004-10-26 19:44:09 MSD
(In reply to comment #2)
> Действительно, зачем ему fork?

Этот fork находится в main.c в функции do_recv:                                
                        
------------------------------------------                                     
                        
        if ((pid = do_fork()) == 0) {                                          
                        
------------------------------------------                                     
                        
                                                                               
                        
чтобы сэкономить вам время, потому что моей квалификации                       
                        
на разборку с этим не хватило, а рабочий rsync очень хочется :-).
Comment 4 Sergey Golovin 2004-10-26 19:46:39 MSD
(In reply to comment #1)
> Так RLIMIT_NPROC - это как раз и есть средство для ограничения количества    
                        
> процессов ;)                                                                 
                        
                                                                               
                        
Но оно должно поддаваться логике :-), а какая логика в том, что если я         
                        
хочу  зааплоудить файлик на rsync-сервер, то это у меня не получается          
                        
ровно до тех пор, пока не проставлю эту константу >= 45? Сомневаюсь, что       
                        
для такой простой операции rsync не хватает 44 процессов. К тому же, я         
                        
написал маленький тест rlimit.c в аттаче. Но настаивать не буду, т.к.          
                        
в RLIMITах не разбираюсь :-)                                                   
                        
   
> Ядро в данном случае ведёт себя совершенно правильно - запрещает fork(). А вот
                      
> почему rsync в данном случае собирается делать fork() - это вопрос. Вероятно,
                        
> предполагалось, что для rsync --daemon будет разрешено только чтение.        
                        
                                                                               
                        
более удобная замена ftp, scp, rcp - все они умеют аплоудить и не              
                        
жалуются на лимиты ;-)                                                         
                        
                                                                               
                        
> Перевешиваю на rsync-server.                                                 
                        
                                                                               
                        
так я тестировал и без xinetd, чтобы исключить лишнее звено.                   
                        
Тогда уж на rsync.
Comment 5 Dmitry V. Levin 2004-10-26 21:25:34 MSD
Логика работы rsync в разных режимах разная, возможно, что в одном из них этот
rlimit устанавливать нельзя.
Comment 6 Sergey Golovin 2004-10-26 21:38:16 MSD
(In reply to comment #0)
Бог с ним с rsync - отвлечемся на небольшую программку:
-----------------------------------------------------------
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>

extern int errno;

main()
{
     int pid;
     int i;
     int err;
     struct rlimit rlim;

     i = 40;
     rlim.rlim_cur = rlim.rlim_max = i;
     setrlimit(RLIMIT_NPROC, &rlim);
     if ((pid = fork()) == 0)
     {
          printf("rlimit %i -- OK\n", i);
          _exit(0);
     }
     else if (pid == -1)
     {
          err = errno;
          if (err == EAGAIN)
               printf("rlimit %i -- FAILED\n", i);
     }
     else
          waitpid(pid, NULL, WUNTRACED);
}
---------------------------------------------------

в этом тесте тоже не форкается при i<41. Почему? В чем причина?
Comment 7 Dmitry V. Levin 2004-10-26 21:46:53 MSD
Сергей, прочтите setrlimit(2) и не задавайте больше детских вопросов.
Comment 8 Dmitry V. Levin 2004-10-27 15:57:32 MSD
Created attachment 619 [details]
rsync-2.6.3-alt-setrlimit.patch

Потестируйте этот патч вместо rsync-2.6.1-alt-setrlimit.patch
Comment 9 Sergey Golovin 2004-10-27 19:55:34 MSD
Заработало. 
Comment 10 Dmitry V. Levin 2004-10-27 20:33:20 MSD
Ok, fixed in rsync-server-2.6.3-alt2