Next Previous Contents

12. Job Processing

Much of the flexibility of the LPRng software is obtained from the ability to control the details of each step of job processing. The following section details each step in the processing of a job, and explains the printcap options used to control each operation.

Assume the pr printcap entry has the form:

pr
    :lp=/dev/lp  OR  :lp=rp@rm
    :sd=/var/spool/lpd/pr
    :lf=log
    :of=/usr/local/bin/lpf
    :if=/usr/local/bin/lpf

Assume that we have used the following command to print a set of files.

lpr -Ppr file1 file2

This will create a control file in the /var/spool/lpd/pr directory with the following contents (this is an example - in practice there may be minor differences between the example and an actual control file):

Hastart4.astart.com
J/tmp/file1 /tmp/file2
CA
Lpapowell
Ppapowell
fdfA002230astart4.astart.com
N/tmp/file1
UdfA002230astart4.astart.com
fdfB002230astart4.astart.com
N/tmp/file2
UdfB002230astart4.astart.com

12.1 Opening the Output Device

Options used:

Sequence of Operations:
  1. During the server operations, it will try to create temporary files in the print queue spool directory. If this is not desirable, it will create them in the server_tmp_dir directory.
  2. If the accounting file specified by af exists, it is opened (af_fd) and the af_fd is passed as file descriptor 3 to all filters. If the af value has the form af=|/program then the program is started and the program STDIN is used as af_fd. If the af value has the form af=host%port, then a TCP/IP connection to the corresponding port on the remote host is made and the port used as af_fd. In the latter two cases, the filter STDIN (file descriptor 0) is actually opened read/write, and is used when information is needed from the accounting filter or remote server. See Accounting Printcap Options for more information on the LPRng accounting support.
  3. If la (local accounting) is true and we are printing a job or ar (remote accounting) is true and we are transferring a job, the as value is examined. If it is a filter (program) specification, then the program is started with its STDIN attached to /dev/null, STDOUT will be read by the print spooler, STDERR output will be written to the error log, and file descriptor 3 output will be appended to the accounting file. The lpd program will wait until the accounting filter program terminates, and examine the error code for action, as for the filters (see errorcodes below). If the exit status is 0, (JSUCC) then the printing process will continue, if JHOLD the job will be held, if JREMOVE the job will be removed, if JFAIL the job processing will terminate with a JFAIL indication, otherwise the job processing will terminate with a JABORT indication.
  4. If the accounting filter exited with a JSUCC (no error code) and the achk (accounting check) flag is set, the line read from the accounting filter STDOUT will be examined. This line should be accept, hold, fail, remove, otherwise the job processing terminates with a JABORT indication. An accept will allow the job to be printed, hold will hold the job, fail will cause the job to fail, remove will cause the job to be removed.
  5. If the connect_grace value is non-zero and the server is opening a device or network_connect_grace is non-zero and a network connection is being made, the server will pause the specified time. This is to accommodate devices which need a recovery time between jobs.
  6. The lp option is checked to determine the type of IO device.

    Format
    Meaning
    /pathnameAbsolute pathname of IO device
    pr@hosttransfer to pr on remote host
    host%portopen a TCP/IP connection to port on host. host can be name or IP address
    |filterrun the filter program; it STDIN will be used as device
  7. The IO device specified by lp is opened write-only or read-write if the rw flag is true, and the resulting file descriptor is io_fd. If the nb flag is set, a non-blocking open will be done as well. If the lk (lock device) flag is true, the device will be locked against use by other LPD servers.
  8. If a host%port combination, a TCP/IP connection will be opened to the remote port and the connection will be used as io_fd.
  9. If a filter program is specified, the filter program will be run and the STDIN of the filter will be used as the device file descriptor.
  10. If a rp@rm combination, or none of the above combinations are true and the rm and rp values are non-zero, then the job will be transferred to a remote printer. The type of operation will be a job transfer, rather than printing operation.
  11. If the connect_timeout value is non-zero, a timeout is setup for the device or socket open. If the device or connection open does not succeed within the timeout, then the open operation fails.
  12. If a connection is to a network address (i.e. - connect() system call) and the connection attempt fails with an ECONNREFUSED error, if the retry_econnrefused flag is set then the connection attempt is retried, but this time using an alternative port number. See RFC1179 for details. This is repeated until all of the possible originating port numbers are exhausted.
  13. If the open or connect operation fails, and the retry_nolink flag is set, then the server will pause for a minimum of connect_grace plus a multiple of connect_interval seconds based on the number of attempts before retrying the open operation. Note that the interval may increase as the number of attempts increases.
  14. If printing a job and the of filter is specified, it is created with its STDOUT (fd 1) attached to the io_fd. Its stdin (of_fd) will be used in the steps listed below. If there is no of filter, then the of_fd value will be the io_fd descriptor.
  15. If transferring a job and the control_filter option is specified, then the program specified by the control_filter value will be run. It will have its STDIN set to the control file, and its STDOUT output will be used as the new value of the control file to transfer to the remote host. See Filter Command Line Flags for details of options passed to the control filter, and errorcodes for the exit codes of the filter.
  16. If the operation is a job transfer, the operation proceeds as outlined in RFC1179, and then the Normal Termination operations are carried out.
  17. If the operation is a print operation and the ld (leader on open) value is provided, the string is translated (escapes removed) and written to the of_fd file descriptor.
  18. If the fo (form feed on open) flag is true, then the ff (form feed) string is translated (escapes removed) and written to the of_fd file descriptor.

