Previous Thread
Next Thread
Print Thread
How to Temporarily Prevent Users From Running Programs #34836 16 Dec 21 05:21 PM
Joined: Jun 2001
Posts: 713
S
Steven Shatz Offline OP
Member
OP Offline
Member
S
Joined: Jun 2001
Posts: 713
A process that runs unattended, overnight prevents users from logging into A-Shell until it completes, but it cannot prevent users who are already logged in from attempting to run programs (which can lead to conflicts). Is there a way to prevent such users from interfering with the overnight process (e.g., suspend their jobs)? If not, is there a recommended way in A-Shell Linux to force these users off the system (e.g., kill their jobs) or render them temporarily impotent?

Last edited by Steven Shatz; 16 Dec 21 05:21 PM.
Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34837 16 Dec 21 05:40 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
Interesting question. Some ideas off the top of my head:

  • If the unattended process has sudo privileges, and assuming that your directory privileges are sufficiently uniform, you could have it change the ownership or privileges of all the relevant directories, preventing other uses from even seeing them.
  • It could rename all the RUN files to RUNX
  • It could put a lock on the JOBTBL
  • You could use $ kill -TSTP pid to suspend individual processes and $ kill -CONT pid to resume them.


The first two options wouldn't have any effect on programs that were already running though, since the RUN file would already be in memory. And, it wouldn't make for a very clean suspend/resume.

For the JOBTBL lock, my thought was to try using MX_READJCB to read and lock all the jobtbl records of the other jobs. I'm not sure without actual testing whether that would cause the target jobs to get stuck in a way that would stop them from running an existing program, and make it possible for them to resume.

The kill option (also available directly via MX_KILL) is also only theoretical. Signal handling is pretty complex in A-Shell and I'd need to do some testing to see whether this would really work as intended. Note that the numeric values for the TSTP and CONT signals are 20 and 18, respectively. Also note that you should be able to trace the receipt of these signals with SET TRACE SIGNAL ON. Of all the options, this one appears to have the potential for the cleanest solution (get the pids from a SYSTAT/L or via MX_READJCB calls), but preliminary testing is definitely required. Also, you'd have to do something to stop new connections from starting up, possibly by modifying your main startup command?

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34838 17 Dec 21 03:31 PM
Joined: Sep 2002
Posts: 5,471
F
Frank Online Content
Member
Online Content
Member
F
Joined: Sep 2002
Posts: 5,471
Hey Steve -

This may be too KISS for you, but we have built in a halt system when we run these sorts of tasks. We create a file called "halt.dat" in an area that programs will look for (can be in BAS:, the ,0 or database ppn dependent on the level of the lock). If present it will display a message to the user that is inside the halt.dat (we will just add a few lines in the halt.dat like NOTICE! System Maintenance in Progress....) When the task is complete we simply erase halt.dat and programs can resume.

The key is you would have to add a check of the halt.dat file before allowing a user to log in, or if they are already logged in, add to the programs housekeeping routine. We have ours in our main "system.sub" which is automatically included in all our programs.

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34839 17 Dec 21 05:24 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
This is probably a better approach since you can more easily customize it to your exact requirements, but it does require updating all the existing programs to interface with it. That may be a simple as inserting a ++include at the top of each program and recompiling.

However, you still have the issue of what to do about programs that had already started running and had passed the security gate when the critical process starts. One approach to that which I've used is create a routine to be executed at the start of one of these critical background processes that scans the job table (either using SYSTAT/L or MX_JCBREAD) looking for potential conflicts (i.e. jobs in the RN state) and use SENT (LIT or SBR) to send them a screen message telling them to please exit. It can then sleep for a bit and repeat the process until everyone is out. It could even send KILL commands to them if necessary.

Another variation on this scenario is where you have a background process that you want to make sure is always running. You could create a second watchdog for it, but you could also just launch a new one via the crontab every few minutes. The startup of the process would use the above technique to see if there was already a copy of that program in use, and if so, just exit. So you end up with a lot of session startups and shutdowns, but there's little harm there, and it's a simple way of making sure that the process doesn't terminate unexpectedly, and go unnoticed for hours,.

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34840 17 Dec 21 09:41 PM
Joined: Jun 2001
Posts: 713
S
Steven Shatz Offline OP
Member
OP Offline
Member
S
Joined: Jun 2001
Posts: 713
Thank you both for your suggestions.

Frank, as Jack pointed out I am concerned about jobs that are already in progress. I need to temporarily "freeze" or kill those jobs. I already have a way to prevent new jobs from starting.

Jack, I like the idea of getting a SYSTAT list and parsing it for other running (RN) jobs. If time wasn't of the essence I would send a message and wait as you suggest. But we are asking users to stay out of A-Shell during a specific time frame (5:30 AM to 7:00 AM) and waiting for users to log out would waste precious minutes.

