This file is indexed.

/usr/share/doc/lprng-doc/LPRng-Reference-Multipart/x3593.htm is in lprng-doc 3.8.A~rc2-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
  <meta name="generator" content=
  "HTML Tidy for Linux/x86 (vers 6 November 2007), see www.w3.org">

  <title>Load Balance Queues and Printer Pools</title>
  <meta name="GENERATOR" content=
  "Modular DocBook HTML Stylesheet Version 1.79">
  <link rel="HOME" title=" LPRng Reference Manual" href=
  "index.htm">
  <link rel="UP" title="Print Spooling Tutorial " href=
  "tutorial.htm">
  <link rel="PREVIOUS" title="Holding and Releasing Jobs" href=
  "x3515.htm">
  <link rel="NEXT" title="Routing Jobs To Print Queues" href=
  "x3699.htm">
</head>

<body class="SECT1" bgcolor="#FFFFFF" text="#000000" link="#0000FF"
vlink="#840084" alink="#0000FF">
  <div class="NAVHEADER">
    <table summary="Header navigation table" width="100%" border=
    "0" cellpadding="0" cellspacing="0">
      <tr>
        <th colspan="3" align="center">LPRng Reference Manual: 24
        Sep 2004 (For LPRng-3.8.28)</th>
      </tr>

      <tr>
        <td width="10%" align="left" valign="bottom"><a href=
        "x3515.htm" accesskey="P">Prev</a></td>

        <td width="80%" align="center" valign="bottom">Chapter 4.
        Print Spooling Tutorial</td>

        <td width="10%" align="right" valign="bottom"><a href=
        "x3699.htm" accesskey="N">Next</a></td>
      </tr>
    </table>
    <hr align="left" width="100%">
  </div>

  <div class="SECT1">
    <h1 class="SECT1"><a name="AEN3593" id="AEN3593">4.17. Load
    Balance Queues and Printer Pools</a></h1>

    <p>A Load Balance Queue provides a way to use multiple printers
    for a single print queue. All jobs are normally sent to the
    main or load balance queue which then dispatches the jobs to
    <span class="emphasis"><i class="EMPHASIS">server</i></span>
    queues or printers that do the actual printing as they become
    available. You can also send jobs to the individual server
    printers if they have special processing or setups required for
    a particular job. Because all of the server printers are shared
    by the load balance queue, they are said to be in a
    <span class="emphasis"><i class="EMPHASIS">printer
    pool</i></span>.</p>

    <p>Edit the printcap file so it have the contents indicated
    below, create the <tt class="FILENAME">/tmp/lp2</tt> and
    <tt class="FILENAME">/tmp/lp3</tt> files with <tt class=
    "LITERAL">0777</tt> permissions, use <tt class=
    "COMMAND">checkpc -f</tt> to check the printcap, and then use
    <tt class="COMMAND">lpc reread</tt> to restart the <b class=
    "APPLICATION">lpd</b> server.</p>

    <div class="INFORMALEXAMPLE">
      <a name="AEN3605" id="AEN3605"></a>
      <pre class="SCREEN">
# printcap
lp:force_localhost
lp:server
  :sd=/var/spool/lpd/%P
  :sv=lp2,lp3
lp2:force_localhost
lp2:server
  :ss=lp
  :sd=/var/spool/lpd/%P
  :lp=/tmp/lp2
lp3:force_localhost
lp3:server
  :ss=lp
  :sd=/var/spool/lpd/%P
  :lp=/tmp/lp2
</pre>
    </div>

    <p>The <tt class="LITERAL">:sv=...</tt> option flags the queue
    as a load balance queue and lists the queues that are used for
    load balancing. The <tt class="LITERAL">:ss=...</tt> option
    flags the queue as a server for a load balance queue and
    specifies the name of the load balance queue. When a job is
    sent to the load balance queue the <b class=
    "APPLICATION">lpd</b> server checks to see which server queues
    are available and then the first one to become available.</p>

    <p>Execute the following commands to print the <tt class=
    "FILENAME">/tmp/hi</tt> file and observe the results:</p>

    <div class="INFORMALEXAMPLE">
      <a name="AEN3613" id="AEN3613"></a>
      <pre class="SCREEN">