12.2 Printing Banner At Beginning

Options used:

Banner printing is one of the more complicated configuration options of LPRng. This is due mainly to historical evolution of the software, as well as a lack of a well defined standard for filter responsibilities. In the original BSD print spoolers, the philosophy was that banner printing should be delegated to the filters, as they were the most aware of the capabilities of the printers. This required an out of band method to convey banner printing information to the filter, and resulted in a complicated interface. The original interface was:

  1. The filter doing banner printing was invoked as a special of filter, or passed a special flag.
  2. The print spooling software would send a special single line of information telling it what the banner information should be. Note that this line was never documented except for the source code, and was inconsistent from version to version. Also, there was no indication of what to do with additional lines, if any.
  3. The filter would generate the banner, discard the line, and then pass other lines to the output device.

Adding to the confusion, the original print spoolers had a :sh (suppress header or banner) flag, which was supposed to suppress banner printing. It did this by having the print spooler not generate the magic banner information line.

A more sophisticated banner printing system would allow the print spooler software to generate the banner, and would then have the of filter act as a pass through. Thus, we need configure the of filter NOT to use the first line as banner printing information, and to pass through all information to the device.

Complicating this whole mess is the ld (leader option) and tr (trailer option) which is a string sent to the output device (of filter) when the device (filter) is initialized or terminated. This can sometimes be interpreted as the banner line, leading to unexpected results.