But you have given me a method that I believe will work. I can use the Linux "kill" command with -STOP and -CONT signals to suspend and resume a Linux process. Since SYSTAT provides the pid #, I can first SEND a notification to the bottom status line of each job before I suspend it with "kill -STOP". At EOJ, I would undo this using "kill -CONT". I'd also like to clear the bottom status line - is there a command like SEND.LIT that can do that?

You referred to the -TSTP signal. Should I use that instead of -STOP? (I ran some tests with -STOP and -CONT and that seemed to work.)

The overnight job is running as root, so it should be able to "kill" other jobs. Can you think of any pitfalls using this technique?

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34841 17 Dec 21 10:18 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
Regarding SEND ...
Code
.SEND/?
Usage:

  .SEND {switches} <target> <message>

<target> may be 'ALL', or a job,user or machine name
<message> is a text message (or filename for /F)
If <message> = "!" forces hidden target to display itself
Switches:
 /B - send message to bottom status line
 /F - ask if target has file open (message is filename)
 /T - send message to top status line
 /W - send message in popup window


SEND.SBR offers the same options.

As for -STOP vs -TSTP, you're right, I think -STOP is the way to go. TSTP is what you get by entering ^Z at the bash prompt, but that's a different situation. In fact, this technique of stopping and continuing an A-Shell process only works if the process is not running under a shell that responds to those signals, because if it is, then the shell will spin the stopped job into the background and give you a new shell prompt. I was able to get it -STOP and -CONT to work as desired though if I launch ashell using exec (to replace the shell with ashell). I suspect you must be doing the same, or else have configured your shell to ignore those signals.

Re: How to Temporarily Prevent Users From Running Programs [Re: Jack McGregor] #34842 17 Dec 21 11:01 PM
Joined: Jun 2001
Posts: 713
S
Steven Shatz Offline OP
Member
OP Offline
Member
S
Joined: Jun 2001
Posts: 713
SEND does not appear to have an option to clear the top or bottom status line. If <message> is blank, the sending jobname is still displayed. Is there any other A-Shell or Linux command that can clear that?

And yes, I invoke ashell using exec (as you had long ago recommended).

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34843 17 Dec 21 11:23 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
Sending a blank message is a special case, which sends an "Are You There" message. But it should still obey the /B and /T switches. For example:
Code
.send /b tskaat

results in "TSKAAS - tskaat" appearing on the bottom status line of the TSKAAT terminal.

Those status line options were implemented back in 2001, so it's unlikely you don't have them. (Although you may want to execute UPDCUR.LIT from the SYS: directory to make sure you have all the latest LIT files.)

Another possibility is that the TCRT commands for the top/bottom status lines aren't supported or aren't compatible in your terminal emulation. You could test that with a simple program:
Code
? TAB(-1,130);"Bottom status line message";TAB(-1,129);

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34844 17 Dec 21 11:34 PM
Joined: Jun 2001
Posts: 713
S
Steven Shatz Offline OP
Member
OP Offline
Member
S
Joined: Jun 2001
Posts: 713
I can display messages on the bottom status line, but I can't find a way to completely clear that line:

Code
send /b tskaat   

followed by a space

displays "TSKAAS -".

Last edited by Steven Shatz; 17 Dec 21 11:35 PM.
Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34845 18 Dec 21 12:19 AM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
Ohhhh...
Funny, no one has ever asked for that feature in 20+ years!
We could probably add it to SEND without requiring an update to A-Shell. But in the meantime, maybe you can send them a followup message, e.g.

Code
send /b tskaat Please wait while we oil the machine...

and then...

Code
send /b tskaat All Clear - Go Back to Work!

Re: How to Temporarily Prevent Users From Running Programs [Re: Jack McGregor] #34846 18 Dec 21 01:01 AM
Joined: Jun 2001
Posts: 713
S
Steven Shatz Offline OP
Member
OP Offline
Member
S
Joined: Jun 2001
Posts: 713
That's exactly what I'm doing. The status line is not really a problem - so don't knock yourself out. And thanks for all your suggestions!

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34847 18 Dec 21 10:55 PM
Joined: Jun 2001
Posts: 713
S
Steven Shatz Offline OP
Member
OP Offline
Member
S
Joined: Jun 2001
Posts: 713
I've found another wrinkle in the cloth:

If any suspended jobs held locks, the presence of those locks could impact the programs that are about to run. It seems that I would need to save a copy of the lock table so it can be restored when the running job finishes. And the running job would need to clear the lock table at startup. However, the lock table is in memory (MEM:), so how can this be accomplished? (Can this be accomplished?)


Last edited by Steven Shatz; 18 Dec 21 11:05 PM.
Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34848 19 Dec 21 07:54 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
I thought about that problem yesterday as I was out hiking. And I'm not sure there's any good solution. Perhaps if we're just talking about XLOCK or FLOCK locks, we could theoretically remove another job's locks and restore them later. But if we're talking about system (aka LOKSER) locks, there's no way to force other processes to release them other than by killing the process entirely. And even in the simpler XLOCK case, A-Shell uses system locks to lock access to the QFLOCK.SYS file, so you could end up with the system lock problem anyway.