<samp class="PROMPT">h4: {274} % </samp><kbd class=
"USERINPUT">lpq</kbd>
Printer: lp@h4  (subservers lp2, lp3)
 Queue: no printable jobs in queue
 Status: job 'papowell@h4+42' removed at 07:29:57.924
Server Printer: lp2@h4  (serving lp)
 Queue: no printable jobs in queue
Server Printer: lp3@h4  (serving lp)
 Queue: no printable jobs in queue
<samp class="PROMPT">h4: {275} % </samp><kbd class=
"USERINPUT">lpr /tmp/hi</kbd>
<samp class="PROMPT">h4: {276} % </samp><kbd class=
"USERINPUT">lpq</kbd>
Printer: lp@h4  (subservers lp2, lp3)
 Queue: 1 printable job
 Server: pid 4063 active
 Status: waiting for subserver to finish at 07:31:08.074
 Rank   Owner/ID           Class Job Files        Size Time
1      papowell@h4+62        A    62 /tmp/hi         3 07:31:07
Server Printer: lp2@h4  (serving lp)
 Queue: no printable jobs in queue
Server Printer: lp3@h4  (serving lp)
 Queue: no printable jobs in queue
<samp class="PROMPT">h4: {277} % </samp><kbd class=
"USERINPUT">lpq</kbd>
Printer: lp@h4  (subservers lp2, lp3)
 Queue: no printable jobs in queue
 Status: no more jobs to process in load balance queue at 07:31:12.317
Server Printer: lp2@h4  (serving lp)
 Queue: no printable jobs in queue
Server Printer: lp3@h4  (serving lp)
 Queue: no printable jobs in queue
 Status: job 'papowell@h4+62' removed at 07:31:10.311
</pre>
    </div>

    <p>The first <b class="APPLICATION">lpq</b> command shows how
    the status is displayed for a load balance queue - the queue
    and its server queues are shown as well. Next, we use <b class=
    "APPLICATION">lpr</b> to print a job (job id <tt class=
    "LITERAL">papowell@h4+62</tt>). We then use a couple of
    <b class="APPLICATION">lpq</b> commands to see how the job is
    first sent to the <tt class="LITERAL">lp</tt> queue, which then
    forwards it to the <tt class="LITERAL">lp3</tt> queue, which
    then processes it and removes it. (For purposes of
    demonstration we have artificially slowed down the operation of
    the load balance queue so that the jobs will remain in the
    queue for sufficient time for us to display their status.) We
    can send another job to the load balance queue:</p>

    <div class="INFORMALEXAMPLE">
      <a name="AEN3630" id="AEN3630"></a>
      <pre class="SCREEN">
<samp class="PROMPT">h4: {278} % </samp><kbd class=
"USERINPUT">lpr /tmp/hi</kbd>
<samp class="PROMPT">h4: {279} % </samp><kbd class=
"USERINPUT">lpq</kbd>
Printer: lp@h4  (subservers lp2, lp3)
 Queue: no printable jobs in queue
 Status: no more jobs to process in load balance queue at 07:37:17.953
Server Printer: lp2@h4  (serving lp)
 Queue: no printable jobs in queue
 Status: job 'papowell@h4+89' removed at 07:37:15.936
Server Printer: lp3@h4  (serving lp)
 Queue: no printable jobs in queue
 Status: job 'papowell@h4+81' removed at 07:36:40.116
