Back to Knowledege base

Identifying and Removing Redundant Xi-Text Jobs and Printers

What the queue deletes by itself, why a printer's state is no evidence of disuse, and the two-stage removal

Why Housekeeping Matters

Over time, Xi-Text systems accumulate jobs that are no longer needed and printers that are no longer in service. Retained jobs occupy slots in the shared-memory job table, old printer definitions clutter the display, and entries for decommissioned remote hosts cause the scheduler to attempt connections that will never succeed. Regular housekeeping keeps the system manageable and helps administrators focus on what is actually in use.

This article walks through the process of exploring what is on the system, deciding what can be removed, and safely carrying out the cleanup. It also states plainly, in each case, what evidence the product actually holds for the judgement being made, because for printers that evidence is much thinner than it looks.

Exploring the Job Queue

The sqlist command is the primary tool for reviewing jobs. By default its output is terse, but the -H flag adds column headings and the -F format option lets you choose exactly which fields to display.

A useful format for housekeeping purposes includes the job number, owner, title, form type, submission time, retain flag, and the two deletion timeouts:

sqlist -H -F "%N %u %h %f %W %q %t %T"
Format codeMeaning
%NJob number (host:number for a job owned by a remote machine)
%uUser who submitted the job
%hJob title
%fForm type
%WSubmission time, as dd/mm/yyyy hh:mm
%qRetain on queue flag - prints the word retain when set
%tDelete time if printed (hours)
%TDelete time if not printed (hours)
%PThe printer the job asked for

Case matters: %p is the priority, not the printer, and %T and %t are two different timeouts.

To restrict the view, add -q for the printer the job asked for, or -u for the owner:

sqlist -H -q "oldprinter*" -F "%N %u %h %W"
sqlist -H -u fred -F "%N %h %W %t"

Read -q carefully before relying on it. The value a job carries in its printer field is itself a pattern, not the name of the printer that will print it, and -q asks whether the job's pattern is contained within the one you gave. Jobs that named no printer at all - which is the common case - are included unless you add -Z. So -q answers "which jobs restricted themselves to this printer", never "which jobs will print here".

To separate jobs that have printed from those that have not, use -y for unprinted, -p for printed, and -Y for both. There is no format code for a printed flag, and an Xi-Text job has no state field of any kind.

For a fuller picture of an individual job, use spq and press O on the job to open the Other Options screen. This shows all attributes including whether the job has been printed, the hold time, the deletion timeouts, and the page reached if printing was interrupted.

One caveat that applies to every listing in this article: sqlist and spq show only jobs whose class code intersects your own. An administrator with a narrow class code can be looking at an incomplete queue with nothing to indicate it. Check your own class code before concluding that a job is absent.

How Jobs Leave the Queue by Themselves

Xi-Text deletes jobs on a timer, and understanding the timer changes which jobs are worth looking at.

Every job carries two timeouts in hours: one that applies once it has printed (%t, default 24) and one that applies while it is still unprinted (%T, default 168, one week). The scheduler periodically computes the deletion moment as the job's submission time plus the applicable timeout, and deletes any job that has passed it, notifying the owner by mail or by a write message.

Two consequences follow, and both contradict the intuition:

  • A timeout of zero means delete at the next sweep, since the deletion moment then equals the submission time. It does not mean "keep for ever".
  • Retaining a job does not make it permanent. When a retained job finishes printing, the scheduler resets its submission time to the current moment, which restarts the printed-job clock. The job then survives for %t hours after it last printed, and is deleted after that.

Useful side effect: for a retained job that has printed, %W is the time it last printed, not the time it was submitted. It is the closest thing Xi-Text has to a per-job last-used timestamp, and unlike the equivalent field in Xi-Batch it carries a four-digit year.

So a job that has genuinely been on the queue for months has had its timeout raised deliberately - the fields are 16-bit, so the ceiling is 65535 hours, about seven and a half years.

Identifying Stale Jobs

With the timer in mind, these are the patterns worth reviewing.

Jobs with long deletion timeouts
Sort on %t and %T. A job set to wait a year before automatic deletion was almost certainly given that value to stop it disappearing, and the reason may no longer apply. Check with the owner before removing.
Unprinted jobs with old submission times
%W carries the year, so this judgement can be made with confidence. A job that has been unprinted for longer than its %T value should already have gone, so its presence means either a very long timeout or a spooler that has been down.
Jobs that can never be selected
A job whose copy count is zero will never print and nothing reports why. So will a job whose class code intersects no printer's. Check both:
sqlist -H -Y -F "%N %u %h %c %C %P"
splist -H -F "%p %t %c %f"

