1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 
 13 wdx$init: proc (a_evchn, a_ec);
 14 
 15 
 16 /* wdx - ring 1 lv_attach_table manager
 17 
 18    Runs in Initializer process, communicates lv_request_'s desires to table and user process.
 19    Entries are accessible through initializer_mdc_
 20 
 21 
 22    Entry Points:
 23 
 24    check_mount                issue syserr message for overdue mount
 25    free_lvate                 clear one out
 26    init                       set up for bootload
 27    invalidate_lvate           cause process to give up lv
 28    mhvmessage                 issue syserr message for Operator
 29    poll_mounts                check for overdue mounts
 30    respond_mount_lv           set return state, code, and bit
 31    retrieve_lvate             dredge entry out of lvat
 32    scan_lv                    find all lv occurences
 33    scan_process               find all process occurrences
 34    set_lvinfo                 put lvid and stuff in lvate
 35 
 36    Bernard Greenberg 09/08/76
 37    Modified December 1981 by J. Bongiovanni for poll_mounts, check_mount
 38    Modified April 82 BIM for legal acls.
 39 */
 40 
 41 /*  Parameter  */
 42 
 43 dcl  a_array (*) fixed bin;
 44 dcl  a_code fixed bin (35);
 45 dcl  a_ec fixed bin (35);
 46 dcl  a_evchn fixed bin (71);
 47 dcl  a_lvatep ptr;
 48 dcl  a_lvax fixed bin (17);
 49 dcl  a_lvid bit (36) aligned;
 50 dcl  a_lvname char (*);
 51 dcl  a_lvx fixed bin;
 52 dcl  a_n fixed bin;
 53 dcl  a_next_time fixed bin (71);
 54 dcl  a_pid bit (36) aligned;
 55 dcl  a_state fixed bin;
 56 dcl  a_unit_string char (*) varying;
 57 dcl  a_username char (*);
 58 
 59 /*  Automatic  */
 60 
 61 dcl  1 seg_acl (1) aligned like segment_acl_entry;
 62 
 63 dcl  ec fixed bin (35);
 64 dcl  fixedipcmessage fixed bin (71);
 65 dcl  lvax fixed bin;
 66 dcl  lvname char (32);
 67 dcl  n fixed bin;
 68 dcl  next_time fixed bin (71);
 69 dcl  pid bit (36) aligned;
 70 dcl  save_lev fixed bin;
 71 dcl  username char (32);
 72 
 73 /*  Static  */
 74 
 75 dcl  END_OF_TIME fixed bin (71) int static options (constant) init (1111111111111111111111111111111111111111111111111111b);
 76 dcl  LVAT_NAME char (32) static init ("lv_attach_table") options (constant);
 77 dcl  s_lvatp ptr static init (null);
 78 dcl  SYSDIR char (168) static init (">lv");
 79 dcl  TIMEOUT fixed bin (71) int static options (constant) init (240000000);     /* 4 minutes */
 80 dcl  WDX_RING fixed bin init (1) static;
 81 /*  Based  */
 82 
 83 dcl  ipcmessage char (8) based (addr (fixedipcmessage));
 84 
 85 /*  Entry  */
 86 
 87 dcl  admin_gate_$reclassify_sys_seg entry (char (*), char (*), bit (72) aligned, fixed bin (35));
 88 dcl  admin_gate_$syserr entry options (variable);
 89 dcl  admin_gate_$syserr_error_code entry options (variable);
 90 dcl  cu_$level_get entry (fixed bin);
 91 dcl  cu_$level_set entry (fixed bin);
 92 dcl  get_max_authorization_ returns (bit (72) aligned);
 93 dcl  get_process_id_ entry returns (bit (36) aligned);
 94 dcl  get_ring_ entry returns (fixed bin);
 95 dcl  hcs_$add_acl_entries entry (char (*), char (*), ptr, fixed bin, fixed bin (35));
 96 dcl  hcs_$make_seg entry (char (*), char (*), char (*), fixed bin (5), ptr, fixed bin (35));
 97 dcl  hcs_$truncate_seg entry (ptr, fixed bin, fixed bin (35));
 98 dcl  hcs_$wakeup entry (bit (36) aligned, fixed bin (71), fixed bin (71), fixed bin (35));
 99 