</pre>
    </div>

    <p>This time we see that the job was put in <tt class=
    "LITERAL">lp2</tt>. The normal load balance queue operation is
    to use the server queues in round robin order.</p>

    <p>While this simple configuration is suitable for a large
    number of configurations, there are situations where server
    queue must be chosen <span class="emphasis"><i class=
    "EMPHASIS">dynamically</i></span>. For example, if the server
    queues are actually transferring jobs to remote clients then as
    soon as the job is sent to the remote client the queue appears
    empty and available for use. To correctly check to see if the
    queue is available, the status of the remote queue or
    destination of the server queue must be checked.</p>

    <p>To handle this situation, a <tt class=
    "LITERAL">:chooser</tt> program or filter can be used. When the
    load balance queue is trying to decide where to send a job, it
    first checks the server queues to see if they are enabled for
    printing. If a <tt class="LITERAL">:chooser</tt> program is
    specified in the load balance queue printcap entry, then it is
    started with the normal filter options and environment
    variables, supplemented as discussed below. The <tt class=
    "LITERAL">:chooser</tt> program will read a list of candidate
    queues from its <acronym class="ACRONYM">STDIN</acronym>, write
    the chosen one to its <acronym class=
    "ACRONYM">STDOUT</acronym>, and then exit. The <b class=
    "APPLICATION">lpd</b> server checks the <tt class=
    "LITERAL">:chooser</tt> exit code - if it is zero (successful)
    then the chosen queue is used otherwise the exit code is used
    for the result value of processing the job. This allows the
    chooser process to not only control the destination of the job
    but also to hold, remove, or abort the job handling process. If
    the <tt class="LITERAL">:chooser</tt> does not specify a queue,
    then the job is skipped and another job is chosen.</p>

    <p>One side effect of the using a chooser program is that while
    there are jobs that can be processed in the queue the <b class=
    "APPLICATION">lpd</b> server needs to periodically check to see
    if a server queue has become available. If it did this
    continually then a very high load would be put on the system.
    Instead, the <tt class="LITERAL">chooser_interval</tt> option
    specifies a maximum time in seconds (default 10 seconds)
    between the times that the <b class="APPLICATION">lpd</b>
    server checks to see if there is an available server.</p>

    <p>Normally, the <tt class="LITERAL">chooser</tt> is applied to
    the first job in the queue. If the job cannot be printed then
    <b class="APPLICATION">lpd</b> will wait for the <tt class=
    "LITERAL">chooser_interval</tt> time. However, the chooser can
    also be used to direct jobs by their characteristics, or other
    criteria. This means that the entire spool spool queue has to
    be scanned for work. If the <tt class=
    "LITERAL">:chooser_scan_queue</tt> flag is set to 1, then all
    of the jobs are tested to see if they can be sent to an
    appropriate destination.</p>

    <p>Edit the printcap file so it have the contents indicated
    below, create the <tt class="FILENAME">/tmp/lp2</tt> and
    <tt class="FILENAME">/tmp/lp3</tt> files with <tt class=
    "LITERAL">0777</tt> permissions. Then create the <tt class=
    "FILENAME">/tmp/chooser.script</tt> with the contents indicated
    below, and give it <tt class="LITERAL">0755</tt> (executable)
    permissions. Make sure that the path to the <b class=
    "APPLICATION">head</b> program used in <tt class=
    "FILENAME">chooser.script</tt> is correct. Use <tt class=
    "COMMAND">checkpc -f</tt> to check the printcap, and then use
    <tt class="COMMAND">lpc reread</tt> to restart the <b class=
    "APPLICATION">lpd</b> server.</p>

    <div class="INFORMALEXAMPLE">
      <a name="AEN3669" id="AEN3669"></a>
      <pre class="SCREEN">
# printcap
lp:force_localhost
lp:server
  :sd=/var/spool/lpd/%P
  :sv=lp2,lp3
  :chooser=/tmp/chooser.script
lp2:force_localhost
lp2:server
  :ss=lp
  :sd=/var/spool/lpd/%P
  :lp=/tmp/lp2
lp3:force_localhost
lp3:server
  :ss=lp
  :sd=/var/spool/lpd/%P
  :lp=/tmp/lp2

