1
2
3
4
5
6
7
8
9
10
11
12
13
14 verify_lock:
15 procedure;
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 dcl 1 dirs_locked aligned,
62 2 count fixed bin,
63 2 array (30) aligned,
64 3 seg_ptr pointer,
65 3 uid bit (36) aligned;
66
67 dcl code fixed bin (35);
68 dcl cond_name char (32);
69
70 dcl check_masked bit (1) aligned;
71 dcl log_condition bit (1) aligned;
72 dcl unlock_occurred bit (1) aligned;
73 dcl mcptr ptr;
74 dcl pvtx fixed bin;
75 dcl pagex fixed bin;
76 dcl p99 pic "99";
77 dcl tsdw fixed bin (71);
78
79 %include hc_lock;
80
81 dcl condition_ entry (char (*), entry);
82 dcl ioi_verify_lock entry () returns (bit (1) aligned);
83 dcl reversion_ entry (char (*));
84 dcl syserr entry options (variable);
85 dcl syserr$binary entry options (variable);
86 dcl syserr$error_code entry options (variable);
87 dcl on_line_salvager entry (ptr, fixed bin (35));
88 dcl lock$dir_unlock_given_uid
89 entry (bit (36) aligned);
90 dcl lock$dir_lock_salvage
91 entry (ptr, bit (36) aligned, fixed bin (35));
92 dcl lock$unlock_fast entry (ptr);
93 dcl lock$lock_fast entry (pointer);
94 dcl pxss$notify entry (bit (36) aligned);
95 dcl get_pvtx$cleanup entry () returns (bit (1) aligned);
96 dcl debug_check entry (char (4) aligned) returns (bit (1));
97 dcl vtoc_man$crawlout entry;
98 dcl tty_lock$verify entry () returns (bit (1) aligned);
99 dcl syserr_seg_manager$verify_lock
100 entry () returns (bit (1) aligned);
101 dcl kstsrch entry (bit (36) aligned, fixed bin (17), ptr);
102 dcl page$write_volmap_page_unwired
103 entry (ptr, fixed bin);
104 dcl page$unlock_volmap entry (ptr);
105 dcl pmut$swap_sdw entry (ptr, ptr);
106 dcl pmut$read_mask entry (fixed bin (71));
107 dcl vtoce_stock_man$force_unlock
108 entry (ptr);
109
110 dcl pds$process_group_id
111 external char (32) aligned;
112 dcl pds$processid external bit (36) aligned;
113 dcl pds$block_lock_count
114 external fixed bin (17);
115 dcl scs$sys_level fixed bin (71) external static;
116 dcl error_table_$salv_pdir_procterm
117 external fixed bin (35);
118 dcl ahd$search_rules_lock
119 external;
120 dcl sst$astl bit (36) aligned external static;
121 dcl tc_data$system_shutdown
122 external bit (1) aligned;
123 dcl tc_data$lock_error_severity
124 fixed bin external static;
125 dcl pvt$n_entries fixed bin external static;
126 dcl volmap_abs_seg$ external static;
127
128 dcl seg_fault_error condition;
129 dcl page_fault_error condition;
130 dcl subscriptrange condition;
131
132 dcl (addr, addrel, baseptr, convert, hbound, null, unspec)
133 builtin;
134 %page;
135
136
137 cond_name = "r0 process termination";
138 check_masked = "0"b;
139 mcptr = null;
140 log_condition = "1"b;
141
142 start:
143 if debug_check ("crwl")
144 then call syserr (SYSERR_CRASH_SYSTEM, "verify_lock: Crawlout stop specified on PARM card.");
145
146 unlock_occurred = "0"b;
147 code = 0;
148
149 if (syserr_seg_manager$verify_lock ())
150 then call NOTE_UNLOCK ("syserr_log");
151
152 call VERIFY_PVT_LOCKS;
153
154 call VERIFY_VTOC_BUFFERS;
155
156 if (ioi_verify_lock ())
157 then unlock_occurred = "1"b;
158
159 call VERIFY_DBM;
160
161 call VERIFY_DM_JOURNAL_SEG;
162
163 if (get_pvtx$cleanup ())
164 then unlock_occurred = "1"b;
165
166 call VERIFY_DIR_LOCK_SEG;
167
168 call VERIFY_AST (code);
169 if code ^= 0
170 then call syserr (SYSERR_CRASH_SYSTEM, "verify_lock: Crawlout with AST lock set.");
171
172 call VERIFY_SEARCH_RULES;
173
174 if (tty_lock$verify ())
175 then unlock_occurred = "1"b;
176
177 dirs_locked.count = 0;
178 dirs_locked.seg_ptr (*) = null ();
179 dirs_locked.uid (*) = (36)"0"b;
180
181 call VERIFY_DIRECTORIES (code);
182 if code ^= 0
183 then call syserr (SYSERR_CRASH_SYSTEM, "verify_lock: Crawlout error on directory cleanup.");
184
185 call SALVAGE_DIRECTORIES;
186
187 if pds$block_lock_count ^= 0
188 then call syserr (SYSERR_CRASH_SYSTEM, "verify_lock: block_lock_count ^d, should be 0", pds$block_lock_count);
189
190 if check_masked
191 then call VERIFY_MASKED;
192
193
194 if log_condition & unlock_occurred
195 then if mcptr = null
196 then call syserr (SYSERR_LOG_OR_PRINT, "verify_lock: ^a condition by ^a", cond_name, pds$process_group_id);
197 else call make_syserr_message (cond_name, mcptr);
198
199 return;
200 %page;
201
202
203 verify_lock_bad_dir:
204 entry (a_mcptr);
205
206 cond_name = "bad_dir_";
207 mcptr = null;
208 check_masked = "1"b;
209 log_condition = "1"b;
210 go to start;
211
212 condition:
213 entry (a_name, a_mcptr);
214
215 dcl a_name char (*);
216 dcl a_mcptr ptr;
217
218 cond_name = a_name;
219 mcptr = a_mcptr;
220 check_masked = "1"b;
221 log_condition = "1"b;
222 go to start;
223
224
225
226
227
228 condition_nolog:
229 entry (a_name, a_mcptr);
230
231 cond_name = a_name;
232 mcptr = a_mcptr;
233 check_masked = "1"b;
234 log_condition = "0"b;
235 go to start;
236 %page;
237 VERIFY_VTOC_BUFFERS:
238 proc;
239
240 vtoc_buffer_segp = addr (vtoc_buffer_seg$);
241 lock_ptr = addr (vtoc_buffer.lock);
242
243 if lock.pid = pds$processid
244 then do;
245 call vtoc_man$crawlout;
246 call lock$unlock_fast (lock_ptr);
247 call NOTE_UNLOCK ("vtoc_buffer_seg");
248 end;
249 else call CHECK_NOTIFY (lock_ptr);
250 return;
251 end VERIFY_VTOC_BUFFERS;
252 %page;
253 VERIFY_DBM:
254 procedure;
255
256 %include dbm;
257 %page;
258 dbmp = addr (dbm_seg$);
259 lock_ptr = addr (dbm.lock_data);
260 if lock.pid = pds$processid
261 then do;
262 call lock$unlock_fast (lock_ptr);
263 call NOTE_UNLOCK ("dbm_seg");
264 end;
265 else call CHECK_NOTIFY (lock_ptr);
266 return;
267 end VERIFY_DBM;
268 %page;
269 VERIFY_DM_JOURNAL_SEG:
270 procedure;
271
272 %include dm_journal_seg_;
273 %page;
274 dm_journal_segp = addr (dm_journal_seg_$);
275 lock_ptr = addr (dm_journal.lock);
276 if lock.pid = pds$processid
277 then do;
278 call lock$unlock_fast (lock_ptr);
279 call NOTE_UNLOCK ("dm_journal_seg_");
280 end;
281 else call CHECK_NOTIFY (lock_ptr);
282 return;
283 end VERIFY_DM_JOURNAL_SEG;
284 %page;
285 VERIFY_DIR_LOCK_SEG:
286 procedure;
287
288 dir_lock_segp = addr (dir_lock_seg$);
289 lock_ptr = addr (dir_lock_seg.seg_lock);
290
291 if lock.pid = pds$processid
292 then do;
293 call NOTE_UNLOCK ("dir_lock_seg");
294 call lock$unlock_fast (lock_ptr);
295 end;
296 else call CHECK_NOTIFY (lock_ptr);
297 return;
298 end VERIFY_DIR_LOCK_SEG;
299
300
301
302 VERIFY_AST:
303 proc (code);
304
305 dcl code fixed bin (35);
306
307 lock_ptr = addr (sst$astl);
308
309 if lock.pid = pds$processid
310 then do;
311 code = 1;
312 end;
313 else call CHECK_NOTIFY (lock_ptr);
314 return;
315 end VERIFY_AST;
316 %page;
317
318
319
320
321 VERIFY_DIRECTORIES:
322 procedure (code);
323
324 dcl code fixed bin (35);
325 dcl i fixed bin (17);
326 dcl rx fixed bin;
327 dcl this_dir_locked bit (1) aligned;
328
329 code = 0;
330 dir_lock_segp = addr (dir_lock_seg$);
331 dir_lock_all_locksp = dir_lock_seg.header.locks_ptr;
332 dir_lock_all_readersp = dir_lock_seg.header.readers_ptr;
333
334 LOOP_OVER_DIRS:
335 do i = 1 to dir_lock_seg.header.highest_in_use;
336 this_dir_locked = "0"b;
337 dir_lockp = addr (dir_lock_all_dir_locks (i));
338 dir_read_lockers_ptr = addr (dir_lock_all_readers (i, 1));
339 if dir_lock.lock_count ^= 0
340 then do;
341 call lock$lock_fast (addr (dir_lock_seg.header.seg_lock));
342
343 if dir_lock.lock_count > 0
344 then if dir_lock.write_locker = pds$processid
345 then this_dir_locked = "1"b;
346 else ;
347 else if dir_lock.lock_count < 0
348 then
349 LOOP_OVER_LOCKERS:
350 do rx = 1 to hbound (dir_read_lockers, 1);
351 if dir_read_lockers (rx) = pds$processid
352 then this_dir_locked = "1"b;
353 end LOOP_OVER_LOCKERS;
354
355 call lock$unlock_fast (addr (dir_lock_seg.header.seg_lock));
356 if this_dir_locked
357 then call VERIFY_DIR (dir_lock.uid, (dir_lock.salvage_sw), (dir_lock.lock_count > 0));
358 end;
359
360 end LOOP_OVER_DIRS;
361 return;
362
363 end VERIFY_DIRECTORIES;
364
365
366 VERIFY_DIR:
367 procedure (uid, salvage_sw, write_sw) options (non_quick);
368
369 dcl uid bit (36) aligned;
370 dcl salvage_sw bit (1) aligned;
371 dcl write_sw bit (1) aligned;
372
373 dp = GET_SEG_PTR (uid);
374
375 if salvage_sw
376 then do;
377 call syserr (SYSERR_LOG_OR_PRINT, "verify_lock: Crawlout while in directory salvager, dir (^w,^p).",
378 uid, dp);
379 go to unlock_return;
380 end;
381
382 if dp = null
383 then go to unlock_return;
384
385 on seg_fault_error, page_fault_error go to NO_MODIFY_CHECK;
386 if (dir.modify ^= pds$processid) & (dir.modify ^= ""b)
387 then do;
388 call syserr (tc_data$lock_error_severity, "verify_lock: dir.modify ^p ^w ^^= processid.", dp,
389 dp -> dir.modify);
390 end;
391
392 NO_MODIFY_CHECK:
393 revert seg_fault_error, page_fault_error;
394
395 on subscriptrange
396 call syserr (SYSERR_CRASH_SYSTEM, "verify_lock: more than ^d directories locked to process.",
397 hbound (dirs_locked.seg_ptr, 1));
398
399 dirs_locked.count = dirs_locked.count + 1;
400 (subscriptrange):
401 dirs_locked.seg_ptr (dirs_locked.count) = dp;
402 revert subscriptrange;
403
404 dirs_locked.uid (dirs_locked.count) = uid;
405 unlock_return:
406 call syserr (SYSERR_LOG_OR_PRINT, "verify_lock: Unlocking dir ^w. Locked for ^[read^]^[write^]^[, salvage^].",
407 uid, ^write_sw, write_sw, salvage_sw);
408 unlock_occurred = "1"b;
409
410 call lock$dir_unlock_given_uid (uid);
411
412 end VERIFY_DIR;
413
414 SALVAGE_DIRECTORIES:
415 procedure;
416
417 declare dirx fixed bin;
418 declare uid bit (36) aligned;
419
420 if dirs_locked.count = 0
421 then return;
422
423 do dirx = 1 to dirs_locked.count;
424 call lock$dir_lock_salvage (dirs_locked.seg_ptr (dirx), uid, (0));
425
426
427 call syserr (SYSERR_LOG_OR_PRINT, "verify_lock: Salvaging dir ^p ^w on crawlout.", dp, uid);
428
429 call condition_ ("any_other", salvager_handler);
430
431 code = 0;
432
433 call on_line_salvager (dirs_locked.seg_ptr (dirx), code);
434
435 call reversion_ ("any_other");
436
437
438 if code = error_table_$salv_pdir_procterm
439 then call syserr$error_code (SYSERR_TERMINATE_PROCESS, code, "Terminating user process ^a: ",
440 pds$process_group_id);
441
442 CONTINUE_VERIFY_LOCK:
443 call lock$dir_unlock_given_uid (uid);
444 end;
445 return;
446
447 salvager_handler:
448 procedure (mc_ptr, condition_name, wc_ptr, info_ptr, continue_flag);
449
450 declare (mc_ptr, wc_ptr, info_ptr)
451 pointer;
452 declare condition_name character (*);
453 declare continue_flag bit (1) aligned;
454
455
456 call syserr (SYSERR_PRINT_ON_CONSOLE, "verify_lock: ^a condition by ^a while salvaging directory.",
457 condition_name, pds$process_group_id);
458
459 if mc_ptr ^= null
460 then call make_syserr_message (condition_name, mc_ptr);
461
462 go to CONTINUE_VERIFY_LOCK;
463
464 end salvager_handler;
465
466 end SALVAGE_DIRECTORIES;
467 %page;
468 VERIFY_PVT_LOCKS:
469 procedure;
470
471 pvt_arrayp = addr (pvt$array);
472 do pvtx = 1 to pvt$n_entries;
473
474 pvtep = addr (pvt_array (pvtx));
475
476 if pvte.vtoc_map_lock = pds$processid
477 then do;
478 call vtoce_stock_man$force_unlock (pvtep);
479 call syserr (SYSERR_LOG_OR_PRINT,
480 "verify_lock: Force unlocked VTOC Map lock (^a_^a^[^a^;^s^]) on crawlout for ^a", pvte.devname,
481 convert (p99, pvte.logical_area_number), pvte.is_sv, pvte.sv_name, pds$process_group_id);
482 pvte.vol_trouble_count = pvte.vol_trouble_count + 1;
483 tsdw = 0;
484 unlock_occurred = "1"b;
485 call pmut$swap_sdw (addr (volmap_abs_seg$), addr (tsdw));
486 end;
487
488 if pvte.volmap_lock = pds$processid
489 then do;
490 call pmut$swap_sdw (addr (volmap_abs_seg$), addr (pvte.volmap_seg_sdw));
491 record_stockp = pvte.volmap_stock_ptr;
492 do pagex = 0 to record_stock.n_volmap_pages;
493 call page$write_volmap_page_unwired (pvtep, pagex);
494 end;
495 call page$unlock_volmap (pvtep);
496 call syserr (SYSERR_LOG_OR_PRINT,
497 "verify_lock: Force unlocked Volmap lock (^a_^a^[^a^;^s^]) on crawlout for ^a", pvte.devname,
498 convert (p99, pvte.logical_area_number), pvte.is_sv, pvte.sv_name, pds$process_group_id);
499 tsdw = 0;
500 unlock_occurred = "1"b;
501 call pmut$swap_sdw (addr (volmap_abs_seg$), addr (tsdw));
502 end;
503
504 end;
505
506 end VERIFY_PVT_LOCKS;
507 %page;
508 VERIFY_SEARCH_RULES:
509 proc;
510
511 if tc_data$system_shutdown
512 then return;
513 lock_ptr = addr (ahd$search_rules_lock);
514 if lock.pid = pds$processid
515 then do;
516 call NOTE_UNLOCK ("search rules");
517 call lock$unlock_fast (lock_ptr);
518 end;
519 else call CHECK_NOTIFY (lock_ptr);
520 end VERIFY_SEARCH_RULES;
521
522
523
524 VERIFY_MASKED:
525 procedure;
526
527 declare mask fixed bin (71);
528
529 call pmut$read_mask (mask);
530 if mask = scs$sys_level
531 then call syserr (SYSERR_CRASH_SYSTEM, "verify_lock: Crawlout while masked.");
532
533 return;
534 end VERIFY_MASKED;
535
536
537 CHECK_NOTIFY:
538 proc (a_lock_ptr);
539
540 dcl a_lock_ptr ptr;
541
542 lock_ptr = a_lock_ptr;
543 if lock.pid = (36)"0"b & lock.flags.notify_sw = "1"b
544 then call pxss$notify (lock.event);
545 return;
546 end CHECK_NOTIFY;
547
548
549 NOTE_UNLOCK:
550 procedure (What_did_we_unlock);
551
552 declare What_did_we_unlock char (*);
553
554 call syserr (SYSERR_LOG_OR_PRINT, "verify_lock: Unlocked ^a.", What_did_we_unlock);
555 unlock_occurred = "1"b;
556 end NOTE_UNLOCK;
557
558
559 GET_SEG_PTR:
560 proc (uid) returns (ptr);
561
562 dcl uid bit (36) aligned;
563 dcl segptr ptr;
564
565 call kstsrch (uid, (0), kstep);
566 if kstep ^= null
567 then segptr = baseptr (kstep -> kste.segno);
568 else segptr = null;
569 return (segptr);
570 end GET_SEG_PTR;
571
572
573 make_syserr_message:
574 procedure (cond_name, mcptr);
575
576 dcl cond_name character (*);
577 dcl mcptr pointer;
578 dcl 1 auto_fault_msg aligned like fault_msg;
579 dcl ssptr pointer;
580
581 ssptr = addrel (mcptr, -8);
582
583 unspec (auto_fault_msg.mach_cond) = unspec (ssptr -> signaller_stack.mach_cond);
584 auto_fault_msg.hist_reg = ssptr -> signaller_stack.history_registers;
585 call syserr$binary (SYSERR_LOG_OR_PRINT, addr (auto_fault_msg), SB_verify_lock, SBL_verify_lock,
586 "verify_lock: ^a condition by ^a", cond_name, pds$process_group_id);
587
588
589 end make_syserr_message;
590
591
592
593 %page; %include dir_header;
594 %page; %include dir_lock_seg_;
595 %page; %include kst;
596 %page; %include pvte;
597 %page; %include signaller_stack;
598 %page; %include stock_seg;
599 %page; %include syserr_binary_def;
600 %page; %include syserr_constants;
601 %page; %include syserr_fault_msg;
602 %page; %include mc;
603 %page; %include vtoc_buffer;
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837 end verify_lock;