msync - can someone shed some light please?

Richard Kettlewell rjk at terraraq.uk
Fri Jun 13 21:55:50 UTC 2025


Julien ÉLIE wrote:
> Hi Chris,
> 
>> When adding groups (ctlinnd newgroup…), the following occurs:
>>
>> 2025-06-12T14:14:57.572314+02:00 nntpspool innd: SERVER msync failed / 
>> var/lib/news/active 0x0x7f3f46800000 5062656 Cannot allocate memory
>>
>> Inn refuses to start up, until I literally remove 1 line from my 
>> active file.  As soon as I add them again, the issue reoccurs.  The 
>> name of the group being added/removed is of no consequence, the issue 
>> is about the amount of groups – that is what is getting me here, I 
>> completely fail to understand how inn can’t start up with ~107K groups 
>> in the active file.
>>
>> root at nntpspool ~ # cat /var/lib/news/active|wc -l
>> 107411
>>
>> INN 2.7.3
> 
> What operating system are you using?
> Do you build from sources?  If that is the case, may you try to change 
> in lib/mmap.c:
> 
>      char *start = (char *) ((uintptr_t) p & mask);
>      char *end = (char *) (((uintptr_t) p + length + pagesize) & mask);
> 
> to:
> 
> 
>      char *start = (char *) ((size_t) p & mask);
>      char *end = (char *) (((size_t) p + length + pagesize) & mask);
> 
> It is the only recent change (in 2023) in the code dealing with mmap/ 
> msync.  Though I am unsure it would solve the memory allocation issue, 
> it may be the first thing to test.
> Otherwise, I am sorry I do not have any other clue right now.
> 
> The wanted allocation is 5,062,656 bytes according to the log, so it 
> should have worked on your server with 128 GB of RAM...

Assuming the page size is 4096 bytes:
* p = 0x7f3f46800000 is already page-aligned so start = p
* length = 5062656 is a multiple of 4096,
   so we will get end = p + length + 4096,
   given end-start = length+4096.

The effect is that INN will attempt to msync 4096 bytes beyond the end 
of the mapping.

In https://man7.org/linux/man-pages/man2/msync.2.html doing this is 
documented as being an error. The error code is consistent with the log 
message:

        ENOMEM The indicated memory (or part of it) was not mapped.

If length % 4096 > 0 then the effect would just be to round up to an 
exact number of pages, avoiding the error. So we'd expect to see the 
error in 1/4096 (about 0.025%) of possible active files sizes.

Anyway I think it should be:

   char *end = (char *) (((uintptr_t) p + length + pagesize - 1) & mask);

...so that we end up to the round of the allocation, and never any further.

ttfn/rjk



More information about the inn-workers mailing list