# /tmp/chooser.script

#!/bin/sh
echo CHOOSER $0 $@ &gt;&gt;/tmp/chooser
set &gt;&gt;/tmp/chooser
/usr/bin/head -1
exit 0
</pre>
    </div>

    <p>Now run the following commands:</p>

    <div class="INFORMALEXAMPLE">
      <a name="AEN3672" id="AEN3672"></a>
      <pre class="SCREEN">
<samp class="PROMPT">h4: {280} % </samp><kbd class=
"USERINPUT">lpr /tmp/hi</kbd>
<samp class="PROMPT">h4: {281} % </samp><kbd class=
"USERINPUT">lpq -lll</kbd>
Printer: lp@h4  (subservers lp2, lp3)
 Queue: no printable jobs in queue
 Status: CHOOSER selected 'lp3' at 14:02:50.605
 Status: transferring 'papowell@h4+178' 
      to subserver 'lp3' at 14:02:50.614
 Status: transfer 'papowell@h4+178' 
      to subserver 'lp3' finished at 14:02:50.624
 Status: job 'papowell@h4+178' removed at 14:02:50.632
 Status: starting subserver 'lp3' at 14:02:50.632
 Status: waiting for server queue process to exit at 14:02:50.651
 Status: subserver pid 10182 exit status 'JSUCC' at 14:02:52.872
 Status: no more jobs to process in load balance queue at 14:02:52.879
Server Printer: lp2@h4  (serving lp)
 Queue: no printable jobs in queue
Server Printer: lp3@h4  (serving lp)
 Queue: no printable jobs in queue
 Status: waiting for subserver to exit at 14:02:50.748
 Status: subserver pid 10183 starting at 14:02:50.820
 Status: accounting at start at 14:02:50.821
 Status: opening device '/tmp/lp3' at 14:02:50.833
 Status: printing job 'papowell@h4+178' at 14:02:50.834
 Status: processing 'dfA178h4.private', size 3, format 'f', \
      IF filter 'none - passthrough' at 14:02:50.838
 Status: printing finished at 14:02:50.839
 Status: accounting at end at 14:02:50.839
 Status: finished 'papowell@h4+178', status 'JSUCC' at 14:02:50.841
 Status: subserver pid 10183 exit status 'JSUCC' at 14:02:50.843
 Status: lp3@h4.private: job 'papowell@h4+178' printed at 14:02:50.856
 Status: job 'papowell@h4+178' removed at 14:02:50.871
</pre>
    </div>

    <p>As you see from the example above, the <acronym class=
    "ACRONYM">CHOOSER</acronym> selected <tt class=
    "LITERAL">lp3</tt> for use. Let us look at the <tt class=
    "FILENAME">/tmp/chooser</tt> file and see how the <tt class=
    "FILENAME">chooser.script</tt> program was run:</p>

    <div class="INFORMALEXAMPLE">
      <a name="AEN3683" id="AEN3683"></a>
      <pre class="SCREEN">
CHOOSER -Apapowell@h4+113 -CA -D2000-06-01-14:02:13.313 -Hh4.private \
   -J/tmp/hi -Lpapowell -Plp -Qlp -aacct -b3 -d/var/tmp/LPD/lp \
   -hh4.private -j113 -kcfA113h4.private -l66 -npapowell -sstatus \
   -t2000-06-01-14:02:13.379 -w80 -x0 -y0 acct
USER=papowell
LD_LIBRARY_PATH=/lib:/usr/lib:/usr/5lib:/usr/ucblib
HOME=/home/papowell
PRINTCAP_ENTRY=lp
 :chooser=/var/tmp/LPD/chooser
 :lp=/tmp/lp
 :sd=/var/tmp/LPD/lp
 :server
 :sv=lp2,lp3

lp2=change=0x0
 done_time=0x1
 held=0x0
 move=0x0
 printable=0x0
 printer=lp2
 printing_aborted=0x0
 printing_disabled=0x0
 queue_control_file=control.lp2
 server=0
 spooldir=/var/tmp/LPD/lp2