100 /*  Builtin  */
101 
102 dcl  clock builtin;
103 dcl  min builtin;
104 dcl  null builtin;
105 dcl  stacq builtin;
106 
107 /*  Condition  */
108 
109 dcl  cleanup condition;
110 /* ^L */
111 
112           a_ec = 0;
113 
114           call cu_$level_get (save_lev);
115           on cleanup call cu_$level_set (save_lev);
116           call cu_$level_set (WDX_RING);
117           call hcs_$make_seg (SYSDIR, LVAT_NAME, "", 1011b, s_lvatp, ec);
118           if s_lvatp = null then do;
119 init_lose:     call cu_$level_set (save_lev);
120                a_ec = ec;
121                return;
122           end;
123 
124           call hcs_$truncate_seg (s_lvatp, 0, ec);
125           if ec ^= 0 then go to init_lose;
126 
127           call admin_gate_$reclassify_sys_seg (SYSDIR, LVAT_NAME, get_max_authorization_ (), ec);
128           if ec ^= 0 then go to init_lose;
129 
130           seg_acl (1).access_name = "*.*.*";
131           seg_acl (1).mode = RW_ACCESS;
132           seg_acl (1).extended_mode = ""b;
133           seg_acl (1).status_code = 0;
134 
135           call hcs_$add_acl_entries (SYSDIR, LVAT_NAME, addr (seg_acl), 1, ec);
136           if ec = 0 then if seg_acl (1).status_code ^= 0 then ec = seg_acl (1).status_code;
137           if ec ^= 0 then go to init_lose;
138 
139           call cu_$level_set (save_lev);
140           lvatp = s_lvatp;
141 
142           lvat.master_pid = get_process_id_ ();
143           lvat.master_evchn = a_evchn;
144 
145           lvat.max_n_entries = 10000;
146           lvat.highest_used = 0;
147           lvat.initialized = "1"b;
148           return;
149 
150 /* --------------------------------------------------------- */
151 
152 retrieve_lvate: entry (a_lvax, a_lvatep, a_ec);
153 
154           lvax = a_lvax;
155 
156           lvatp = s_lvatp;
157           if lvax > lvat.highest_used | lvax <= 0 then do;
158                a_ec = 5;
159                return;
160           end;
161 
162           lvatep = addr (lvat.array (lvax));
163           a_lvatep -> lvate = lvate;
164           a_ec = 0;
165           return;
166 
167 /* --------------------------------------------------------- */
168 
169 free_lvate: entry (a_lvax);
170 
171           lvatp = s_lvatp;
172           lvatep = addr (lvat.array (a_lvax));
173 
174           if stacq (lvate.pid, "0"b, (lvate.pid)) then;
175           return;
176 
177 /* --------------------------------------------------------- */
178 
179 respond_mount_lv: entry (a_lvax, a_state, a_code, a_ec);
180 
181 
182           lvatp = s_lvatp;
183           lvatep = addr (lvat.array (a_lvax));
184 
185           lvate.code = a_code;
186           lvate.state = a_state;
187           if lvate.state = 1 then do;
188                lvate.waiting = "0"b;
189                lvate.mounted = "1"b;
190           end;
191           else if lvate.state = 4 then do;
192                lvate.waiting = "1"b;
193                lvate.mount_request_timeout = clock () + TIMEOUT;
194                ipcmessage = "poll    ";
195                call hcs_$wakeup (lvat.master_pid, lvat.master_evchn, fixedipcmessage, ec);
196                if ec ^= 0
197                     then call admin_gate_$syserr_error_code (0, ec, "wdx: Unable to send wakeup on master channel");
198           end;
199           else lvate.waiting = "0"b;
200           if lvate.state ^= 4 then lvate.pending_mount = "0"b;
201           lvate.mount_req_answered = "1"b;
202 
203           ipcmessage = "lv_mount";
204 
205           call hcs_$wakeup (lvate.pid, lvate.evchn, fixedipcmessage, ec);
206 
207           a_ec = ec;
208           return;
209 
210 /* --------------------------------------------------------- */
211 
212 scan_process: entry (a_pid, a_array, a_n);
213 
214           pid = a_pid;
215           lvatp = s_lvatp;
216 
217           n = 0;
218 
219           do lvax = 1 to lvat.highest_used;
220                if lvat.array (lvax).pid = pid then do;
221                     n = n + 1;
222                     a_array (n) = lvax;
223                end;
224           end;
225           a_n = n;
226 
227           return;
228 
229 /* --------------------------------------------------------- */
230 
231 scan_lv:  entry (a_lvname, a_array, a_n);
232 
233           lvname = a_lvname;
234           lvatp = s_lvatp;
235 
236           n = 0;
237 
238           do lvax = 1 to lvat.highest_used;
239                lvatep = addr (lvat.array (lvax));
240                if lvate.pid ^= "0"b then if lvate.pending_mount | lvate.mount_req_answered
241                     then if lvate.lvname = lvname & ^lvate.invalidated then do;
242                               n = n + 1;
243                               a_array (n) = lvax;
244                          end;
245           end;
246           a_n = n;
247           return;
248 
249 /* --------------------------------------------------------- */
250 
251 invalidate_lvate: entry (a_lvax);
252 
253           lvatp = s_lvatp;
254           lvatep = addr (lvat.array (a_lvax));
255 
256           lvate.invalidated = "1"b;
257           return;
258 
259 /* --------------------------------------------------------- */
260 
261 set_lvinfo: entry (a_lvax, a_lvid, a_lvx);
262 
263           lvatp = s_lvatp;
264           lvatep = addr (lvat.array (a_lvax));
265 
266           lvate.lvid = a_lvid;
267           lvate.lvx = a_lvx;
268           return;
269 
270 /* --------------------------------------------------------- */
271 
272 mhvmessage: entry (a_lvax, a_username);
273 
274           lvatp = s_lvatp;
275           lvatep = addr (lvat.array (a_lvax));
276 
277           username = a_username;
278           call admin_gate_$syserr (3, "RCP: Mount logical volume ^a for ^a", lvate.lvname, username);
279           return;
280 
281 /* --------------------------------------------------------- */
282 
283 poll_mounts:
284           entry (a_array, a_n, a_next_time);
285 
286           lvatp = s_lvatp;
287           next_time = END_OF_TIME;
288           n = 0;
289           do lvax = 1 to lvat.highest_used;
290                lvatep = addr (lvat.array (lvax));
291                if (lvate.pid ^= "0"b) & lvate.waiting & lvate.mount_req_answered & ^lvate.invalidated
292                     then do;
293                     if lvate.mount_request_timeout < clock () then do;
294                          n = n + 1;
295                          a_array (n) = lvax;
296                          lvate.mount_request_timeout = clock () + TIMEOUT;
297                     end;
298                     next_time = min (next_time, lvate.mount_request_timeout);
299                end;
300           end;
301           a_n = n;
302           if next_time = END_OF_TIME then a_next_time = -1;
303           else a_next_time = next_time;
304           return;
305 
306 
307 /* --------------------------------------------------------- */
308 
309 check_mount:
310           entry (a_lvax, a_username, a_unit_string);
311 
312           lvatp = s_lvatp;
313           lvatep = addr (lvat.array (a_lvax));
314           if lvate.pid ^= "0"b & lvate.waiting & lvate.mount_req_answered & ^lvate.invalidated
315                then call admin_gate_$syserr (3, "RCP: Check mount of logical volume ^a for ^a^/^15x^a",
316                lvate.lvname, (a_username), (a_unit_string));
317           return;
318 
319 
320 /* --------------------------------------------------------- */
321 test:     entry (testdir);
322 
323 dcl  testdir char (*);
324           SYSDIR = testdir;
325           WDX_RING = get_ring_ ();
326           return;
327                                                             /* ^L */
328 %include acl_structures;
329 %include access_mode_values;
330 %include lv_atttbl;
331 ^L
332 
333 /*  BEGIN MESSAGE DOCUMENTATION
334 
335    Message:
336    RCP: Mount logical volume LVNAME for PROCESSNAME
337 
338    S: $beep
339 
340    T: $run
341 
342    M: A user (PROCESSNAME) has requested the attachment
343    of logical volume LVNAME. It is not now mounted.  The
344    initializer will issue mount messages for all physical volumes needed.
345 
346    A: Mount the required physical volumes, using the add_vol command
347    to indicate when each has been made ready.  The user process will
348    continue when the last volume has been mounted.  If the volume
349    cannot be mounted, use the del_lv command to indicate this fact,
350    and the user process will receive an error indication.
351 
352 
353    Message:
354    RCP: Check mount of logical volume LVNAME for PROCESSNAME
355         PVNAME1(DRIVE1) ...
356 
357    S: $beep
358 
359    T: $run
360 
361    M: A user (PROCESSNAME) previously requested the attachment of logical volume
362    LVNAME.  The mount has not been accomplished in a 4 minutes.
363    All required physical volumes are specified (PVNAMEi, DRIVEi).
364 
365    A: Mount the required physical volumes, using the add_vol command
366    to indicate when each has been made ready.  The user process will
367    continue when the last volume has been mounted.  If the volume
368    cannot be mounted, use the del_lv command to indicate this fact,
369    and the user process will receive an error indication.
370 
371 
372    Message:
373    wdx: ERRORCODE Unable to send wakeup on master channel.
374 
375    S: $info
376 
377    T: $run
378 
379    M: The ring-1 logical volume mount software was unable to send a wakeup
380    to the ring-4 software for the reason indicated.  Some mount requests
381    may have been lost.
382 
383    A: $contact_sa
384 
385    END MESSAGE DOCUMENTATION */
386 
387      end;