Sizing the Xi-Text Shared Memory Queue
What the start-up numbers allocate, when the segments grow, and what happens when they cannot
Xi-Text is allocated a fixed number of job and printer slots when the scheduler starts. This article says how to set that number, where to make the setting permanent, and how to read back what is allocated now. Set the number to cover your peak: the segments do grow when they fill, and after a growth of the job data segment the commands that read the queue can show stale contents until the scheduler is restarted.
The three shared memory segments
Xi-Text keeps its live queue in System V shared memory so that every command can read it without going through the scheduler. The segments are created when the scheduler starts and removed when it stops cleanly.
In normal operation there are three:
- a fixed-size job information segment holding the queue header and the job hash tables;
- a job data segment holding one slot per job;
- a printer segment holding the printer table.
A fourth appears briefly while a segment is being enlarged, and disappears again when the copy is finished.
The segments are sized at start-up and grow when the slots run out
The scheduler allocates a number of slots - jobs or printers - and the byte size of the segment follows from that number. When the slots run out, the scheduler creates a larger segment at the next key, copies the contents across and removes the old one. The copy runs with the queue locked.
Setting the initial allocation
spstart takes two positional numbers, in this order, and passes them to the scheduler. There is no -j option and no -p option.
spstart <jobs> <printers>
The shipped service unit runs:
/usr/local/bin/spstart 2000 50
A third number is a usage error. If either number is omitted or given as zero, the compiled-in default is used instead.
Making the setting permanent
The setting the product treats as the site's own is a system variable in the master configuration file, /etc/xi/textconfig. That file is read by every program, so the value applies however the scheduler is started. Editing the service unit or the start-up script works as well.
| Setting | Name in /etc/xi/textconfig |
|---|---|
| Initial jobs | NUMJOBS |
| Initial printers | NUMPTRS |
| Growth step, jobs | INCJOBS |
| Growth step, printers | INCPTRS |
Each line is a name, an equals sign and a value:
NUMJOBS = 20000
NUMPTRS = 200
The command-line values override the file, so a service unit that passes numbers wins over anything set here. Set the numbers in one place.
The compiled-in defaults are large
The compiled-in defaults are 100,000 jobs and 5,000 printers, well above the numbers the shipped service unit passes.
At start-up the scheduler sizes the segment from the saved queue file where that is bigger than the figure you asked for, so an installation recovering a large queue keeps all of it.
How much memory a slot count takes
A slot is a fixed-size structure, so the segment is roughly the slot count multiplied by the slot size, rounded up. Read the figures off your own system - the bytes column of ipcs -m is the actual allocation:
ipcs -m
Xi-Text's segments have keys beginning 0x58691.
The size column is a Linux one. Solaris, AIX and HP-UX print only the type, identifier, key, mode, owner and group by default; add -b there to get the segment size. ipcs -mb shows the size on all four platforms.
On a machine with a few gigabytes of memory the allocation is megabytes, so a figure that covers your peak comfortably takes a negligible share of it. Set the figure from your own peak.
What grows, when, and by how much
| Segment | Grows when | Grows by |
|---|---|---|
| Job data | A job is added and the slots are full | INCJOBS, by default half the initial-jobs default |
| Printer table | A printer is added and the slots are full | INCPTRS, by default half the initial-printers default |
| Job information | Never - it is fixed at start-up | - |
The default growth steps are derived from the compiled-in defaults, so they stay large at a site that passed small numbers. A site that starts with spstart 2000 50 and fills it grows by the full INCJOBS step. Set INCJOBS explicitly to change that.
Nothing is written to /var/spool/xi/spd/spshed_reps when a segment is enlarged, so the only evidence of a growth is a changed segment size in ipcs -m.
What happens when the slots run out
A failed allocation stops the product. Xi-Text has no "queue full" refusal on the job side: where a segment cannot be created or enlarged, the scheduler writes a message to /var/spool/xi/spd/spshed_reps and exits, taking printing with it. The messages to look for are:
Trouble creating shared memory id ...
Possibly some other software is using it all up, or the maximum shared
memory size allocated in your kernel is too small.
Trouble attaching job data shared memory - ...
Trouble attaching printer shared memory - ...
Failed to create job info shm segment - ...
The last of those is also the message you get when the previous shutdown was not clean and the segment is still present. Clear it with xt-ripc -d before restarting.
Commands can read stale contents after the job data segment grows
In the shipped release, the address published for readers after a growth is not always the address of the new segment; on Xi-Text this affects the job data segment. After a growth of that segment, commands that read the queue may show stale contents or fail to open it, until the scheduler is restarted.
Set the initial allocation to cover your peak, so that the segments do not need to grow in normal running. Restarting the scheduler with a larger initial figure is the reliable way to enlarge a queue.
Checking what is allocated now
List the segments:
ipcs -m
Identify them by key: 0x58691003, 0x58691004 and 0x58691005. Keys move up by two while a segment is being replaced, so a segment may appear at the next key up after a growth.
Filter by key. The segments are owned by root, so a filter on spooler finds nothing:
ipcs -m | grep 0x58691
The IPC tool names which segment is which:
xt-ripc
Check what the scheduler was started with:
ps -ef | grep spshed
Kernel parameters
Xi-Text does not read SHMMAX, SHMALL or SHMMNI, and it has no tuning file of its own. On a current Linux kernel the shared-memory limits are effectively unlimited by default and there is nothing to change; the allocations are megabytes.
Where a limit does apply - an older kernel, or a system where an administrator has lowered the limits deliberately - the behaviour is:
- If the kernel rejects the size as too large, the scheduler halves its request and tries again. You end up with fewer slots than you asked for, with no message.
- If the kernel is out of memory or out of segments, the request fails outright and the scheduler exits.
- If a segment already exists at the key, the scheduler steps to the next key and retries, up to fifty times. Stale segments from an unclean shutdown therefore do not usually block a start, though the client programs may attach to them; clear them with xt-ripc -d.
The other Unix platforms Xi-Text supports - Solaris, AIX and HP-UX - do have shared-memory limits that can be set low, and there the kernel's own documentation is the place to raise them.
Changing the allocation
A change to the initial allocation takes effect at the next start of the scheduler. Stop the product, change the figure, start it again.
sstop -y
spstart 20000 300
Make the same change in /etc/xi/textconfig or in the service unit, or the next reboot will go back to the old figure.
Confirm the new figure with xt-ripc, or by reading the bytes column for keys 0x58691003, 0x58691004 and 0x58691005 in ipcs -m.
Related articles
Sizing the Xi-Batch Shared Memory Queue
What the start-up numbers allocate, when the segments grow, and what happens when they cannot
Configuring Xi-Text Form Types, Paper Types and Suffixes
What a form type is, the exact rule matching a job to a printer, and how a suffix changes without stopping the printer
Controlling the Xi-Batch Job Start Rate with STARTLIM and STARTWAIT
Two settings that bound how many jobs the scheduler starts at once, where they live, and why a change needs a restart