App in container is seeing host's max memory, not container's

I stumbled upon this while debugging an unrelated issue. Any help is appreciated and thank you in advance!

The container (and host) is Ubuntu 20.04 and GraphicsMagick (which has a ceiling memory usage variable) is showing the hosts total memory (62.9GB) and not the container’s memory value (29.8GB).

This is the command ran inside the container:

app01:~# gm convert -list resource
Resource Limits (Q16, 64 bits/pixel, 64bit address)
----------------------------------------------------
    Disk:  Unlimited (MAGICK_LIMIT_DISK)
   Files:        256 (MAGICK_LIMIT_FILES)
     Map:   125.7GiB (MAGICK_LIMIT_MAP)
  Memory:    62.9GiB (MAGICK_LIMIT_MEMORY)

MAGICK_LIMIT_MEMORY is showing the host’s memory amount of 62.9GiB.

What the container shows via free (also htop shows the correct value too)

app01:~# free -h
              total        used        free      shared  buff/cache   available
Mem:           29Gi       1.8Gi        27Gi       0.0Ki       234Mi        27Gi

In this case it would allow GraphicsMagick to blow past the container’s max memory.

Digging into the GraphicsMagick code I think I’ve found (I may be wrong) where it’s pulling the value if that provides any help. Key variable to see is total_memory.

via: https://github.com/kstep/graphicsmagick/blob/c70db3c4669305a5b8c4d5f6573963ca7d7358c2/magick/resource.c#L565

(disclaimer this is an old version of GraphicsMagick mirror I found on Github)

  /*
    Set Magick resource limits.
  */
#if defined(POSIX)
  {
    unsigned long
      total_memory=0;

#  if  defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
    {
      long
        pagesize=-1,
        pages=-1;
      /*
        Compute total physical memory based on number of memory pages,
        and page size.
      */
      pages=sysconf(_SC_PHYS_PAGES);
      pagesize = MagickGetMMUPageSize();

      if (pages > 0 && pagesize > 0)
        total_memory=((pages+512)/1024)*((pagesize+512)/1024);
      (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
                            "Total physical memory %ld MB (%ld pages and %ld bytes per page)",
                            total_memory, pages, pagesize);
    }
#  elif defined(MAGICK_PHYSICAL_MEMORY_COMMAND) && defined(HAVE_POPEN)
    {
      double
        bytes=0;

      FILE
        *command;
      /*
        Execute the external command defined by
        MAGICK_PHYSICAL_MEMORY_COMMAND to obtain the total physical
        memory in bytes.  This external command should be quite speedy
        or else it will impact the time to start GraphicsMagick.
      */
      if ((command = popen(MAGICK_PHYSICAL_MEMORY_COMMAND, "r")) != NULL)
        {
          if (fscanf(command,"%lf",&bytes) == 1)
            total_memory=(bytes/(1024*1024));
          (void) pclose(command);
          (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
                                "Total physical memory %ld MB",total_memory);
        }
    }
#  endif

    if (total_memory > 0)
      {
        /*
          We are not able to use more than size_t worth of address
          space.  On 32 bit systems, we can usually only use half or
          three quarters of it.  Regardless, we need address space
          for more than just image data.
        */
        size_t
          size_t_max = (size_t) ~0UL;

        size_t_max /= (1024U*1024U);
        max_memory = Min(size_t_max/2-100,total_memory);
        max_map = Min(size_t_max/2-100,2*total_memory);
      }
  }
#endif /* defined(POSIX) */

There’s indeed some software that thinks they should go do math to figure out physical memory instead of relying on what’s available in /proc/meminfo.

We can’t really do anything about those and they’ll indeed be able to figure out how much memory there is on the host system. They still won’t be able to use past what’s allocated to the container but if they don’t handle being told no nicely, they may crash.

Ok good to know! Thank you for the fast reply.

Cheers!