From: CSBVAX::MRGATE!info-vax-RELAY@KL.SRI.COM@SMTP 16-JUN-1988 22:47 To: ARISIA::EVERHART Subj: Re: HELP: symbiont dies under 4.7 Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Sat, 11 Jun 88 14:12:52 PDT Received: by ucbvax.Berkeley.EDU (5.59/1.28) id AA16811; Sat, 11 Jun 88 11:06:59 PDT Received: from USENET by ucbvax.Berkeley.EDU with netnews for info-vax@kl.sri.com (info-vax@kl.sri.com) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 21 May 88 18:51:55 GMT From: cunyvm!unknown%psuvm.BITNET@jade.berkeley.edu.user@host.BITNET Subject: Re: HELP: symbiont dies under 4.7 Message-Id: <130rrk@byuvax.bitnet> Sender: info-vax-request@kl.sri.com To: info-vax@kl.sri.com It seems like the hot topic of the day is print symbionts. I have some suggestions on print symbionts. I would be interested in any comments from others who would or wouldn't like to see some of these functions appear in a future release of VMS, and who maybe have experienced the same problems. Request for JOB CONTROL/SMBSRVSHR/$SNDJBC Enhancements JOB CONTROL, especially since its total rewrite for VMS 4.0, is one of VMS's very strong points. There are a few relatively small additions that could be made to greatly increase the flexibility and useability of JOB CONTROL and the spooler services interface by more fully utilizing the good design, greatly improving: - Control of printers with hand fed forms or requiring page setup or other modules from the device control library. - Accounting, aborting, positioning, checkpointing, and restarting in output jobs. - Support for the sequential spooling of jobs requiring different spooler routines in the same output queue. - Support for queues requiring input from the routines of one symbiont fed as output to routines of another symbiont. - Support for non-privileged users needing better and yet more carefully limited control of certain spooling functions. Problem 1: The VMS spooler routines need the ability to perform general spooling services on jobs of unknown format. When spooling simple ascii print jobs, in which pages are separated by formfeeds, lines by linefeeds, etc., the number of pages output are accurately calculated by the symbiont, unless user decides to use the /PASSALL qualifier, and only pay for one page. But many printer languages require command or parameter bytes with values in the range 0-31 or 128-160 (not necessarily conforming to ANSI or DEC defined syntax) indistinguishable from the line/page control codes which the VMS spooler routines use to identify line/page breaks. Many printers expect codes other than formfeeds to request new pages. To expect the standard generic spooler routines to be able to independently calculate the effect of a postscript file on an LN03R or the effect of other common laser printer languages on the corresponding printers is ridiculous. And yet there is no documented way for printer-specific PSM-integrated routines to communicate more accurate information to job control to enable proper accounting, check-points, job cancelation/restart, or insertion of a hand-fed form. Solution 1: User: Use specific symbiont input routines to handle specific input types. DEC: Allow replaceable symbiont routines to signal when page breaks are encountered. Also allow replaceable routines to request inclusion of modules from the device control library. This functionality probably should be closely connected to a specific main input routine associated with a specific input type. Other replaceable input routines, or even format routines could be made to return similar signals. One implementation of this solution would allow input routines to return alternate status codes (similar to PSM$_FLUSH). For example an input routine would return PSM$_NEWPAGE status code to signal that a page break had been sent through. It might call PSM$INCLUDE_MODULES to queue module and return PSM$_SUSPEND status code to signal that there was something for the service routines to do that can't be done at AST level. An alternative implementation would use special command strings interpreted by the main format routine. Command string would enable and disable standard formfeed signaling of page breaks (for backwards compatibility), signal when input codes produce a page break on the printer, and request inclusion of device control modules. They might even tell the main formatter the relative costs of forms from different bins, etc. Command strings could be imbedded in the source file or added by input or input format routines. They would be stripped out as they are interpreted by the main format routine. It is important that the command strings intercepted by the main format routine are distinct and distinguishable from the printer-specific codes which go to the printer. Problem 2: User-modified symbionts have become very popular. They allow implementation of input translation (see the DEC Script translator software, WordPerfect's translator, or various font managers or plotter drivers) as well as output connections to a multitude of devices (see DEC's LATSYM and PrintServer 40 output routines or the output routines of other symbionts designed to output across the TCPIP or to a directory from which files are daily collected and printed onto fiche). But how do you drive an LN03R printer or a plotter which is attached to a terminal server? How can the user output a WordPerfect document to a PrintServer 40 queue or to a fiche queue, since the routines are in separate symbionts? Solution 2: User: Coax DEC to provide for dynamic merging of symbionts. Organize compatible combinations of symbionts which will give all the necessary functions. DEC: Allow callers of PSM$REPLACE to get the address of the original routine being replaced so that control may be passed to the original for job types which the new routine doesn't handle. Allow multiple images containing symbiont modifications from different sources to be activated into a single symbiont image. This problem has already been encountered and solved by WordPerfect Corporation developers. The solution works without any hitch, but it had to be done in an indirect fashion. It was possible to get back the original address of the replaced routines in a position and module independent fashion. This enables a queue using the WordPerfect translating input routine which encounters a non-WordPerfect task to pass back control to the original input routine, whether it may be the one in SMBSRVSHR or one declared by a modified symbiont. The problem of allowing symbiont modifications from multiple sources to coexist in one image has also been solved by WordPerfect Corporation developers. Based on the fact that shareable run-time libraries like SMBSRVSHR use transfer vectors and may be relocated by logical names, it was possible to solve the merging of the symbionts as follows: Create a temporary image called WPCORP_VMS_SMB with transfer vectors ordered like those in SMBSRVSHR. Link all WordPerfect images to this image instead of SMBSRVSHR. Define the system logical name WPCORP_VMS_SMB to point to SYS$SHARE:SMBSRVSHR -- The WordPerfect spooling routines now find the symbiont image via this logical name instead of SMBSRVSHR. Create another image called WPCORP_TRF_SMB. Fill the first few blocks of the image with transfer vectors which jump to the transfer vectors of SMBSRVSHR except for the vector which would jump to PSM$PRINT, which jumps to the entry point of the WordPerfect routines. Then define the system logical SMBSRVSHR to point to the image WPCORP_TRF_SMB. Now, all system images calling PSM$PRINT call the WordPerfect entry point, which accepts parameters intended for PSM$PRINT and adds its own workspace to the end of the one declared by the caller and replaces the main input routine, storing the address of the original. Then it calls the real PSM$PRINT (assuming WPCORP_VMS_SMB was not redefined for another replacement). The message behind this overly-detailed description of a strange interface to PSM is that the solution works well, even though it is currently quite indirect. Customers using DEC's PrintServer 40 software, for example, find that the WordPerfect translator coexists well with the input routines of the other symbiont. LATSYM is another DEC symbiont which worked well with the WordPerfect translator spooler until VMS 4.7, when DEC internalized the spooler routines so that the call to PSM$PRINT was no longer intercepted. Fortunately, WordPerfect Corporation developers already had a LAT WordPerfect translator. But the major issue is this: should LAT ports be inferior to hard ports? Why aren't they supported by the DEC symbiont services utility? I thought that LATPlus was part of VMS. At least DEC could include the output routines for such symbionts in SMBSRVSHR. But DEC could do a lot better and solve more problems with less effort: DEC could allow the system manager to specify a list of processors using the /PROCESSOR qualifier. The first element of the list would remain the name of the primary symbiont. SMBSRVSHR could contain a variable staticly initialized to 1 and incremented by PSM$PRINT (to 2 the first time through). If the value becomes greater than the number of elements in the list of processors, PSM$PRINT performs its normal function. If not, it activates (via LIB$FIND_IMAGE_SYMBOL or perhaps a direct call to SYS$IMGACT so that the image can be located in SYS$SYSTEM) the shareable image represented by the nth element of the /PROCESSOR list and transfers control to a standard universal symbol such as USER$PRINT, which eventually calls PSM$PRINT again. In this way, each image in the list is given the chance to adjust the PSM$PRINT parameters. Each image should save the workspace size passed to it for later use as an offset to its own workspace from the base workspace address and add the size of its own workspace to the total workspace size requested in its call to PSM$PRINT. Each image may choose to save off the original addresses of the routines it replaces in order to transfer control for job types it can't handle. This is only one of many ways the merging of symbionts could be accomplished, but it has a few advantages. It requires few modifications to the symbiont facility. It allows the existing interface to remain intact. By giving a shareable image a transfer address, it may serve as either the primary image (and function on older VMS's without the ability to merge symbionts) or as a secondary symbiont. It requires routines of secondary images to add an offset (the one passed as a workspace size to the main entry) to the workspace address passed to them, but this simplifies defaulting back to a routine declared by a previous symbiont image for an unsupported function or format: since all symbionts then require the same base-workspace address. A routine can pass the same arguments it received to the routine it replaced. In MACRO32: CALLG (AP), @PREVIOUS_ROUTINE. Problem 3: JOB CONTROL is a beautiful controller of shared system resources. Access checks on sources are performed by $SNDJBC in the user's own context to ensure that the symbiont running in system context doesn't receive requests the user should not to make. But users and application writers often require JOB CONTROL-type service to perform tasks which can only reasonably occur in a local context. For example: users have long been looking for a solution as nice as print queues for printing to an attached printer. It is easy to modify the symbiont output routine to output a job to a printer such as the LN03R attached to the printer port of a terminal. The stream can lookup the control sequences required by the terminal device on the port to route data to the attached printer and then back to the screen, and then prefix each I/O with the routing to the printer and suffix each I/O with the routing back to the screen. $BRKTHRU messages (always between I/O's) will always go to the screen. The user can even interactively use the terminal while the attached printer is printing a job (to prevent overloading it may be desirable to pause between I/O completion and the call to PSM$REPORT). But the following problems stand in the way of such a solution: 1. A system symbiont runs in the system context. If a user were given control to start and stop such a queue, he could send output to any device on the VMS system. 2. The system symbiont would assign a channel to the user's terminal. Then if the user logged off, he would be prevented from logging back on due to the assigned channel. 3. A user given privilege to start and stop a queue has the ability to use the /PROCESSOR qualifier to invoke with all privileges any image in SYS$SYSTEM. 4. A user given control over such a queue could really squander system resources. How does a multithreaded symbiont calculate CPU usage by task). There are many other applications besides attached printer queues crying for job-local symbionts including: spool-to-disk servers, network access servers, other spoolers and translators, etc. Solution 3: User: Write symbionts designed to run in the user's context. DEC: Provide a new queue attribute: /LOCAL, which causes $SNDJBC to run the symbiont as a user subprocess and communicate the PID back to JOB CONTROL. Optionally provide an /AUTOSTART attribute for queues which the user doesn't logically think of starting (so the user doesn't have to restart the queue every time he logs in), and a /TEMPORARY attribute for local queues to be automatically deleted when stopped. Any implementation of this solution probably requires JOB CONTROL to open one common non-privileged mailbox so that non-privileged symbionts may send status messages. $SNDJBC would accurately report (to the privileged JOB CONTROL mailbox) the PID as well as the number of the spawned symbiont's input mailbox (created by the $SNDJBC call, only readable by the owner) so false messages to JOB CONTROL's non-privileged mailbox would be no more devastating or compromising than a barrage of useless $SNDJBC requests to the privileged mailbox. JOB CONTROL already identifies symbiont status messages by the PID of the sender. $SNDJBC would not always need to spawn a symbiont, since the user symbionts can be multi-threaded just like system symbionts. $SNDJBC would probably be totally unaware whether a specific queue is a local or system queue when it sends the start request, but JOB CONTROL would return a status giving it certain $CREPRC parameters, and it would call SYS$CREPRC returning PID and status to JOB CONTROL. Since a local symbiont would serve a JOB, it would be advantageous to make the symbiont process owned by the job's master PID by forbidding subprocesses from starting local queues. Or JOB CONTROL could issue a special kernel-mode AST to the JOB's master PID to create the subprocess and return status and PID to JOB CONTROL, or users could live with the fact that the spooler dies with the creating process, or users could be forced to execute the DCL command: $ START/QUEUE/LOCAL_MANAGER/PROCESSOR=xxxxxx from the login command procedure by the master PID before being allowed to start any local queues. The processor image(s) should be located in the directory SYS$LOCAL -- not SYS$SYSTEM (please don't require placement of a local print-to-disk symbiont in SYS$SYSTEM where anyone with OPER privilege or execute access to a system queue could manipulate it to rewrite a system-wide command procedure). Users should probably be given LOCAL_QUEUE privilege to enable them to create local queues. Starting a local queue (which runs a subprocess in the job of the requesting process) can be performed by any user with execute access to the queue. Once a queue is started by a user, anyone else with access to the queue who attempts to start the queue gets an error that the queue is already started. Other users with proper access to the queue could print to the queue, even though the spooler happens to be running as a subprocess of a different job context (so if you have access, you can print to someone else's attached printer), but the default protection on a local queue would only allow the owner and managers with BYPASS privilege to print to it. WordPerfect Corporation developers have already addressed this problem in a limited fashion by creating a module which runs a symbiont as a sub-process of a user's job and writes and reads the messages the local symbiont process expects to read and write from JOB CONTROL. It is amazing how well this method works. It allows great functionality in printing to an attached printer or to disk without compromising system security -- complete with flag and trailer pages, page headers, modules from the device control library, etc. This method was abandoned in WordPerfect's latest releases in favor of more conventional local printing; it was only a partial solution. It was hard to babysit a symbiont which was used to being serviced by JOB CONTROL. If things didn't work right, sometimes the exact error messages were lost. And the local symbiont can only operate while an image containing the special controlling module is active. The queue is also only accessible from within the controlling image. If SMBSRVSHR had ever required privileges beyond those required for reading input, writing output, and reading and writing status messages, the solution would have stopped working. But it is a good idea, which, if implemented through the real JOB CONTROL, could make VMS better. Thanks! AMMON::RAY