The only universal workaround I can think of, so far, would require that A-Shell trap the TSTP signal (I think STOP is untrappable). It could then theoretically clear ll the system locks and restore them on receipt of the CONT signal. Or, much easier for A-Shell and more universal but harder for the application developer would be to convert the TSTP signal to a BASIC error, leaving it to the application to take appropriate action. But that would require rather sophisticated error handling to be added to all your programs.

As I vaguely recall, you have your own locking mechanism, so maybe that might make it easier, but you'll have to refresh my memory so I can review it.

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34849 19 Dec 21 08:39 PM
H
Herman Roehm
Unregistered
Herman Roehm
Unregistered
H
I’m probably missing something, but how can you allow the overnight job to potentially update a record that the lock has been temporarily released and then reapply the lock to a potentially changed record and allow another job to continue and update that record in the morning? It seems to go against what the lock is for.

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34850 19 Dec 21 09:17 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
That's a good point. I've been assuming that the issue isn't so much allowing the overnight job to update records but simply to gain access to them, for backup or other purposes. But in almost all such cases, the presence of locks wouldn't prevent that kind of access. In the general case, if locks are a problem, then we really want the jobs owning those locks to give them up freely, which would require that the applications get the signal. Generating a Basic error would be one approach, but rather difficult to handle. If all of the potentially affected programs were cooperative, you could go with a more tailored approach such as requiring that locks are never held for more than a very short time (in which case the overnight job could just keep retrying).

Going back to the Basic error approach, we already have that - just send each job a SIGINT, SIGHUP or SIGTERM signal or KILL command. A robust application should be able to handle these (Basic errors) without corrupting anything. It might not be quite as elegant for the late-night user, but it eliminates the need to analyze and implement a procedure for an entirely new scenario, by making it just another example of an already existing scenario. And you could be slightly friendly about it, for example using SEND first to warn the users to at least go back to something that doesn't involve any system locks, and then if they don't respond within, say, 30 seconds, sending them a termination signal.

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34851 19 Dec 21 11:29 PM
Joined: Jun 2001
Posts: 713
S
Steven Shatz Offline OP
Member
OP Offline
Member
S
Joined: Jun 2001
Posts: 713
Herman: in my situation, the overnight process does little updating, so it's highly unlikely that a suspended job would later undo an overnight change. However, the overnight process also repairs and rebuilds some ISAM index files and in the future could do more extensive updates. So your point is well taken. I think it would be better to kill any jobs that held locks and only suspend those that don't.

FYI: We use a simplified version of locking originally developed by David Pallmann (remember him?) which Jack converted into ALOCK.SBR and AUNLOK.SBR for A-Shell sometime last century. I don't have the source code so I can't tell whether these modules use XLOCK, but I believe they do. In any case, by killing all jobs that hold locks and thereby releasing all those locks, my locking problem is resolved. (These users are not supposed to be on the system anyway.)

Thank you all for your help.

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34852 20 Dec 21 11:20 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
For what it's worth, here's an update of send that clears the target status line if the message is empty (at least in the UNIX environment) ...

SEND.LIT 2.3(127)

It also removes the target jobname from the displayed message (it didn't seem very helpful).

As for ALOCK/AUNLOK, yes it is in fact a wrapper around XLOCK, so the locks are actually held in the QFLOCK.SYS file. I'm not sure if you had a specific utility for scanning that particular set of locks, but you could use the regular MX_GETQUEUE call. The ALOCK locks can be distinguished by the fact that LOCK3=1.

Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34853 21 Dec 21 10:11 PM
Joined: Jun 2001
Posts: 713
S
Steven Shatz Offline OP
Member
OP Offline
Member
S
Joined: Jun 2001
Posts: 713
In MX_GETQUEUE: is QOWNER (2-byte binary) the Linux Process ID # (pid)? If not, what is it? I am surprised there is no jobname field.

Or does QOWNER reference a matching field in JOBTBL.SYS which indicates the jobname?

Last edited by Steven Shatz; 22 Dec 21 08:10 PM.
Re: How to Temporarily Prevent Users From Running Programs [Re: Steven Shatz] #34862 31 Dec 21 08:57 PM
Joined: Jun 2001
Posts: 11,794
J
Jack McGregor Offline
Member
Offline
Member
J
Joined: Jun 2001
Posts: 11,794
Sorry, I apparently overlooked this...

QOWNER is actually the job #. The very compact (some might say stingy) layout of the queue is some kind of legacy holdover from last century, either inspired by matching the format used under AMOS, or simply to minimize memory usage. But hopefully the job # is good enough for matching against the JOBTBL (were job # = record #).


Moderated by  Jack McGregor, Ty Griffin 

Powered by UBB.threads™ PHP Forum Software 7.7.3