1
2
3
4
5
6
7
8
9
10
11
12
13 wdx$init: proc (a_evchn, a_ec);
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 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
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
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);
80 dcl WDX_RING fixed bin init (1) static;
81
82
83 dcl ipcmessage char (8) based (addr (fixedipcmessage));
84
85
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
101
102 dcl clock builtin;
103 dcl min builtin;
104 dcl null builtin;
105 dcl stacq builtin;
106
107
108
109 dcl cleanup condition;
110
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
328 %include acl_structures;
329 %include access_mode_values;
330 %include lv_atttbl;
331 ^L
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 end;