2

I'm using the following commands to find Shared Memory Limits and Semaphore Limits in Linux.

To find Shared Memory Limits I used this command:

ipcs -lm

and I got the following output:

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 4194303
max total shared memory (kbytes) = 1073741824
min seg size (bytes) = 1

To find Semaphore Limits I used this command:

ipcs -ls

and I got the following output:

------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 32
semaphore max value = 32767

I don't know how to get this output in Solaris,HP-UX and AIX. I have searched lot in internet but I couldn't get the fine solution. Share your ideas to get this thanks in advance.

Kavi Chinna
  • 237
  • 2
  • 7
  • 18
  • Are you writing shell script or you need solution in C? Anyway, using sysctls in Linux may be easier: i.e. `cat /proc/sys/kernel/shmmax` will give you maximum shared memory segment. Speaking of Solaris, Solaris 10 introduces projects, so solutions for >= 10 and <10 will be different. Either way, may be trial-and-error approach is easier: `if error in shmget(100 GB) than shmmax is not enough` – myaut Apr 24 '15 at 08:19
  • Yes I am writing shell script – Kavi Chinna Apr 24 '15 at 09:36
  • I posted my knowledge about Linux & Solaris. I used to do that in AIX once, but there was long ago, so I made my post a wiki, hope someone will updates my post on AIX & HP-UX – myaut Apr 24 '15 at 11:29

2 Answers2

2

Trial and error

The simplest and more robust method is to probe if you can allocate these resources, i.e.:

int shmid = shmget(key, LARGE_BUFFER_SIZE, 0644 | IPC_CREAT);
void* data = shmat(shmid, NULL, 0);

if (data == (char *)(-1)) {
    /* Log an error and exit */
}

I.e. Oracle Database does that.

Linux

On Linux these limits are handled via sysctl:

$ /usr/sbin/sysctl kernel.shmmax
kernel.shmmax = 18446744073709551615
$ /usr/sbin/sysctl kernel.sem
kernel.sem = 250        256000  32      1024
             ^ SEMMSL   ^ SEMMNI

You can get sysctl parameters from /proc/sys:

$ cat /proc/sys/kernel/sem
250     256000  32      1024
$ cat /proc/sys/kernel/shmmax
18446744073709551615

Solaris before 10

In Solaris before 10 kernel parameters were used. They are set in /etc/system. You can get actual values from kernel, but only when shmsys and semsys modules are loaded (Solaris lazy-loads them on first syscall):

# modload /kernel/sys/sparcv9/semsys
# modload /kernel/sys/sparcv9/shmsys
# echo 'shminfo_shmmax/J' | mdb -k
shminfo_shmmax:
shminfo_shmmax: 800000
# echo 'seminfo_semmni/J' | mdb -k
seminfo_semmni:
seminfo_semmni: a0000003c

Note that I used /J modifier in mdb which dumps 8-byte in hexademical. On 32-bits builds, you're probably will need /X which dumps 4-bytes.

Solaris 10 and later

Solaris 10 introduced projects, that allow to set these limits with granularity of user or even a process. Use prctl to get appropriate limits:

# prctl -n project.max-shm-memory $$
process: 3451: bash
NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT
project.max-shm-memory
        privileged       474MB      -   deny                                 -
        system          16,0EB    max   deny                                 -
# prctl -n project.max-sem-ids $$
process: 3451: bash
NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT
project.max-sem-ids
        privileged        128       -   deny                                 -
        system          16,8M     max   deny                                 -
# prctl -n process.max-sem-nsems $$
process: 3451: bash
NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT
process.max-sem-nsems
        privileged        512       -   deny                                 -
        system          32,8K     max   deny                                 - 

priviliged values is what you seek

myaut
  • 11,174
  • 2
  • 30
  • 62
0

AIX

AIX doesn't have any commands that will output the IPC limits that you're looking for, unfortunately. At least none that I've ever found... I generally refer to this table and assume the lowest common denominator for the versions of AIX that I'm supporting.

If I was needing to programmatically detect limits in the shell, I'd just write a wrapper function/script that encapsulated the logic listed in the table, based on the detected version of AIX.

CoreyStup
  • 1,488
  • 13
  • 14