Sequence of Operations:

  1. If the sh (suppress header) flag is true, no banner is printed, and the actions in this section are skipped. No banner information line is generated for the of filter, and no banner printing program is invoked. If there is an of filter and it is expecting such a line and you have ld or tr information then you may get unexpected results (actually, catastrophic failure is a better term, but I digress).
  2. If the hl (header last) flag is true the banner is printed at the end of the job and the actions in this section are done at the end of the job.
  3. If the user does not want banner pages she can use the lpr -h option. This will cause the lpr program to delete the L (banner name) line in the control file. If there is no L line in the control file and ab (always print a banner) is false (the default), then no banner is printed and the other actions in this section are skipped. If ab is true and the L line is missing then the N (user login name) is used; if it is missing as well, then ANONYMOUS is used for the user name.
  4. If a banner printing program is specified by bp, ttbs, or be options, then LPRng will invoke the program to generate a banner and then send the generated banner to the printer via the of filter. The banner printing program will be invoked using the standard filter command line flags (see Filter Command Line Flags for details), with is STDIN attached to /dev/null and STDOUT attached to a file to hold the output banner.
  5. If no banner printing program is specified and the sb (short banner) option is TRUE (default is true), then the bl=... (banner line) option value is expanded and sent to the of_fd (of filter or device. The default bl value is: bl=$-'C:$-'n Job: $-'J Date: $-'t. Using our example, this will get translated to:
    papowell:A Job: file1 file2 Date: Thu Nov 27 23:02:04 PST 1997
    
  6. If no banner printing program is specified and we have sb@ (no short banner) then we skip banner generation, i.e. - we do not send a banner generation line to the output (of filter).
  7. If the queue is a normal forwarding queue, then the generate_banner option will invoke the bp, bs or be program as appropriate to create a banner page file which is then made the first (default) or last (hl flag or be=... present) file in a job. This option has no effect in other types of queues. See the translate_format option as well.

12.3 Printing Job Files

Options used:

Sequence of Operations: for each job in listed in the control file, the following operations are done in turn.

  1. If there is an of filter present, the suspend string \031\001 is written to of_fd and the no further action is taken until the of filter is suspended.
  2. The control file line for the job is examined, and the first letter of the data file specification is used as the format.
  3. If the format is p, the job is first processed by the program specified by the pr program, and the program output used as the print file.
  4. If the format is f, l, or p then the if filter is used, otherwise the keyword Xf is used. Note that certain formats such as p, a, l, may not be used as formats.
  5. The filter program is started with an appropriate set of command line options (see Filter Command Line Flags), and with its STDOUT attached to the printing device (io_fd), STDERR to a pipe which results in the output being written to the status file, and file descriptor 3 to the accounting file or program. If debugging is enabled, then the STDERR output is also written to the error log file (lf).
  6. When doing a read/write operation to a device or remote system, a timeout can be specified. When doing a print or job transfer operation, the send_job_rw_timeout value is used. When doing a status or query operation, the send_query_rw_timeout value is used. If a write or write operation does not complete within the specified timeout seconds, then we have an error condition and job processing or the query operation is terminated with JFAIL status. If the timeout value is 0, then no timeout is done.
  7. lpd will then wait for the filter to exit. The exit status can be as follows:
    Key      Value   Meaning
    JSUCC    0       Successful
    JFAIL    1, 32   Failed - retry later
    JABORT   2, 33   Abort - terminate queue processing
    JREMOVE  3, 34   Failed - remove job
    JHOLD    6, 37   Failed - hold this job
    Other            Abort - terminate queue processing
    
  8. If the filter exit status was JSUCC (0), or no error indicated, then processing will continue otherwise the job termination takes (see Abnormal Termination).
  9. If the of filter is present, then it is reactivated with a kill -CONT signal.
  10. If the sf (suppress FF print file separators ) is false, then the ff (form feed) string will be interpreted and sent to the of_fd.

12.4 Printing Banner At End

Options used:

The actions taken in this step are identical to those for the Printing Banner At Beginning, with the exception that the be (end banner program) is used to select the banner generation program rather than the bs (start banner program).

If we have hl true, then we print a banner at the end of the job, rather than start.

12.5 Normal Termination

Options used:

Sequence of Operations:

  1. If we are printing and the fq flag is set and the sf (suppress interfile FF) flag is set, then the ff (form feed) string will be interpreted and sent to the of_fd.
  2. If we are printing, the tr (trailer) string will be interpreted and sent to the of_fd.
  3. If printing and the la (local printer accounting) flag is set or transferring a job and the ar (remote accounting) flag is set, the ae is examined and accounting is done as described for the as field.
  4. If the of filter is present, its STDIN is closed, and the lpd server waits for it to exit. The exit status is used as described above.
  5. If the device is a socket or network connection, the socket linger time is set to job_send_rw_timeout value if nonzero or the exit_linger_timeout value if nonzero, a write shutdown is done, and if the wait_for_eof option is true (default) then a read is done on the connection until an EOF is found. The device (io_fd) is then closed.
  6. The job is marked as completed in the spool queue.
  7. If the save_when_done flag is not specified, the job is removed.

12.6 Abnormal Termination

Options used:

If the job processing terminates abnormally, the following sequence of events occurs:

  1. The job is marked as having an error during processing.
  2. The LPD server will attempt to kill all filters and other associated processes by sending a SIGINT and SIGCONT (kill -INT and kill -CONT) to them.
  3. If there is a mail_operator_on_error value, the specified operator will be mailed an error indication. The sendmail option specifies the pathname of the sendmail program and the options needed to have it read mail addresses from its standard input. For example, sendmail=/usr/sbin/sendmail -oi -t is a commonly used set of options.
  4. The mail_from value specifies the user name used for mail origination. If not specified, the default is to use the print spool queue or printer name.
  5. If there is a send_failure_action specified, then it is decoded and the corresponding action taken. If the value is remove, hold, abort, or retry, then the job is removed, held, aborted, or retried. If the value is |/program, the program is executed and the number of attempts are written to the filter STDIN. The exit status of the filter will be used to determine the consequent actions. That is, JSUCC (0) will be success, and the standard success action will be taken; JFAIL will cause retry, JREMOVE will cause the job to be removed, JHOLD will cause the job to be held, JABORT or other status will abort processing.
  6. If the status is ABORT and the stop_on_abort flag is set, then further processing of jobs is terminated. The job is not removed from the queue.
  7. If the error status indicates removal, and the save_on_error flag is clear then the job is removed from the spool queue.
  8. If the error status indicates that no further operations should be performed on the queue, then the lpd server will stop processing jobs.
  9. If the error code indicated that the job should be retried, and the send_try value is 0 or the number of attempts is less than the send_try value, then the job is retried. Between each attempt to transfer a job to a remote site. This pause will double after each attempt, reaching a maximum of max_connect_interval seconds. If max_connect_interval is 0, there is no limit on the interval value.

12.7 LPD Spool Queue Processing

Options used:

When the lpd server starts, it will fork a set of subserver processes, each which will handle an individual queue.

If a system has a large number of queues, then this forking operation may result in the lpd server exhausting the process resources. To control this, the max_servers_active value restricts the number of active children to the specified value. If this value is 0, then 50% of the maximum system processes value will be used.

Due to the limits on the number of processes, there may be times when a job is placed in a queue, but the lpd server is unable to start handling the job. When all of the children of the main lpd server have exited, the server starts a timer. After lpd_poll_time seconds, it will scan the queues, looking for jobs to process, and starts a process to service them. If it does not find any jobs it remains idle.

The lpd_force_poll flag causes the server to periodically poll the queues. This is useful when there is a high possibility that jobs could fail to be printed due to high loads on the server.


Next Previous Contents