Sizing the Xi-Batch Job Environment
What a job slot holds, what it requires in memory, and what to do about "Too many strings in job"
Every Xi-Batch job is held in a slot of fixed size, and the slot carries the job's environment. This article says what the slot holds, how its size and the slot count set the memory the queue takes, and what to do when a submission is refused with Too many strings in job. It is one half of a pair: the slot count itself is set as described in Sizing the Xi-Batch Shared Memory Queue.
What a job slot holds
A slot is a fixed header followed by a string area. The header carries the job's owner, priority, load level, run times, conditions, assignments, permissions and command interpreter name. The string area holds everything of variable length:
- the command arguments, each with a 2-byte index entry;
- the environment variables, each as a name string, a value string and a 4-byte index entry;
- the file redirections, each with the file name it opens;
- the working directory;
- the job title.
Each string costs its length plus one byte, and the environment and redirection groups each start on a word boundary. The size of the string area is fixed when the product is built and differs between releases, so the figure for a given installation is read from that installation, as described under Finding the string space of an installation below.
The environment is the largest item by far. The submitting command captures the environment it was run from and stores it in the job, so a job submitted from an interactive login shell carries that shell's environment: on a current Linux distribution that is commonly 3,000 bytes or more before the arguments, directory and title are added. A job submitted from cron, from a script run with env -i, or from a shell that has been trimmed carries a few hundred.
The count of variables is limited as well as their size. A job holds at most 750 environment variables; a submission with more is truncated to the first 750 with the message Too many environment variables - truncated, and the job goes ahead.
The static environment file removes the common variables from every job
The submitting commands read /etc/xi/batch-env when they start. The file holds environment variable assignments, one per line, with blank lines and lines beginning # ignored:
PATH=/usr/local/bin:/usr/bin:/bin
LANG=en_GB.UTF-8
TERMCAP=
Before a job is stored, its environment is compared with the file:
- a variable whose name and value match a line in the file is left out of the job;
- a variable whose name appears in the file with an empty value (
TERMCAP=above) is left out of the job whatever its value; - every other variable is stored in the job.
When the job runs, the scheduler builds its environment from the file first and then applies the variables stored in the job, so the job runs with the file's values for everything that was left out. Each program reads the file when it starts. A change to the file applies to the next submission at once; the scheduler reads it at its own start, so the values it supplies to running jobs change at the next scheduler start.
A different file, or a list of files read in turn, is named with a BATCHENV line in /etc/xi/batchconfig:
BATCHENV:/etc/xi/batch-env,/etc/xi/batch-env.local
The file is read by the submitting user's own process, so it must be readable by every user who submits jobs. A file that cannot be opened is passed over without a message, and every job then carries its whole environment.
What the slot size means for memory and disk
The job segment in shared memory is the slot count multiplied by the slot size, plus a header and hash tables. A slot is the string area plus about 1,400 bytes of header. With a 3,000-byte string area a slot is about 4.4 KB, so the shipped service unit's 2,000 slots take about 9 MB and 20,000 slots take about 88 MB; a 4,608-byte string area makes a slot about 6 KB and 20,000 slots about 120 MB. The scheduler's saved queue file, /var/spool/xi/batch/btsched_jfile.xbjl6, is written as text and takes space in proportion to what the jobs hold.
The slot size in force on a system is the segment size divided by the slot count (the next section gives the steps). From 1.9.2 the scheduler reports the count at start-up in /var/spool/xi/batch/btsched_reps:
Job list 2000 slots, variable list 500 slots (shm keys 0x5869b002 job, 0x5869b003 var)
and the bytes column of ipcs -m gives the segment size for the key named there. A segment of 87,860,052 bytes for 20,000 slots is 4,393 bytes a slot; the string area is that figure less some 1,400 bytes of header and hash table.
Every job in the segment occupies a full slot, however small the job. The way to use less memory for the queue is a smaller slot count, as described in Sizing the Xi-Batch Shared Memory Queue; the slot size is fixed for a release.
Finding the string space of an installation
The string space is the byte count a job's strings must fit in. No command reports it. It is worked out from the scheduler's own figures, on every release.
- Read the slot count from the start-up line in
/var/spool/xi/batch/btsched_reps:Job list 2000 slots. The count is the figure in force, which can differ from the one requested. - Read the byte size of the job segment from
ipcs -m, for the key named in the same line (0x5869b002in the example). It is the segment whose size is not the variable segment's. - Divide the size by the slot count. The result is the slot size in bytes.
- Subtract about 1,400 bytes. The remainder is the string space, to within the accuracy of the subtraction.
A segment of 87,860,052 bytes for 20,000 slots gives 4,393 bytes a slot and a string space of about 3,000 bytes. The figure is compared with the environment of the shells that submit, so an accuracy of a few tens of bytes is enough.
The calculation assumes a single job segment. Where a growth has just replaced one, use the segment at the key named in the newest line of btsched_reps.
What happens when a job does not fit
A job whose strings exceed the area is refused at submission. btr prints:
Too many strings in job. This is almost certainly because you
have a very large environment table (please run the command
"env" or "printenv" from the command line to see) and there
is too much data there to store in a single job structure.
and exits with status 253. Nothing is queued. The same message comes from btjchange when a change to a queued job's environment, arguments or redirections takes it over the limit, and from btq when a job is edited there.
What to do
Measure the environment the job is carrying
From the shell the submission is made from:
printenv | wc -c
printenv | wc -l
The first figure is the bytes the environment needs before the file is applied; the second is the variable count against the limit of 750. Compare the first figure with the string space of the installation. An environment that approaches it leaves no room for the arguments, directory and title, and is the cause of the refusal.
Put the common variables in the static environment file
Take the environment of a representative login as the starting point:
printenv | sort > /etc/xi/batch-env
chmod 644 /etc/xi/batch-env
Then edit the file. Variables that are the same for every user and every session stay as they are: PATH, LANG, TZ, the product's own variables, and whatever the site sets for all logins. Variables that describe a terminal session - TERMCAP, LS_COLORS, DISPLAY, SSH_CLIENT, SSH_CONNECTION, SSH_TTY, WINDOWID, XDG_SESSION_ID and their like - are of no use to a batch job and are removed from every job by leaving the name with an empty value:
TERMCAP=
LS_COLORS=
SSH_CONNECTION=
Variables that differ by user, such as HOME, USER and LOGNAME, are deleted from the file so that each job carries its own. The file applies to the next submission.
Trim the submitting shell
Where the file cannot be changed, remove the variables from the shell before submitting:
unset TERMCAP LS_COLORS
btr myjob
or submit with an environment built for the purpose:
env -i PATH=/usr/local/bin:/usr/bin:/bin HOME=$HOME btr myjob
Check the result
Submit again and check the exit status:
btr myjob; echo $?
The submission has worked when the status is 0 and the job appears in btjlist.
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