This function will try to raise the max number of open files accordingly to * the configured max number of clients. It also reserves a number of file * descriptors (CONFIG_MIN_RESERVED_FDS) for extra operations of * persistence, listening sockets, log files and so forth. * * If it will not be possible to set the limit accordingly to the configured * max number of clients, the function will d
| 3557 | * max number of clients, the function will do the reverse setting |
| 3558 | * g_pserver->maxclients to the value that we can actually handle. */ |
| 3559 | void adjustOpenFilesLimit(void) { |
| 3560 | rlim_t maxfiles = g_pserver->maxclients+CONFIG_MIN_RESERVED_FDS; |
| 3561 | if (g_pserver->m_pstorageFactory) |
| 3562 | maxfiles += g_pserver->m_pstorageFactory->filedsRequired(); |
| 3563 | struct rlimit limit; |
| 3564 | |
| 3565 | if (getrlimit(RLIMIT_NOFILE,&limit) == -1) { |
| 3566 | serverLog(LL_WARNING,"Unable to obtain the current NOFILE limit (%s), assuming 1024 and setting the max clients configuration accordingly.", |
| 3567 | strerror(errno)); |
| 3568 | g_pserver->maxclients = 1024-CONFIG_MIN_RESERVED_FDS; |
| 3569 | } else { |
| 3570 | rlim_t oldlimit = limit.rlim_cur; |
| 3571 | |
| 3572 | /* Set the max number of files if the current limit is not enough |
| 3573 | * for our needs. */ |
| 3574 | if (oldlimit < maxfiles) { |
| 3575 | rlim_t bestlimit; |
| 3576 | int setrlimit_error = 0; |
| 3577 | |
| 3578 | /* Try to set the file limit to match 'maxfiles' or at least |
| 3579 | * to the higher value supported less than maxfiles. */ |
| 3580 | bestlimit = maxfiles; |
| 3581 | while(bestlimit > oldlimit) { |
| 3582 | rlim_t decr_step = 16; |
| 3583 | |
| 3584 | limit.rlim_cur = bestlimit; |
| 3585 | limit.rlim_max = bestlimit; |
| 3586 | if (setrlimit(RLIMIT_NOFILE,&limit) != -1) break; |
| 3587 | setrlimit_error = errno; |
| 3588 | |
| 3589 | /* We failed to set file limit to 'bestlimit'. Try with a |
| 3590 | * smaller limit decrementing by a few FDs per iteration. */ |
| 3591 | if (bestlimit < decr_step) break; |
| 3592 | bestlimit -= decr_step; |
| 3593 | } |
| 3594 | |
| 3595 | /* Assume that the limit we get initially is still valid if |
| 3596 | * our last try was even lower. */ |
| 3597 | if (bestlimit < oldlimit) bestlimit = oldlimit; |
| 3598 | |
| 3599 | if (bestlimit < maxfiles) { |
| 3600 | unsigned int old_maxclients = g_pserver->maxclients; |
| 3601 | g_pserver->maxclients = bestlimit-CONFIG_MIN_RESERVED_FDS; |
| 3602 | /* maxclients is unsigned so may overflow: in order |
| 3603 | * to check if maxclients is now logically less than 1 |
| 3604 | * we test indirectly via bestlimit. */ |
| 3605 | if (bestlimit <= CONFIG_MIN_RESERVED_FDS) { |
| 3606 | serverLog(LL_WARNING,"Your current 'ulimit -n' " |
| 3607 | "of %llu is not enough for the server to start. " |
| 3608 | "Please increase your open file limit to at least " |
| 3609 | "%llu. Exiting.", |
| 3610 | (unsigned long long) oldlimit, |
| 3611 | (unsigned long long) maxfiles); |
| 3612 | exit(1); |
| 3613 | } |
| 3614 | serverLog(LL_WARNING,"You requested maxclients of %d " |
| 3615 | "requiring at least %llu max file descriptors.", |
| 3616 | old_maxclients, |
no test coverage detected