• M
    Fix infinite loop on startup if ulimit too low · 1e7b9980
    Matt Stancliff 提交于
    Fun fact: rlim_t is an unsigned long long on all platforms.
    
    Continually subtracting from a rlim_t makes it get smaller
    and smaller until it wraps, then you're up to 2^64-1.
    
    This was causing an infinite loop on Redis startup if
    your ulimit was extremely (almost comically) low.
    
    The case of (f > oldlimit) would never be met in a case like:
    
        f = 150
        while (f > 20) f -= 128
    
    Since f is unsigned, it can't go negative and would
    take on values of:
    
        Iteration 1: 150 - 128 => 22
        Iteration 2:  22 - 128 => 18446744073709551510
        Iterations 3-∞: ...
    
    To catch the wraparound, we use the previous value of f
    stored in limit.rlimit_cur.  If we subtract from f and
    get a larger number than the value it had previously,
    we print an error and exit since we don't have enough
    file descriptors to help the user at this point.
    
    Thanks to @bs3g for the inspiration to fix this problem.
    Patches existed from @bs3g at antirez#1227, but I needed to repair a few other
    parts of Redis simultaneously, so I didn't get a chance to use them.
    1e7b9980
redis.c 131.3 KB