Solaris mmap for memory mapped file failing with ENOMEM - c++

On Solaris 10 as well as Linux, I am using mmap call to create a memory mapped file and subsequently read the file from a separate process. For large memory mapped file, during reading (no writing), I am getting ENOMEM. What could be the reason and what could be remedy or way forward? I thought memory mapped file is not occupying memory for the entirety.
I am using the following call:
char * segptr = (char *) mmap(0,sz,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);
where,sz is the file size and fd is file descriptor of file opened through open.
I am getting ENOMEM failure while trying to reserve space for the entirety.
ulimit -a shows:
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
open files (-n) 256
pipe size (512 bytes, -p) 10
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 29995
virtual memory (kbytes, -v) unlimited
Can I map partial file? If I open partial file, then will I able to access the whole contents on-demand? I have not used setrlimit to set any limit, so I guess, using the default (don't know what is the default), should I increase that? Please guide.
How do I map the file in smaller chunks to save over usage of memory and thus avoiding ENOMEM?

Related

dopen(): "failed to map segment from shared object" when not running as root

I am trying to load some self-written libraries under a self-made Yocto Linux.
It works fine when running the same program as root, but not as another, later added user.
for (<all files found in directory>)
{
m_HModule = dlopen(Filename.c_str(), RTLD_NOW | RTLD_GLOBAL);
if (m_HModule == NULL)
{
fprintf(stderr, "Error: %s\n", dlerror());
}
else
{
cout << "Loaded module " << Filename << endl;
}
}
Unfortunately, my version of dlerror() does not return too terribly precise information:
Loaded module /opt/epic/libepicGpioToggle.so
Loaded module /opt/epic/libepicSaveImage.so
Error: libboost_filesystem.so.1.66.0: failed to map segment from shared object
Loaded module /opt/epic/libepicFpgaCommunicatorUserDemo.so
Error: /opt/epic/libepicCommunicatorFpga.so: failed to map segment from shared object
Error: /opt/epic/libepicDataproviderTimedData.so: failed to map segment from shared object
Error: /opt/epic/libepicDataproviderFromCamera.so: failed to map segment from shared object
Loaded module /opt/epic/libepicFramework.so
Error: /opt/epic/libepicTriggerMonitor.so: failed to map segment from shared object
Error: /opt/epic/libepicTemplate.so: failed to map segment from shared object
Even with maximum file permissions chmod 777 * and all libraries being owned by the calling user, it does not work.
Everything works fine when running as root or via sudo.
Yes, some of these libraries use boost elements, which are all available unter /lib and accessible by the calling user. If I do not try to load the libraries referencing boost, the other failures persist.
It is always the same libraries failing to load; the order does not seem to matter.
The compiler settings for all of my libraries look the same, and are all abbreviated from the same "template project".
I checked the dependencies with ldd, straced all system calls and do not see any difference, apart from the error messages.
The user's shell environment env is the same as for root.
With export LD_DEBUG=files, I see
4231: file=/opt/epic/libepicSaveImage.so [0]; dynamically loaded by ./libepicFramework.so [0]
4231: file=/opt/epic/libepicSaveImage.so [0]; generating link map
4231: dynamic: 0x0000ffff8b56fd60 base: 0x0000ffff8b524000 size: 0x000000000004d608
4231: entry: 0x0000ffff8b5487a0 phdr: 0x0000ffff8b524040 phnum: 7
4231:
4231:
4231: file=/opt/epic/libepicGpioToggle.so [0]; needed by /opt/epic/libepicSaveImage.so [0] (relocation dependency)
4231:
4231:
4231: calling init: /opt/epic/libepicSaveImage.so
4231:
4231: opening file=/opt/epic/libepicSaveImage.so [0]; direct_opencount=1
4231:
Loaded module /opt/epic/libepicSaveImage.s
for successful loadings, but
4231: file=/opt/epic/libepicCommunicatorFpga.so [0]; dynamically loaded by ./libepicFramework.so [0]
4231: file=/opt/epic/libepicCommunicatorFpga.so [0]; generating link map
Error: /opt/epic/libepicCommunicatorFpga.so: failed to map segment from shared object
for failures.
User limits ulimits -a look the same for both root and user:
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 10974
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 10974
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
I increased max locked memory to 100's of MB, but no change.
What could be different from the user's perspective?
#JohnBollinger was right - it was the user's limits, with 16384 kbytes being too small for "max memory size".
I had to increase the limit in /etc/security/limits.conf for the specific user by adding
username soft memlock unlimited
username hard memlock unlimited
and then configuring SSHD to obey these limits by adding
session required pam_limits.so
to /etc/pam.d/sshd.
Being root ignores all set limits, no matter if logged on through SSH, directly or via RS-232 TTY.
Thanks for pointing me into the right direction!

python resource limits

Is there some limit for usage of subprocess.Popen..? I observed that it fails continuously at 1017`th execution of external command.
usage:
subprocess.Popen (cmd, shell=True, stdout=file_hndl, stderr=file_hndl)
Expecting the error and output to be redirected to file with file object file_hndl
There is no fault with subprocess.Popen, the havoc is created by using the file_hndl in place of stdout and stderr.
All the resources are limited to each user process in operating system.
Ex:On Linux $ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 30254
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
Note the number of files that can be opened is 1024, This was limiting the execution of subprocess.Popen.
set the resource limit as required using resource.setrlimit.
Ex: resource.setrlimit (resource.RLIMIT_NOFILE, (20000,20000))
You are running out of file handles. You can increase it and check;
More info here
https://unix.stackexchange.com/questions/36841/why-is-number-of-open-files-limited-in-linux
https://unix.stackexchange.com/questions/84227/limits-on-the-number-of-file-descriptors

what happens to HDFS block size in case of smaller file size

i read but still confused
what happens if a file size is less than block size.
if file size is 1MB will it consume 64MB or only 1MB
It will consume only 1 MB. That remaining can be used to store some other files block.
Ex: Consider your HDFS Data node total size is 128MB and block size is 64MB.
Then HDFS can store 2, 64MB blocks
or 128, 1MB blocks
or any number of block that can consume 128MB of Data node.

Call to operator new results in segmentation fault in MPI code

So the following line in an MPI code results in a segfault:
myA = new double[numMyElements*numRows];
, where numMyElements and numRows are both int -s and none of them are garbage. In my test runs numMyElements*numRows = 235074 . The line of code above gets called in a constructor for an object and double* myA is a member of that class. I am using:
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
and
mpirun (Open MPI) 1.4.3
For now I was just running this program with only one processor i.e.
mpirun -np 1 ./program
on my laptop.
The exact error I get is the following:
[user:03753] *** Process received signal ***
[user:03753] Signal: Segmentation fault (11)
[user:03753] Signal code: (128)
[user:03753] Failing at address: (nil)
After which my code hangs and I have to abort it manually. I don't think that I'm running out of heap since when looking at processes through top the program only uses 2.1% of memory.
However! Interestingly enough if I decrease the size i.e. I replace numMyElements*numRows with a small constant like 10 or 100 I don't get the error. I can't go higher than a 1000.
myA = new double[1000];
would result in the same error again.
Just in case my ulimit -a output:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 31438
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 31438
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Does anyone know what could be going on here? Thanks!
As mentioned in the comments, it turns out it was simply an issue of incorrect array indexing unrelated to where the error popped up. Thanks for the comments!

shmget size limit issue

I have this snippet of code:
if ((shmid = shmget(key, 512, IPC_CREAT | 0666)) < 0)
{
perror("shmget");
exit(1);
}
Whenever I set the number any higher than 2048, I get, an error that says:
shmget: Invalid argument
However when I run cat /proc/sys/kernel/shmall, I get 4294967296.
Does anybody know why this is happening? Thanks in advance!
The comment from Jerry is correct, even if cryptic if you haven't played with this stuff: "What about this: EINVAL: ... a segment with given key existed, but size is greater than the size of that segment."
He meant that the segment is already there - these segment are persistent - and it has size 2048.
You can see it among the other ones with:
$ ipcs -m
and you can remove your segment (beware: remove your one only) with:
$ ipcrm -M <key>
After that you should be able to create it larger.
man 5 proc refers to three variables related to shmget(2):
/proc/sys/kernel/shmall
This file contains the system-wide limit on the total number of pages of System V shared memory.
/proc/sys/kernel/shmmax
This file can be used to query and set the run-time limit on the maximum (System V IPC) shared memory segment size that can be created. Shared memory segments up to 1GB are now supported in the kernel. This value defaults to SHMMAX.
/proc/sys/kernel/shmmni
(available in Linux 2.4 and onward) This file specifies the system-wide maximum number of System V shared memory segments that can be created.
Please check you violated none of them. Note that shmmax and SHMMAX are in bytes and shmall and SHMALL are in the number of pages (the page size is usually 4 KB but you should use sysconf(PAGESIZE).) I personally felt your shmall is too large (2**32 pages == 16 TB) but not sure if it is harmful or not.
As for the definition of SHMALL, I got this result on my Ubuntu 12.04 x86_64 system:
$ ack SHMMAX /usr/include
/usr/include/linux/shm.h
9: * SHMMAX, SHMMNI and SHMALL are upper limits are defaults which can
13:#define SHMMAX 0x2000000 /* max shared seg size (bytes) */
16:#define SHMALL (SHMMAX/getpagesize()*(SHMMNI/16))
/usr/include/linux/sysctl.h
113: KERN_SHMMAX=34, /* long: Maximum shared memory segment */