%c on a job is the copy count and %C its class code; %c on a printer is the printer's class code. A zero in the job's %c column, or a class code sharing no letter with any printer, is a job that will sit for ever.

Jobs targeted at printers that no longer exist
Compare the %P column against the printer names in splist. A job restricted to a pattern that matches nothing will never print.

Exploring Printer Status

The splist command shows all printers known to Xi-Text:

splist -H

The default output shows the printer name, device or network address, state with any message, the job number being printed and its owner. For housekeeping, ask for the fields the decision needs:

splist -H -F "%p %d %f %t %c %y %z"

That is printer name, device, form type, state, class code, minimum job size and maximum job size. Note that %t is the state on its own and %s is the state followed by any message from the device; %p is the printer name and %d the device.

The state names are printed in lower case, and there are eight of them: offline, error, halted, startup, idle, shutdown, printing and a/w oper. The three that matter here are:

halted
The printer is stopped. This is also the state every printer is put into when the spooler restarts, so a halted printer says nothing on its own about whether it is in use.
error
The printer's daemon reported a problem. This state is recoverable - a printer in error is restarted with spstart, and the condition is frequently a paper jam or a cable rather than a decommissioned device.
offline
The device reported itself offline. As with error, this is a live condition rather than a verdict.

None of the three is evidence that a printer is redundant. They tell you the printer is not working now.

Checking Remote Hosts

In a networked installation some printers belong to other machines. They appear in splist with the owning host prefixed to the name, such as kira:hp5, and they cannot be deleted from here - only from the host that owns them.

The remote hosts are listed in the Xi-Text host file, by default /etc/xi/text-hosts. Review it to see which hosts are configured and with which flags.

Connection and disconnection are operator commands, and both take a host name:

spconn kira
spdisconn kira

Both require the privilege to start and stop the spooler. Note that spconn starts the local spooler first where it finds it stopped, so on a machine you have deliberately quiesced it has a side effect beyond the connection itself.

A host that is no longer on the network can be removed from the host file, which stops the scheduler attempting to connect to it when it next starts. Disconnect it cleanly with spdisconn first.

Printer Log Files: the Only Usage Record

Xi-Text records no last-used time for a printer anywhere. The printer record in shared memory and in spshed_pfile has no time field at all; the report file records only failures; and the files in a printer's definition directory are written when the printer is defined and never touched again. A printer that last printed in 1998 is indistinguishable, from every file the product maintains, from one that printed five minutes ago.

The single exception is an opt-in per-printer log, enabled by a logfile keyword in the printer's setup file. Where it has been configured, the printer daemon appends one line for every job it completes, giving the date, start and finish times, user, title, form type, characters, device, printer name, priority, pages and job number.

Each printer has its own directory under the printers directory, by default /var/spool/xi/printers. Within it, .device holds the interface settings, a file named after the form type holds that form's setup, and default is the fallback used when no form-specific file exists. The logfile keyword can be in any of them, so check all three:

