1
2
3
4
5
6
7
8
9
10
11
12
13
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 ^L
82 salvage_pv : procedure (a_pvtx, a_code);
83
84
85 dcl (a_pvtx, pvtx) fixed bin;
86 dcl (a_code, code) fixed bin (35);
87
88 dcl no_free_aste_err fixed bin (35) internal static init (1);
89 dcl get_vtocep_err fixed bin (35) internal static init (3);
90
91 dcl table1p ptr;
92 dcl table2p ptr;
93 dcl table3p ptr;
94 dcl table4p ptr;
95 dcl table5p ptr;
96 dcl table6p ptr;
97
98 dcl s_ptr ptr;
99
100 dcl r0 fixed bin;
101 dcl r1 fixed bin;
102 dcl ptp pointer;
103 dcl vtocx fixed bin;
104 dcl pvid bit (36) aligned;
105 dcl n_used_rec fixed bin;
106 dcl n_free_vtoce fixed bin;
107 dcl max_n_vtoc_seg fixed bin internal static init (4);
108 dcl damaged_count fixed bin;
109 dcl damaged_by_me fixed bin;
110 dcl salvage_call bit (1);
111 dcl previous_damaged_sw bit (1);
112 dcl complained bit (1);
113 dcl not_enabled_sw bit (1) aligned;
114 dcl free_count fixed bin;
115 dcl comp_time fixed bin (71);
116 dcl hdr_time (2) bit (36) aligned;
117 dcl root_pack bit (1) aligned;
118 dcl salv_mode char (32) var;
119 dcl p99 pic "99";
120 dcl curtime bit (36);
121 dcl trp_bad bit (1) aligned;
122
123
124 dcl 1 table1 based (table1p) aligned,
125 2 bit_table (0 : label.vol_size - 1) bit (1) unaligned;
126
127 dcl 1 table2 based (table2p) aligned,
128 2 vtocx_table (0 : label.vol_size - 1) fixed bin (17) unaligned;
129
130 dcl 1 table3 based (table3p) aligned,
131 2 new_map (1 : vol_map.map_n_words) bit (36) aligned;
132
133 dcl 1 table4 based (table4p) aligned,
134 2 incr_map (0 : vtoc_header.n_vtoce -1) bit (1) unaligned;
135
136 dcl 1 table5 based (table5p) aligned,
137 2 cons_map (0 : vtoc_header.n_vtoce -1) bit (1) unaligned;
138
139 dcl 1 salv_vtoc_map aligned based (table6p) like vtoc_map;
140
141 dcl sst$astl bit (36) aligned external;
142 dcl sst$astsize fixed bin external;
143 dcl sst$damaged_ct fixed bin external;
144 dcl 1 sst$level (0 : 3) aligned external,
145 2 ausedp bit (18) unaligned,
146 2 no_aste bit (18) unaligned;
147 dcl sst$pts (0 : 3) fixed bin external;
148 dcl sst$root_pvtx fixed bin external;
149
150 dcl pds$processid ext bit (36) aligned;
151
152 dcl dseg$ (0 : 1023) fixed bin (71) external static;
153 dcl pv_salv_seg$ ext;
154
155 dcl dir_dump$vtoce ext entry (ptr);
156 dcl get_aste entry (fixed bin) returns (ptr);
157 dcl get_ptrs_$given_astep entry (ptr) returns (fixed bin (71) aligned);
158 dcl get_ptrs_$given_segno entry (fixed bin) returns (ptr);
159 dcl get_pvtx$hold_pvtx entry (bit (36) aligned, fixed bin, fixed bin (35));
160 dcl get_pvtx$release_pvtx entry (bit (36) aligned, fixed bin (35));
161 dcl lock$lock_ast entry;
162 dcl lock$unlock_ast entry;
163 dcl page$cam entry;
164 dcl pc$truncate_deposit_all entry (ptr);
165 dcl pc_wired$write_wait entry (ptr, fixed bin, fixed bin);
166 dcl ptw_util_$make_null entry (pointer, bit (22) aligned);
167 dcl put_aste entry (ptr);
168 dcl salv_err_msg entry options (variable);
169 dcl salv_err_msg$code entry options (variable);
170 dcl syserr entry options (variable);
171 dcl syserr$binary ext entry options (variable);
172 dcl thread$out entry (ptr, bit (18));
173 dcl vm_vio$clean_up entry (fixed bin);
174 dcl vm_vio$get_vtocep entry (fixed bin, fixed bin) returns (ptr);
175 dcl vm_vio$init entry (fixed bin, fixed bin (35)) returns (ptr);
176
177 dcl cleanup condition;
178 dcl (addr, addrel, baseno, bin, bit, ceil, clock, convert, divide, fixed, max, mod, null, ptr, rel, substr, unspec) builtin;
179
180 ^L
181
182
183 salvage_call = "1"b;
184 salv_mode = "Volume salvage";
185 goto COMMON;
186
187 convert_vtoc:
188 entry (a_pvtx, a_code);
189
190 salvage_call = "0"b;
191 salv_mode = "VTOC conversion";
192
193 COMMON:
194 pvtx = a_pvtx;
195 code = 0;
196 pvt_arrayp = addr (pvt$array);
197 pvtep = addr (pvt_array (pvtx));
198 curtime = substr (bit (bin (clock (), 71), 71), 20, 36);
199
200 on cleanup call CLEAN_UP;
201
202 s_ptr = vm_vio$init (pvtx, code); if code ^= 0 then goto RTN;
203
204 labelp = ptr (s_ptr, LABEL_ADDR * 1024);
205 vol_mapp = ptr (s_ptr, VOLMAP_ADDR * 1024);
206 vtoc_headerp = ptr (s_ptr, DUMPER_BIT_MAP_ADDR * 1024);
207 vtoc_mapp = ptr (s_ptr, VTOC_MAP_ADDR * 1024);
208
209 pvid = label.pvid;
210
211
212 call salv_err_msg (SALV_ANNOUNCE, "salvage_pv: ^a of ^a_^a, volume ^a of logical vol ^a.",
213 salv_mode, pvte.devname, (convert (p99, pvte.logical_area_number) || pvte.sv_name),
214 label.pv_name, label.lv_name);
215
216 comp_time = clock ();
217
218 if salvage_call then do;
219 call CHECK_LABEL_VOLMAP_HEADER (code); if code ^= 0 then goto CLEAN;
220 n_used_rec = 0;
221 free_count = 0;
222
223 r0 = vol_map.base_add;
224 r1 = vol_map.n_rec - 1 + r0;
225 end;
226
227 damaged_count = 0;
228 damaged_by_me = 0;
229
230 call INIT_TABLES (table1p, table2p, table3p, table4p, table5p, table6p, code); if code ^= 0 then goto CLEAN;
231
232 n_free_vtoce = 0;
233
234 if label.volmap_version = 1
235 | label.volmap_version = 2
236 then do;
237 salv_vtoc_map.n_vtoce = vtoc_map.n_vtoce;
238 salv_vtoc_map.n_free_vtoce = vtoc_map.n_free_vtoce;
239 salv_vtoc_map.bit_map_n_words = vtoc_map.bit_map_n_words;
240 salv_vtoc_map.vtoc_last_recno = vtoc_map.vtoc_last_recno;
241 end;
242 else do;
243 salv_vtoc_map.n_vtoce = vtoc_header.n_vtoce;
244 salv_vtoc_map.n_free_vtoce = vtoc_header.n_free_vtoce;
245 salv_vtoc_map.bit_map_n_words
246 = divide (vtoc_header.n_vtoce + 31, 32, 17);
247 salv_vtoc_map.vtoc_last_recno = vtoc_header.vtoc_last_recno;
248 end;
249
250
251 do vtocx = 0 to vtoc_header.n_vtoce - 1;
252
253 vtocep = vm_vio$get_vtocep (pvtx, vtocx);
254 if vtocep = null then do;
255 code = get_vtocep_err;
256 goto CLEAN;
257 end;
258
259
260 if vtoce.uid = "0"b then do;
261 vtoce.pad_free_vtoce_chain = ""b;
262 if vtoce_parts (1) ^= "0"b then call salv_err_msg (SALV_DEBUG,
263 "salvage_pv: vtoce ^oo free but not zero", vtocx);
264 call FREE_VTOCE;
265 end;
266 else if salvage_call then do;
267 complained = "0"b;
268 previous_damaged_sw = vtoce.damaged;
269 if ^vtoce.dirsw then do;
270 if vtoce.per_process then do;
271 if salv_data$debug then call salv_err_msg (SALV_DEBUG,
272 "salvage_pv: freeing ^w per process vtocx ^oo: ^a",
273 vtoce.uid, vtocx, vtoce.primary_name);
274 call FREE_VTOCE;
275 go to NEXT_VTOCE;
276 end;
277 else if vtoce.deciduous then do;
278 if salv_data$debug then call salv_err_msg (SALV_DEBUG,
279 "salvage_pv: freeing ^w deciduous vtocx ^oo: ^a",
280 vtoce.uid, vtocx, vtoce.primary_name);
281 call FREE_VTOCE;
282 go to NEXT_VTOCE;
283 end;
284 else if vtoce.perm_flags.per_bootload then do;
285 if salv_data$debug then call salv_err_msg (SALV_DEBUG,
286 "salvage_pv: freeing ^w per-bootload vtocx ^oo: ^a",
287 vtoce.uid, vtocx, vtoce.primary_name);
288 call FREE_VTOCE;
289 goto NEXT_VTOCE;
290 end;
291 end;
292 call CHECK_VTOCE;
293 if previous_damaged_sw & ^complained
294 then call salv_err_msg (SALV_DEBUG, "salvage_pv: damaged switch found on for ^w vtocx ^oo: ^a",
295 vtoce.uid, vtocx, vtoce.primary_name);
296 if vtoce.damaged then do;
297 damaged_count = damaged_count + 1;
298 if ^previous_damaged_sw
299 then damaged_by_me = damaged_by_me + 1;
300 if complained then do;
301 segdamage.pvid = label.pvid;
302 segdamage.lvid = label.lvid;
303 segdamage.uid = vtoce.uid;
304 segdamage.vtocx = vtocx;
305 segdamage.pno = -1;
306 segdamage.uid_path = vtoce.uid_path;
307 call syserr$binary (SALV_LOG, addr (segdamage), SB_vtoc_salv_dam, SBL_vtoc_salv_dam,
308 "salvage_pv: setting damaged switch on ^a (^oo) on pv ^a.",
309 vtoce.primary_name, vtocx, label.pv_name);
310 sst$damaged_ct = sst$damaged_ct + 1;
311 end;
312 end;
313
314 end;
315 NEXT_VTOCE:
316 end;
317
318 if salvage_call
319 then do;
320 call UPDATE_VOL_MAP;
321 pvte.vol_trouble_count = 0;
322 end;
323
324 call UPDATE_VTOC_MAP;
325
326 call FORCE_VTOC_ON_DISK;
327
328 call UPDATE_LABEL;
329
330 call FORCE_LABEL_ON_DISK;
331
332 if free_count > 0 then call salv_err_msg (SALV_DEBUG, "salvage_pv: ^d free vtoces added to free list.", free_count);
333 if damaged_count > 0
334 then call salv_err_msg (SALV_ANNOUNCE,
335 "salvage_pv: ^d damaged segments on volume ^a (^d damaged in this salvage)",
336 damaged_count, label.pv_name, damaged_by_me);
337 CLEAN: if code = 0 then call salv_err_msg (SALV_DEBUG, "salvage_pv: ^a finished.", salv_mode);
338 else call salv_err_msg$code (SALV_DEBUG, "", "salvage_pv: ^a finished with error.", code, salv_mode);
339 call CLEAN_UP;
340
341 RTN: a_code = code;
342
343 return;
344 ^L
345 CHECK_VTOCE : proc;
346
347 dcl (records, csl, msl, i, r, conflict) fixed bin;
348
349 csl, records, conflict = 0;
350 msl = 256;
351
352 do i = 0 to msl - 1;
353
354 SAME_I: if substr (vtoce.fm (i), 1, 1) = "1"b then goto NEXT_I;
355
356 r = fixed (substr (vtoce.fm (i), 2, 17), 17);
357
358 if r < r0 | r > r1 then
359 do;
360 call report_out_of_range;
361 vtoce.fm (i) = pv_salv_null_addr; goto NEXT_I;
362 end;
363
364 if bit_table (r) = "1"b then
365 do;
366 conflict = 1; call RESOLVE_CONFLICT (i); goto SAME_I;
367 end;
368
369 vtocx_table (r) = vtocx;
370 bit_table (r) = "1"b;
371 records = records + 1;
372 csl = i + 1;
373 NEXT_I:
374 end;
375
376 do i = msl to 255;
377 if substr (vtoce.fm (i), 1, 1) = "0"b then vtoce.fm (i) = pv_salv_null_addr;
378 end;
379
380 if conflict ^= 0 then do; csl = RECOMPUTE_CSL (vtocep); records = RECOMPUTE_RECORDS (vtocep); end;
381
382 n_used_rec = n_used_rec + records;
383
384 if fixed (vtoce.records, 9) ^= records then
385 do;
386 call report_records;
387 vtoce.records = bit (fixed (records, 9));
388 end;
389
390 if fixed (vtoce.csl, 9) ^= csl then
391 do;
392 call report_csl;
393 vtoce.csl = bit (fixed (csl, 9));
394 end;
395
396 if fixed (vtoce.msl, 9) > msl | fixed (vtoce.msl, 9) < csl then
397 do;
398 call report_msl;
399 vtoce.msl = bit (fixed (msl, 9));
400 end;
401
402 trp_bad = "0"b;
403 do i = 0 to 1;
404 if vtoce.trp (i) < 0 | fixed (vtoce.trp_time (i), 36) > fixed (curtime, 36)
405 then trp_bad = "1"b;
406 end;
407 if trp_bad then do;
408 call report_trp;
409 do i = 0 to 1;
410 vtoce.trp (i) = 0;
411 vtoce.trp_time = curtime;
412 end;
413 end;
414
415 if vtoce.dirsw then if ^root_pack then do;
416 call salv_err_msg (SALV_DEBUG,
417 "salvage_pv: dirsw turned off for vtocx ^oo: ^a", vtocx, vtoce.primary_name);
418 if salv_data$dump then call dir_dump$vtoce (vtocep);
419 vtoce.dirsw = "0"b;
420 vtoce.damaged, complained = "1"b;
421 end;
422
423 vtoce.fm_damaged = "0"b;
424 vtoce.fm_checksum_valid = "0"b;
425 vtoce.fm_checksum = ""b;
426
427 if fixed (vtoce.dtm) > fixed (hdr_time (1)) then call THREAD_FOR_DUMPER (1);
428 if fixed (vtoce.dtm) > fixed (hdr_time (2)) then call THREAD_FOR_DUMPER (2);
429
430 return;
431
432
433
434
435 report_out_of_range : proc;
436 call salv_err_msg (SALV_DEBUG, "salvage_pv: vtoce ^a at ^oo: page ^oo disk_addr ^oo bad",
437 vtoce.primary_name, vtocx, i, r);
438 vtoce.damaged, complained = "1"b;
439 return;
440 end;
441
442 report_records : proc;
443 call salv_err_msg (SALV_DEBUG, "salvage_pv: vtoce ^a at ^oo: rec used changed from ^oo to ^oo",
444 vtoce.primary_name, vtocx, fixed (vtoce.records), records);
445 vtoce.damaged, complained = "1"b;
446 return;
447 end;
448
449 report_csl : proc;
450 call salv_err_msg (SALV_DEBUG, "salvage_pv: vtoce ^a at ^oo: cur len changed from ^oo to ^oo",
451 vtoce.primary_name, vtocx, fixed (vtoce.csl), csl);
452 vtoce.damaged, complained = "1"b;
453 return;
454 end;
455
456 report_msl : proc;
457 call salv_err_msg (SALV_DEBUG, "salvage_pv: vtoce ^a at ^oo: max len changed from ^oo to ^oo",
458 vtoce.primary_name, vtocx, fixed (vtoce.msl), msl);
459 vtoce.damaged, complained = "1"b;
460 return;
461 end;
462
463 report_trp: proc;
464 call salv_err_msg (SALV_DEBUG, "salvage_pv: vtoce ^a at ^oo: time-record-product reset to zero",
465 vtoce.primary_name, vtocx);
466 return;
467 end;
468
469 end CHECK_VTOCE;
470
471
472
473 ^L
474
475 FREE_VTOCE : proc;
476
477 dcl bit_no fixed bin;
478 dcl word_no fixed bin;
479
480 if vtoce.uid ^= "0"b then free_count = free_count + 1;
481
482 unspec (vtoce) = "0"b;
483
484 n_free_vtoce = n_free_vtoce + 1;
485
486 word_no = divide (vtocx, 32, 17);
487 bit_no = mod (vtocx, 32);
488 bit_map_wordp = addr (salv_vtoc_map.bit_map (word_no));
489 substr (bit_map_word.bits, bit_no + 1, 1) = "1"b;
490
491 call THREAD_FOR_DUMPER (2);
492
493 return;
494
495 end FREE_VTOCE;
496
497
498 THREAD_FOR_DUMPER: proc (index);
499
500 dcl index fixed bin;
501
502 if not_enabled_sw then return;
503
504 if index = 1 then
505 incr_map (vtocx) = "1"b;
506 else
507 cons_map (vtocx) = "1"b;
508
509 return;
510
511 end THREAD_FOR_DUMPER;
512
513 ^L
514 RESOLVE_CONFLICT : proc (i);
515
516 dcl (i, I, r, VTOCX, del, DEL) fixed bin;
517
518 dcl VTOCEP ptr;
519 dcl 1 VTOCE like vtoce aligned based (VTOCEP);
520
521
522
523 r = fixed (substr (vtoce.fm (i), 2, 17), 17);
524
525 VTOCX = vtocx_table (r);
526 VTOCEP = vm_vio$get_vtocep (pvtx, VTOCX);
527
528 do I = 0 to 255 while (VTOCE.fm (I) ^= vtoce.fm (i));
529 end;
530
531 if I > 255 then go to del_eq_1;;
532
533 DEL, del = 0;
534
535 if vtoce.dirsw = VTOCE.dirsw then DEL, del = 1;
536 if vtoce.dirsw & ^VTOCE.dirsw then DEL = 1;
537 if ^vtoce.dirsw & VTOCE.dirsw then del = 1;
538
539 if del = 1 then
540 del_eq_1: do;
541 call report_page_del;
542 vtoce.fm (i) = pv_salv_null_addr;
543 end;
544
545 if DEL = 1 then
546 do;
547 call report_page_DEL;
548 vtocx_table (r) = 0;
549 bit_table (r) = "0"b;
550
551 VTOCE.fm (I) = pv_salv_null_addr;
552
553 if vtocep ^= VTOCEP then
554 do;
555 VTOCE.csl = bit (fixed (RECOMPUTE_CSL (VTOCEP), 9));
556 VTOCE.records = bit (fixed (fixed (VTOCE.records, 9) - 1, 9), 9);
557
558 n_used_rec = n_used_rec - 1;
559 end;
560 end;
561
562 return;
563 ^L
564 report_page_del : proc;
565 call salv_err_msg (SALV_DEBUG,
566 "salvage_pv: vtoce ^a at ^oo: ref to pageno ^oo at addr ^oo deleted, dirsw is ^b",
567 vtoce.primary_name, vtocx, i, r, vtoce.dirsw);
568 vtoce.damaged, complained = "1"b;
569 return;
570 end;
571
572 report_page_DEL : proc;
573 call salv_err_msg (SALV_DEBUG,
574 "salvage_pv: vtoce ^a at ^oo: ref to pageno ^oo at addr ^oo deleted, dirsw is ^b",
575 VTOCE.primary_name, VTOCX, I, r, VTOCE.dirsw);
576 if ^VTOCE.damaged & VTOCX < vtocx then do;
577 damaged_count = damaged_count + 1;
578 damaged_by_me = damaged_by_me + 1;
579 end;
580 if VTOCE.damaged | VTOCX > vtocx then return;
581 segdamage.pvid = label.pvid;
582 segdamage.lvid = label.lvid;
583 segdamage.uid = VTOCE.uid;
584 segdamage.vtocx = VTOCX;
585 segdamage.pno = I;
586 segdamage.uid_path = VTOCE.uid_path;
587 call syserr$binary (SALV_LOG, addr (segdamage), SB_vtoc_salv_dam, SBL_vtoc_salv_dam,
588 "salvage_pv: setting damaged switch on ^a (^oo) on pv ^a.",
589 VTOCE.primary_name, VTOCX, label.pv_name);
590 sst$damaged_ct = sst$damaged_ct + 1;
591 VTOCE.damaged = "1"b;
592 return;
593 end;
594
595 end RESOLVE_CONFLICT;
596
597
598
599
600 RECOMPUTE_CSL : proc (vtoce_ptr) returns (fixed bin);
601
602 dcl vtoce_ptr ptr;
603 dcl (i, csl) fixed bin;
604
605 csl = 0;
606 do i = 0 to 255; if substr (vtoce_ptr -> vtoce.fm (i), 1, 1) = "0"b then csl = i + 1;
607 end;
608 return (csl);
609
610 end RECOMPUTE_CSL;
611
612
613
614 RECOMPUTE_RECORDS : proc (vtoce_ptr) returns (fixed bin);
615
616 dcl vtoce_ptr ptr;
617 dcl (i, records) fixed bin;
618
619 records = 0;
620 do i = 0 to 255; if substr (vtoce_ptr -> vtoce.fm (i), 1, 1) = "0"b then records = records + 1;
621 end;
622 return (records);
623
624 end RECOMPUTE_RECORDS;
625 ^L
626 CHECK_LABEL_VOLMAP_HEADER: proc (code);
627
628 dcl code fixed bin (35);
629 dcl rightsize fixed bin (24);
630
631
632 code = 0;
633
634 if label.time_last_dmp (1) = 0 then not_enabled_sw = "1"b;
635 else do;
636 if comp_time < max (label.time_mounted, label.time_map_updated,
637 label.time_unmounted, label.time_salvaged, label.time_of_boot) then do;
638 call salv_err_msg (SALV_ANNOUNCE,
639 "salvage_pv: Label times in advance of clock. The clock may be wrong.");
640 end;
641 end;
642
643 hdr_time (1) = substr(bit (fixed (label.time_last_dmp (1), 52), 52),1,36);
644 hdr_time (2) = substr(bit (fixed (label.time_last_dmp (2), 52), 52),1,36);
645
646 root_pack = (label.lv_name = "root");
647
648 rightsize = ceil (vol_map.n_rec/32);
649 if vol_map.bit_map_n_words ^= rightsize then do;
650 call salv_err_msg (SALV_DEBUG,
651 "salvage_pv: Bit map size is ^d. (^oo) words, s/b ^d. (^oo), changing to latter.",
652 vol_map.bit_map_n_words, vol_map.bit_map_n_words, rightsize, rightsize);
653 vol_map.bit_map_n_words = rightsize;
654 end;
655
656
657
658
659
660 return;
661
662 end CHECK_LABEL_VOLMAP_HEADER;
663
664
665
666 UPDATE_VOL_MAP : proc;
667
668 dcl 1 old_map (vol_map.bit_map_n_words) based (addr (vol_map.bit_map)) aligned,
669 2 pad1 bit (1) unaligned,
670 2 bits bit (32) unaligned,
671 2 pad2 bit (3) unaligned;
672
673 dcl 1 new_map (vol_map.bit_map_n_words) based (table3p) aligned like old_map;
674
675 dcl bit_table_map (1000) bit (32) based (addr (bit_table (r0))) unaligned;
676
677 dcl w fixed bin;
678 dcl j fixed bin;
679 dcl n_free_rec fixed bin;
680
681
682
683 unspec (new_map) = "0"b;
684
685 do w = 1 to vol_map.bit_map_n_words;
686 new_map (w).bits = ^ bit_table_map (w);
687 end;
688
689 j = mod (vol_map.n_rec, 32);
690 if j ^= 0 then substr (new_map (w - 1).bits, j + 1) = "0"b;
691
692 if unspec (old_map) ^= unspec (new_map) then
693 do;
694 call report_bit_map_changed;
695 unspec (old_map) = unspec (new_map);
696 end;
697
698 n_free_rec = vol_map.n_rec - n_used_rec;
699
700 if vol_map.n_free_rec ^= n_free_rec then
701 do;
702 call report_n_free_rec_changed;
703 vol_map.n_free_rec = n_free_rec;
704 end;
705 return;
706
707
708 report_bit_map_changed : proc;
709 call salv_err_msg (SALV_DEBUG, "salvage_pv: map of assigned addresses changed");
710 return;
711 end;
712
713 report_n_free_rec_changed : proc;
714 call salv_err_msg (SALV_DEBUG, "salvage_pv: no. of free recs changed from ^d to ^d",
715 vol_map.n_free_rec, n_free_rec);
716 return;
717 end;
718
719 end UPDATE_VOL_MAP;
720 ^L
721 UPDATE_VTOC_MAP : proc;
722
723 if (salv_vtoc_map.n_free_vtoce ^= n_free_vtoce) & salvage_call
724 then call report_n_free_vtoce;
725 salv_vtoc_map.n_free_vtoce = n_free_vtoce;
726
727 unspec (vtoc_map) = unspec (salv_vtoc_map);
728
729 return;
730
731
732 report_n_free_vtoce : proc;
733 call salv_err_msg (SALV_DEBUG, "salvage_pv: no. of free vtoces changed from ^d to ^d",
734 salv_vtoc_map.n_free_vtoce, n_free_vtoce);
735 return;
736 end;
737
738 end UPDATE_VTOC_MAP;
739
740
741
742
743
744
745
746 FORCE_VTOC_ON_DISK : proc;
747
748 dcl i fixed bin;
749
750
751 do i = 1 to max_n_vtoc_seg - 1;
752 astep = get_ptrs_$given_segno (fixed (baseno (s_ptr)) + i);
753 if astep ^= null then call pc_wired$write_wait (astep, 0, -1);
754 end;
755
756 return;
757
758 end FORCE_VTOC_ON_DISK;
759 ^L
760 UPDATE_LABEL : proc;
761
762 label.time_map_updated = comp_time;
763 label.time_salvaged = comp_time;
764
765
766 label.vol_trouble_count = 0;
767
768 if label.volmap_version ^= 1 then do;
769 if label.volmap_version ^= 2
770 then do;
771 old_labelp = labelp;
772 label.time_unmounted = old_label.time_unmounted;
773 end;
774 label.volmap_version = 1;
775
776 end;
777
778 return;
779
780 end UPDATE_LABEL;
781
782
783
784
785
786
787
788 FORCE_LABEL_ON_DISK : proc;
789
790
791 astep = get_ptrs_$given_segno (fixed (baseno (s_ptr)));
792
793 if astep ^= null then call pc_wired$write_wait (astep, LABEL_ADDR, 1);
794
795 return;
796
797 end FORCE_LABEL_ON_DISK;
798 ^L
799 CLEAN_UP : proc;
800
801
802 dcl segno fixed bin;
803
804
805 segno = fixed (baseno (addr (pv_salv_seg$)), 18);
806
807 astep = get_ptrs_$given_segno (segno);
808
809 if astep ^= null then
810 do;
811
812 dseg$ (segno) = 0;
813 call page$cam;
814
815 call pc$truncate_deposit_all (astep);
816 if aste.usedf then call get_pvtx$release_pvtx ((pvt_array.pvid (aste.pvtx)), (aste.pvtx));
817 if sst$astl ^= pds$processid then call lock$lock_ast;
818 call put_aste (astep);
819 call lock$unlock_ast;
820
821
822 end;
823
824 call vm_vio$clean_up (pvtx);
825
826 return;
827
828 end CLEAN_UP;
829 ^L
830 INIT_TABLES : proc (table1p, table2p, table3p, table4p, table5p, table6p, code);
831
832 dcl table1p ptr;
833 dcl table2p ptr;
834 dcl table3p ptr;
835 dcl table4p ptr;
836 dcl table5p ptr;
837 dcl table6p ptr;
838 dcl code fixed bin (35);
839
840 dcl 1 pv_salv_seg based (addr (pv_salv_seg$)) aligned,
841
842 2 table1,
843 3 bit_table (0 : label.vol_size - 1) bit (1) unaligned,
844
845 2 table2,
846 3 vtocx_table (0 : label.vol_size - 1) fixed bin (17) unaligned,
847
848 2 table3,
849 3 new_map (1 : vol_map.bit_map_n_words) bit (36) aligned,
850
851 2 table4,
852 3 incr_map (0 : vtoc_header.n_vtoce -1) bit (1) unaligned,
853
854 2 table5,
855 3 cons_map (0 : vtoc_header.n_vtoce -1) bit (1) unaligned,
856
857 2 table6 aligned like vtoc_map,
858
859 2 end bit (36) aligned;
860
861 dcl segno fixed bin,
862 pvtx fixed bin,
863 msl fixed bin;
864
865 dcl (i, pts, ptsi) fixed bin;
866
867 dcl tsdw fixed bin (71);
868
869
870 code = 0;
871
872 segno = fixed (baseno (addr (pv_salv_seg$)), 18);
873 pvtx = sst$root_pvtx;
874 msl = divide (fixed (rel (addr (pv_salv_seg.end)), 18), 1024, 17, 0) + 1;
875
876
877
878
879 call lock$lock_ast;
880
881 astep = get_aste (msl);
882
883 if astep = null then
884 do;
885 call lock$unlock_ast;
886 code = no_free_aste_err;
887 call syserr (ANNOUNCE, "salvage_pv: INIT_TABLES: aste pool ^oo too small", msl);
888 return;
889 end;
890
891 ptsi = fixed (aste.ptsi);
892 pts = sst$pts (ptsi);
893
894
895
896
897 astep -> aste_part.two = "0"b;
898
899
900
901
902 ptp = addrel (astep, sst$astsize);
903
904 do i = 0 to pts - 1;
905 call ptw_util_$make_null (addrel (ptp, i), fill_page_table_null_addr);
906 end;
907
908
909
910
911 astep -> aste.vtocx = -1;
912 astep -> aste.dnzp = "1"b;
913 astep -> aste.nqsw = "1"b;
914 astep -> aste.strp = bit (fixed (segno, 18), 18);
915 astep -> aste.msl = bit (fixed (msl, 9), 9);
916 astep -> aste.pvtx = pvtx;
917
918
919
920
921 tsdw = get_ptrs_$given_astep (astep);
922 dseg$ (segno) = tsdw;
923 call page$cam;
924
925
926 call get_pvtx$hold_pvtx ((pvt_array.pvid (pvtx)), pvtx, (0));
927 astep -> aste.usedf = "1"b;
928
929 call thread$out (astep, sst$level (ptsi).ausedp);
930
931 call lock$unlock_ast;
932
933
934
935
936 table1p = addr (pv_salv_seg.table1);
937 table2p = addr (pv_salv_seg.table2);
938 table3p = addr (pv_salv_seg.table3);
939 table4p = addr (pv_salv_seg.table4);
940 table5p = addr (pv_salv_seg.table5);
941 table6p = addr (pv_salv_seg.table6);
942
943 return;
944
945 end INIT_TABLES;
946
947 %page; %include aste;
948 %page; %include disk_pack;
949 %page; %include fs_vol_label;
950 %page; %include null_addresses;
951 %page; %include old_fs_vol_label;
952 %page; %include pvte;
953 %page; %include salv_data;
954 %page; %include salvager_severities;
955 %page; %include segdamage_msg;
956 %page; %include syserr_binary_def;
957 %page; %include syserr_constants;
958 %page; %include vol_map;
959 %page; %include vtoc_header;
960 %page; %include vtoc_map;
961 %page; %include vtoce;
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392 end salvage_pv;