Understanding Printer States
An Xi-Text printer is always in one of eight states, and the product prints their names in lower case: offline, error, halted, startup, idle, shutdown, printing and a/w oper. Three of them - halted, offline and error - are states in which the printer is stopped and has no process of its own running. See Managing Xi-Text Printer States and Operations for the full list and for what moves a printer between them.
error means the printer met something it could not proceed past, reported it and stopped. Two things about it are worth knowing before you start:
- It is recoverable. Xi-Text treats halted, offline and error identically when you start a printer, so spstart is all that is needed once the underlying fault is fixed. Halting an error-state printer first does nothing at all - it is already stopped.
- Only a running printer can enter it. A halted printer has no process to detect a fault, so a printer never moves from halted to error on its own.
The companion article Distinguishing the Xi-Text offline State From error covers the difference between error and offline, and how to tell which one you are looking at.
Common Causes of Error State
Most error states arise while the printer is starting, when it reads its setup files and opens its device. The rest arise while it is printing.
At startup - setup files:
- The printer has no directory of its own in the printers directory, or that directory is not accessible to the spooler account.
- The directory contains no usable setup file - no .device, no file named for the paper type, and no default.
- A parse error in .device or in the paper-type setup file.
- An align file that cannot be read, an execalign command that cannot be executed, or a record or logfile entry naming a file that cannot be opened.
- A printer defined as a network device whose setup files carry no network line, or a printer defined as a local device whose setup files carry one. Either way round stops the printer.
At startup - the device:
- The device cannot be opened for writing by the spooler account.
- The device is neither a character device nor a FIFO. A regular file or a directory is refused.
- A portsetup or stty command in the setup file failed.
While printing:
- A write to the device failed.
- A bannprog banner program could not be run.
- Any of the startup faults above, met again. The setup files are re-read whenever a selected job's form type differs from the printer's current one, so an edit that broke a file surfaces at the next form-type change rather than when it was saved.
Network printers only:
- The network transport process crashed, dumped core, appeared to hang, or was lost. These four are the only causes that put an explanatory message on the printer display alongside the state name.
- The transport exited with a non-zero status, which is the default mapping, or died on a signal other than SIGHUP or SIGPIPE. A setup file can change either mapping - see Distinguishing the Xi-Text offline State From error.
Internal failures: a printer that loses contact with the spooler's shared memory, or that is sent a request it cannot interpret, also stops in error. So does a printer whose process dies untidily - the spooler notices the death and sets the state itself, in which case there is nothing in the log from the printer.
One thing that does not cause an error state: an ordinary job filter exiting with a non-zero status. That produces an error report against the job and the printer carries on with the next one.
Diagnostic Approach
Step 1: Check System Log
Xi-Text writes printer diagnostics to the report file in the spool directory:
# View system log
tail -50 /var/spool/xi/spd/spshed_reps
# Or from spq (X command)
# In spq, switch to the printer screen, press X
Entries carry a header line, a row of equals signs, and the message. A setup-file entry names the file that was being read when the fault occurred, which is the only way to tell .device from the paper-type file:
SPDI: /var/spool/xi/printers/ptr1/a4.ps: 14:22:05 06/02
==============
Error near line 12 - probable undefined name `netwrk'.
Other messages you will meet, in their exact wording:
Open of /dev/lp0 gave error - Permission denied
Invalid device name /var/tmp/printout
Error on output - Input/output error
Network printer ptr2 (addr/dev srv:9100)
does not have network command specified or non-network printer does
Network filter process (/usr/libexec/xi/xtelnet) terminated with exit code 1
Cannot run banner program `/usr/local/bin/banner'
Two things about the log matter more than the individual messages:
- A successful start writes nothing. There is no "printer started" entry. Silence for a printer means it started cleanly, so the entries you find are the failures and nothing has to be filtered out.
- A printer stopped by the spooler leaves no entry at all. If a printer sits in error with no message anywhere near the time it stopped, its process died rather than reported.
Step 2: Check Printer Configuration
View printer details:
# Show one printer in the default format
splist ptr1
# Show its name and device only
splist -F "%p %d" ptr1
A device shown in angle brackets, as <srv:9100>, is a network address rather than a file, and the printer is a network printer.
Verify:
- The device is the one you expect, and for a local printer it names a file that exists
- The printer has a directory of its own under the printers directory
- That directory holds a setup file for the printer's current form type, or a default
- The directory and its files are owned by the spooler account
Step 3: Examine Setup Files
Setup files define how Xi-Text communicates with the printer. They live in a directory named for the printer, under the printers directory:
# Everything the printer has, including dot files
ls -la /var/spool/xi/printers/ptr1/
# The two files that are read
cat /var/spool/xi/printers/ptr1/.device
cat /var/spool/xi/printers/ptr1/a4.ps
The default location is /var/spool/xi/printers; a site that moved it has SPOOLPT set in /etc/xi/textconfig.
Mistakes that stop a printer, and the form each takes:
- A misspelled keyword. An unrecognised word followed by = is accepted as a symbolic-name definition and does nothing; the same word with no = after it gives "probable undefined name".
- An unquoted value on a string keyword. The keywords that build a string sent to the printer - setup, halt, docstart and the rest - take a quoted string or a previously defined name. Anything else, an escape sequence written directly after the keyword for instance, silently ends the parse, and every line after it in both files is discarded with no message anywhere. The keywords that name a command to run - filter, network, portsetup, stty, exec - are the exception: they take an equals sign and then the rest of the line, unquoted.
- An equals sign after a numeric keyword. Numeric settings are written as a keyword and a value separated by a space, so a line such as baud=9600 gives "Number expected".
- An unclosed conditional block. Gives "Expected a `}'".
An unmatched quote raises no error: the string simply runs to the end of the line. See Xi-Text Printer Setup Files for the keywords and the full syntax.
Step 4: Check the Device
Xi-Text opens the device for writing as the spooler account, and accepts only a character device or a FIFO:
ls -l /dev/lp0
# crw-rw---- 1 root lp 6, 0 Feb 6 10:00 /dev/lp0
The first character of the mode must be c for a character device or p for a FIFO, and the spooler account must have write permission through the owner, group or other bits. A regular file is rejected with "Invalid device name", however permissive its mode.
Writing to the device from a shell is a last resort. While a printer is running, its own process holds the device open, and bytes written from a shell interleave with the print stream; on a serial line they are also sent with whatever settings the shell inherited rather than the ones the setup file establishes. If you do test a write, halt the printer first, and put the redirection inside the command so that it runs under the spooler account and not under your own:
sphalt ptr1
su spooler -c 'echo test > /dev/lp0'
spstart ptr1
Expected: the command completes and the text reaches the printer, possibly held until the next form feed.
If it fails: the permissions or the ownership are the fault, and the message will say which.
Do not use this test on a network printer. Its device field is an address rather than a file, and the connection is made by a separate transport program.
Resolving Common Error Scenarios
Scenario 1: Permission Denied on Device
Symptom:
Open of /dev/lp0 gave error - Permission denied
Cause: the device file is not writable by the spooler account.
Solution:
Check the device:
ls -l /dev/lp0
# crw-rw---- 1 root lp 6, 0 Feb 6 10:00 /dev/lp0
Give the account access to the device, rather than opening the device to everyone:
chown spooler /dev/lp0
chmod 600 /dev/lp0
On systems where device nodes are created afresh at each boot, make the change wherever they are created, or it is lost at the next restart.
Then start the printer. There is no need to halt it first:
spstart ptr1
Scenario 2: Device File Doesn't Exist
Symptom:
Open of /dev/lp0 gave error - No such file or directory
Cause: the printer's device field names a path that is not there.
Solution:
Find out what the printer is actually set to, and what exists:
splist -F "%p %d" ptr1
ls -l /dev/lp*
Device names differ between platforms - a serial port is not called the same thing on Linux, Solaris, AIX and HP-UX - so confirm the correct name for the system in front of you before changing anything.
The device is a property of the printer, held by the spooler, and is not set in the setup files: there is no device keyword to edit. Change it with spchange, on a halted printer:
sphalt ptr1
spchange -v /dev/ttyS0 ptr1
spstart ptr1
spchange needs the add and delete printers privilege, which ordinary users do not have by default.
Scenario 3: Syntax Error in Setup File
Symptom:
SPDI: /var/spool/xi/printers/ptr1/a4.ps: 14:22:05 06/02
==============
Error near line 12 - probable undefined name `netwrk'.
Cause: a misspelled or unrecognised keyword.
Solution:
Edit the file the log names - it is the file that was being read when the fault was met, which may be .device rather than the paper-type file:
vi /var/spool/xi/printers/ptr1/a4.ps
Correct line 12. In the example, netwrk should be network, which names the transport program to run for a network printer:
network=/usr/libexec/xi/xtelnet -p 9100 -h $SPOOLDEV
Then start the printer and check the log again:
spstart ptr1
tail /var/spool/xi/spd/spshed_reps
A clean read adds nothing to the log, so no new entry is the result you want. Starting the printer is the only way to check a setup file: there is no separate syntax checker.
Scenario 4: Network Printer Not Reachable
Symptom: the printer stops with a message naming the transport program:
Network filter process (/usr/libexec/xi/xtelnet) terminated with exit code 1
or, where the setup file captures the transport's own output, the printer's state carries the reason after a colon:
splist ptr2
ptr2 <srv:9100> a4.ps error:Connection refused
Cause: the print server or terminal server is not answering.
Solution:
The address is the printer's device field, shown in angle brackets, and the setup file's network line names the program that makes the connection. Read both before testing anything:
splist -F "%p %d" ptr2
grep network /var/spool/xi/printers/ptr2/.device
Test reachability from the spooler host:
ping srv
telnet srv 9100
If the host answers but the port does not, check that the printer is powered on and on the network, that its address has not changed, that the port number is the one the device actually listens on, and that no firewall sits between the two.
If the address has changed, correct it on the printer rather than in the setup file:
sphalt ptr2
spchange -v newsrv:9100 ptr2
spstart ptr2
By default any non-zero exit from the transport puts the printer into error, and a transport killed by SIGHUP or SIGPIPE puts it into offline. A setup file can change either mapping with exit setoffline, exit seterror, signal setoffline and signal seterror. Distinguishing the Xi-Text offline State From error covers the rules and their traps.
Scenario 5: Filter or Banner Program Failed
Two different things are called filters, and only one of them stops the printer.
A job filter - the filter keyword - post-processes each job's output. If it exits non-zero, or writes anything to its standard error, Xi-Text records that against the job and moves on; the printer stays running. Look for the job's error report rather than in the printer log.
A network transport - the network keyword - carries the whole print stream to a network device, and can stop the printer. It does so unconditionally if it crashes, dumps core, appears to have hung, or is lost; and on an ordinary exit it does so for any non-zero status, unless the setup file has replaced that mapping.
A banner program - the bannprog keyword - stops the printer if it cannot be run at all:
Cannot run banner program `/usr/local/bin/banner'
Solution: run the program by hand as the spooler account, which is what Xi-Text does:
su spooler -c '/usr/local/bin/pdf-filter < /dev/null > /dev/null'
echo $?
Common causes are a path that is wrong or not executable by the spooler account, a missing dependency, and an argument the program does not accept. To take a filter out of service while you investigate, remove or comment out its line in the setup file and start the printer again:
vi /var/spool/xi/printers/ptr1/a4.ps
# Comment out the filter line:
# filter=/usr/local/bin/pdf-filter -options
spstart ptr1
Recovery Procedures
Basic Recovery Steps
- Read the log for the specific message
- Fix the underlying cause (permissions, setup file, device, network)
- Start the printer
spstart ptr1
There is no separate step to clear the error state. Starting a printer works from halted, offline and error alike, and halting one that is already in error does nothing.
Starting a printer is also silent about failure: the spooler starts it as a background process, so spstart reports success whether or not the printer got as far as idle. Check the result rather than the command:
splist ptr1
If Error Persists
Verify the spooler is running:
ps -ef | grep spshed
If it is not, start it. spstart with no printer name starts the spooler rather than a printer:
spstart
Test with a minimal configuration. A printer that starts on a bare setup file and a harmless device proves that the spooler, the account and the directory layout are sound, and narrows the fault to the real printer's own configuration:
# Create the printer's directory and an empty setup file
mkdir /var/spool/xi/printers/testptr
: > /var/spool/xi/printers/testptr/default
chown -R spooler /var/spool/xi/printers/testptr
chmod 755 /var/spool/xi/printers/testptr
chmod 644 /var/spool/xi/printers/testptr/default
# Add the printer with a device that always accepts output
spadd -l /dev/null testptr
# Start it
spstart testptr
splist testptr
spadd requires a device with -l and needs the add and delete printers privilege. Delete the test printer with spdel when you have finished with it.
Preventing Error States
Start the printer after every setup-file change. That is the only way to find out whether a file parses, and it puts the failure in front of you rather than in front of the next person to print. It matters more than it looks: the setup files are also re-read whenever a job arrives with a different form type, so a broken edit can drop a printer that has been running for days into error in the middle of a queue.
Watch the report file. A clean start writes nothing, so anything in the file is a fault:
tail -50 /var/spool/xi/spd/spshed_reps
Keep copies of the setup files outside the spool tree. They are ordinary text and are worth holding under change control, but keep the working copy the authority: files restored from a copy must be owned by the spooler account, or they will not be offered as paper types even though they can still be read.
Check network printers before they are needed. Take the address from the spooler rather than from the setup file, which does not hold it:
#!/bin/sh
# check-printers.sh - report any printer that is not running
splist -F "%p %s" | while read ptr state
do
case $state in
offline*|error*|halted) echo "$ptr: $state" ;;
esac
done
Document printer configurations:
- Device type and model
- Network address (if applicable)
- Special configuration requirements
- Common issues and solutions