Разбираясь с проблемой по ссылке, обнаружил, что в альтовском пакете 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), то решил повесить багу на ядро.
Так RLIMIT_NPROC - это как раз и есть средство для ограничения количества процессов ;) Ядро в данном случае ведёт себя совершенно правильно - запрещает fork(). А вот почему rsync в данном случае собирается делать fork() - это вопрос. Вероятно, предполагалось, что для rsync --daemon будет разрешено только чтение. Перевешиваю на rsync-server.
Действительно, зачем ему fork?
(In reply to comment #2) > Действительно, зачем ему fork? Этот fork находится в main.c в функции do_recv: ------------------------------------------ if ((pid = do_fork()) == 0) { ------------------------------------------ чтобы сэкономить вам время, потому что моей квалификации на разборку с этим не хватило, а рабочий rsync очень хочется :-).
(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.
Логика работы rsync в разных режимах разная, возможно, что в одном из них этот rlimit устанавливать нельзя.
(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. Почему? В чем причина?
Сергей, прочтите setrlimit(2) и не задавайте больше детских вопросов.
Created attachment 619 [details] rsync-2.6.3-alt-setrlimit.patch Потестируйте этот патч вместо rsync-2.6.1-alt-setrlimit.patch
Заработало.
Ok, fixed in rsync-server-2.6.3-alt2
http://lists.altlinux.ru/pipermail/errata/2004-October/000016.html