lp3=change=0x0
 done_time=0x2
 held=0x0
 move=0x0
 printable=0x0
 printer=lp3
 printing_aborted=0x0
 printing_disabled=0x0
 queue_control_file=control.lp3
 server=0
 spooldir=/var/tmp/LPD/lp3
PS1=$
OPTIND=1
PS2=&gt;
SPOOL_DIR=/var/tmp/LPD/lp
LOGNAME=papowell
CONTROL=Hh4.private
Ppapowell
J/tmp/hi
CA
Lpapowell
Apapowell@h4+113
D2000-06-01-14:02:13.313
Qlp
N/tmp/hi
fdfA113h4.private
UdfA113h4.private
</pre>
    </div>

    <p>As you can see, the program is invoked with the same options
    as a normal filter. In addition, the printcap information for
    each server queue is passed in an environment variable with the
    name of the server queue. This means that if there is
    information needed by the chooser program to test for the
    availability of hardware, etc., this can be placed in the
    printcap information.</p>

    <p>One of the limitations of using the <tt class=
    "LITERAL">:chooser</tt> program is that you may have a high
    overhead associated with running the program. The <b class=
    "APPLICATION">LPRng</b> software provides support for linking
    in a user provided routine that does the same thing as the
    <tt class="LITERAL">:chooser</tt> program. This routine has the
    following API or interface:</p>

    <div class="INFORMALEXAMPLE">
      <a name="AEN3690" id="AEN3690"></a>
      <pre class="SCREEN">
Printcap Option: chooser_routine
   chooser_routine@  - default - do not use chooser routine
   chooser_routine   - use chooser routine

Configuration:
   configure --with-chooser_routine=name --with-user_objs=objectfile.o
      defines the CHOOSER_ROUTINE compilation option to name
      includes the objectfile.o in the library.

extern int CHOOSER_ROUTINE( struct line_list *servers,
    struct line_list *available, int *use_subserver );
  servers:    all subserver queues for this load balance queue
  available:  subserver queues to choose from
  use_subserver: chosen subserver queue
  RETURNS:
     0 - use the 'use_subserver' value as index into servers
         list for server to use
     != 0 - set job status to value returned.
</pre>
    </div>

    <p>See the <tt class=
    "FILENAME">LPRng/src/common/lpd_jobs.c</tt> and <tt class=
    "FILENAME">LPRng/src/common/user_objs.c</tt> files for details
    of the servers, available, and user_subserver parameters. The
    <tt class="FILENAME">user_objs.c</tt> file provides a simple
    template that can be used as a starting point for a more
    complex routine. You should modify the code in the <tt class=
    "FILENAME">user_objs.c</tt> file and then use the configure
    options shown above to cause the <tt class=
    "FILENAME">user_objs.c</tt> file to be compiled and linked into
    the <b class="APPLICATION">LPRng</b> executables.</p>
  </div>

  <div class="NAVFOOTER">
    <hr align="left" width="100%">

    <table summary="Footer navigation table" width="100%" border=
    "0" cellpadding="0" cellspacing="0">
      <tr>
        <td width="33%" align="left" valign="top"><a href=
        "x3515.htm" accesskey="P">Prev</a></td>

        <td width="34%" align="center" valign="top"><a href=
        "index.htm" accesskey="H">Home</a></td>

        <td width="33%" align="right" valign="top"><a href=
        "x3699.htm" accesskey="N">Next</a></td>
      </tr>

      <tr>
        <td width="33%" align="left" valign="top">Holding and
        Releasing Jobs</td>

        <td width="34%" align="center" valign="top"><a href=
        "tutorial.htm" accesskey="U">Up</a></td>

        <td width="33%" align="right" valign="top">Routing Jobs To
        Print Queues</td>
      </tr>
    </table>
  </div>

  <p align="center"></p>
</body>
</html>