grep logfile= /var/spool/xi/printers/printername/.device \
              /var/spool/xi/printers/printername/default \
              /var/spool/xi/printers/printername/*

A relative path given to logfile is resolved against that printer's own directory. Inspect the most recent entries:

tail -20 /var/spool/xi/printers/printername/<logfile>

Two limits on what this can tell you. The log line carries a day and a month but no year, so the age of the last entry has to come from the file's own modification time. And different form types can write to different log files, so a printer used with several forms may have several logs.

Determining printer activity is covered in full in its own article; the short version for housekeeping is that where no log was configured, no evidence exists, and the decision has to be made from the site's own records instead.

Backing Up Before Cleanup

Before removing anything, take a copy. Xi-Text ships three converters that read the spooler's binary state files and write shell scripts of the commands that would recreate them. On a packaged installation they carry an xt- prefix and are on the ordinary command path. The state files live in the spool directory, by default /var/spool/xi/spd.

Create somewhere to put the copies:

bkdir=/var/backups/xi/text/`date +%Y%m%d`
mkdir -p $bkdir/Scripts

Back up the jobs, giving the job file, the output script and a directory for the job data:

xt-cjlist -D /var/spool/xi/spd spshed_jfile $bkdir/Jcmd $bkdir/Scripts

Back up the printer installations and the user permissions:

xt-cplist -D /var/spool/xi/spd spshed_pfile $bkdir/Pcmd
xt-spuconv -D /var/spool/xi/spd spufile23 $bkdir/Ucmd

-D is required for xt-spuconv, which has no default source directory.

Jcmd is a script of spr commands that would resubmit every job, referring to the data files in the Scripts directory. Pcmd is a script of spadd commands that would reinstall every printer. Ucmd is a script of spuchange commands that would restore the privilege table, with the system default entry first.

Pcmd does not back up your printers. It records only the installation - the name, device, form type, class code and description that spadd needs. Everything that makes the printer work, which is the contents of its definition directory, is outside all three converters. Copy that separately:

cd /var/spool/xi/printers && tar cf $bkdir/printers.tar .

These scripts can be edited before restoration if you only need to recover specific items.

Safely Removing Jobs

Once you have confirmed a job is no longer needed, it can be removed in two ways.

Using spq interactively
Navigate to the job in the job list and press A to abort and delete it. If the job has not been printed you are asked to confirm. If it is currently printing, the print run is aborted.
Using sqdel from the command line
sqdel takes one or more job numbers, and a host:number pair for a job owned by a remote machine:
sqdel 15033 15034
sqdel kira:15040

By default sqdel refuses to delete a job that has not printed, reporting that the job has not been printed yet and returning a non-zero status. Add -y to override that. Deleting another user's job requires the appropriate privilege.

Taking a copy of individual jobs first
sqdel -u writes the job's data and a command file that would resubmit it, into the directory given by -D; adding -k leaves the queue entry in place. This is the right step when you are unsure, and it requires the unqueue privilege. The same operation is on the U key in spq, with C to copy without deleting.

For bulk work, list the job numbers with the heading suppressed and pass them on:

sqlist -N -u olduser -F "%N"

Safely Removing Printers

Printer removal is a two-stage process: first take the printer out of the running spooler, then remove its definition files. The two stages are separate because the first is reversible from the backup above and the second is not.

  1. Stop the printer. In spq, on the printer list, h halts it at the end of the current job and H stops it at once. From the command line the equivalents are sphalt and spstop, both taking the printer name:
sphalt oldlaser
  1. Remove it from the spooler with spdel:
spdel oldlaser

spdel requires the add/delete printers privilege, refuses a printer that is still running, refuses a remote printer, and will only take one printer at a time. In spq the same operation is the D key on the printer list, with a confirmation prompt and the same three conditions.

At this point the printer is gone from splist but its definition directory is untouched, so the printer can be reinstated with a single spadd. That is the state to leave things in until you are certain.

  1. When you are certain, remove the definition directory:
rm -rf /var/spool/xi/printers/oldlaser

Check first whether the directory is a symbolic link, which is how a cloned printer is defined - removing the target of a clone breaks the clone. Removing a definition directory needs root.

The interactive Ptrinstall program performs all of this from a menu, and is the supported route on any installation that has Perl. It must be run as root.

Shared Memory

The job and printer tables live in shared-memory segments whose initial sizes are the two positional arguments to spstart when it starts the spooler; the packaged unit passes 2000 jobs and 50 printers. Neither is a hard ceiling - the spooler allocates a larger segment when a table fills - but Xi-Text writes nothing to the report file when it does so, so a growth is invisible except as a changed size in ipcs output.

Deleting jobs and printers returns their slots for reuse at once. The segments themselves do not shrink until the spooler is stopped and started again, and the sizing arguments take effect only when the spooler is not already running.

Housekeeping Checklist

A periodic review - quarterly or before major upgrades - should cover the following.

Check your own class code first
Otherwise the queue you are reviewing may not be the whole queue.
Review the deletion timeouts, not just the dates
Most jobs clear themselves. The ones that do not have been given a long timeout, and that is the field to look at.
Look for jobs that can never print
Zero copies, an unmatched class code, or a printer pattern that matches nothing.
Review printers against the site's records
The product holds no usage history unless logfile was configured, so this step is a conversation rather than a query.
Check the host file
Confirm every host listed is still in service, and disconnect cleanly before editing the file.
Back up before removing
All three converters plus a tar of the printers directory. The converters alone do not preserve a working printer.
Document changes
Keep a record of what was removed and why, for audit purposes and in case something needs to be restored.
Notify users
If removing jobs belonging to other users or printers used by specific teams, inform them beforehand.

Best Practices

Schedule housekeeping during quiet periods when the print queue is not heavily loaded. Avoid removing printers whilst they are printing, since that aborts the current job.

Leave a decommissioned printer at the spdel stage for a while before deleting its definition directory. Reinstating it is one command until the directory goes, and a rebuild afterwards.

When decommissioning a remote host, disconnect it with spdisconn before removing its entry from the host file.

Enable logfile on every printer as a matter of course. It is the only usage record Xi-Text can produce, it costs almost nothing, and its absence is what turns the next housekeeping review into guesswork.

Stopping and Starting All Xi-Text Printers at Once
The pattern form that halts or starts every printer in one command, and the four things a restart does not bring back