1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) BULL HN Information Systems Inc., 1989   *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Bull Inc., 1987                *
  6         *                                                         *
  7         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  8         *                                                         *
  9         * Copyright (c) 1972 by Massachusetts Institute of        *
 10         * Technology and Honeywell Information Systems, Inc.      *
 11         *                                                         *
 12         *********************************************************** */
 13 
 14 
 15 
 16 /****^  HISTORY COMMENTS:
 17   1) change(86-01-15,Fawcett), approve(86-04-11,MCR7383),
 18      audit(86-06-03,GWMay), install(86-07-17,MR12.0-1097):
 19      Add support for 512_WORD_IO devices.
 20   2) change(88-10-05,GWMay), approve(88-10-05,MCR8005), audit(88-10-12,Farley),
 21      install(88-10-17,MR12.2-1173):
 22      Added administrative calls to support one additional temporary work
 23      segment. Changed the call to reload_volume_ to used the correct number of
 24      parameters.
 25   3) change(89-08-31,GWMay), approve(89-10-03,MCR8135),
 26      audit(89-10-04,Beattie), install(89-10-10,MR12.3-1089):
 27      Updated to process version 3 for backup_volume_log.incl.pl1 structures.
 28                                                    END HISTORY COMMENTS */
 29 
 30 
 31 /* format: style1,ind2,^inddcls,ifthenstmt,dclind2,declareind2,ifthendo,ifthen*/
 32 
 33 reloader: proc;
 34 
 35 /* This routine is the main control program of the volume reloader. We initialize  the control
 36    structure, and read and process the control arguments. We then get info about the physical volume to
 37    be reloaded and calculate some parameters that are used to convert disk sector address
 38    to Multics record numbers.  We then create the needed temp segs and set the external pointers.
 39    We then create the control seg which will be used to restart the reload if it should be interrupted. Next we
 40    determine the list of dump volumes that must be read and in what order to recreate the logical image the
 41    the physical volume to be reloaded. We then initialize the output attachment and initialize the label,
 42    volume map, and vtoc header data bases. Finally we compare the label info in the volume log with that on the
 43    pre-initialized output medium and if we find a problems we query the operator as to whether he wants
 44    to proceed. If so we reload the physical volume, build the VTOC map, and update
 45    the vtoc header, the volume map, and the label. Just a nice straigth foward program. */
 46 
 47 /*
 48    Modified April 1982 by J. Bongiovanni for new pack layout
 49    Modified Feburary 1983 by E. N. Kittlitz for 256K segments.
 50    Modified 3/1/83 by GA Texada for multiple physical volume reloading.
 51    Modified 3/5/84 by GA Texada to fix hardcore 630, which simply deletes the
 52             control seg when no -restart specified and one exisites. Changed
 53             to continue the reload and make restart a per pv attribute.
 54    Modified 3/6/84 by GA Texada to allow for reloading of 'stranger' physical volumes.
 55 
 56 */
 57 
 58 reload_volume: entry;
 59 
 60 dcl Area                 area based (areap);
 61 dcl (areap, argp)        ptr;
 62 dcl (code, ignore)       fixed bin (35);
 63 dcl dev_idx              fixed bin;
 64 dcl lvname               char (32) aligned;
 65 dcl time_string          char (24);
 66 dcl (ename, control_name) char (32);
 67 dcl (cln, enl, i, pvindex, vtocx) fixed bin;
 68 dcl mounted_rpv_pvid     bit (36);
 69 dcl time_unmounted       fixed bin (71);
 70 dcl (YES, found_restart, dont_query_restart, pvid_missing, version_1_found, volog_missing) bit (1);
 71 
 72 dcl 1 local_vtoce        like vtoce aligned;
 73 
 74 dcl tp2                  (2) ptr;
 75 dcl tp6                  (6) ptr;
 76 
 77 dcl error_table_$entlong fixed bin (35) ext;
 78 dcl error_table_$improper_data_format ext fixed bin (35);
 79 dcl error_table_$namedup ext fixed bin (35);
 80 dcl error_table_$segknown ext fixed bin (35);
 81 dcl sys_info$seg_size_256K fixed bin (19) ext static;
 82 dcl myname               char (32) static int init ("reload_volume") options (constant);
 83 
 84 dcl hcs_$initiate        entry (char (*), char (*), char (*), fixed bin, fixed bin, ptr, fixed bin (35));
 85 dcl hcs_$set_max_length_seg entry (ptr, fixed bin (19), fixed bin (35));
 86 dcl ioa_$rsnnl           entry options (variable);
 87 dcl hcs_$level_get       entry returns (fixed bin);
 88 dcl get_group_id_        entry returns (char (32));
 89 dcl get_system_free_area_ entry () returns (ptr);
 90 dcl hcs_$delentry_seg    entry (ptr, fixed bin (35));
 91 dcl hcs_$make_seg        entry (char (*), char (*), char (*), fixed bin (5), ptr, fixed bin (35));
 92 dcl hcs_$fs_search_get_wdir entry (ptr, fixed bin (35));
 93 dcl hcs_$set_256K_switch entry (bit (2) aligned, bit (2) aligned, fixed bin (35));
 94 dcl cu_$arg_list_ptr     entry (ptr);
 95 dcl command_query_$yes_no entry options (variable);
 96 dcl mdc_$pvname_info     entry (char (*) aligned, bit (36) aligned, char (*) aligned, bit (36) aligned,
 97                          fixed bin, fixed bin (35));
 98 dcl rldr_arg_reader_     entry (ptr, ptr, fixed bin (35));
 99 dcl rldr_check_pvol_     entry (ptr, fixed bin, fixed bin (35));
100 dcl rldr_label_$open     entry (ptr, fixed bin, fixed bin (35));
101 dcl rldr_label_$close    entry (ptr, fixed bin, fixed bin (35));
102 dcl get_temp_segments_   entry (char (*), (*) ptr, fixed bin (35));
103 dcl date_time_           entry (fixed bin (71), char (*));
104 dcl rldr_input_$init_volume_list entry (ptr, fixed bin (35));
105 dcl rldr_output_$init    entry (ptr, fixed bin, fixed bin (35));
106 dcl reload_volume_       entry (ptr, fixed bin (35));
107 dcl rldr_vtoc_header_$open entry (ptr, fixed bin, fixed bin (35));
108 dcl rldr_vtoc_header_$close entry (ptr, fixed bin, fixed bin (35));
109 dcl rldr_vtoc_header_$build_vtoc_map entry (ptr, fixed bin, fixed bin (35));
110 dcl rldr_volume_map_$open entry (ptr, fixed bin, fixed bin (35));
111 dcl rldr_volume_map_$close entry (ptr, fixed bin, fixed bin (35));
112 dcl rldr_finish_         entry (ptr, ptr, fixed bin (35));
113 dcl rldr_report_$error_output entry options (variable);
114 dcl rldr_report_$online_output entry options (variable);
115 dcl rldr_output_$read_vtoce entry (ptr, fixed bin, ptr, fixed bin, fixed bin, fixed bin (35));
116 
117 dcl (cleanup, seg_fault_error) condition;
118 
119 dcl (addr, clock, divide, null, search, substr) builtin;
120 ^L
121 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
122 
123 
124 /* init control structure */
125     areap, rldr_datap = null ();
126                                                             /* setup cleanup handler */
127     on cleanup call rldr_finish_ (rldr_datap, areap, ignore);
128                                                             /* init local variables */
129     call get_max_pvs (rldr_data_max_pvs, code);             /* get the pvt and set up for allocation          */
130     if code ^= 0 then rldr_data_max_pvs = 100;              /* just in case                                   */
131     areap = get_system_free_area_ ();
132     allocate rldr_data_ in (Area) set (rldr_datap);
133     rldr_data_.ptrs = null ();
134     rldr_data_.bits = "0"b;
135     rldr_data_.fixed = 0;
136     rldr_data_.chars = "";
137     rldr_data_.detach = "1"b;
138     rldr_data_.first_volume = "1"b;
139     rldr_data_.sys_dir,
140          rldr_data_.default_sys_dir = ">daemon_dir_dir>volume_backup";
141     rldr_data_.io_module = "tape_mult_";
142     rldr_data_.old_256K_switch = ""b;
143 
144     do pvindex = 1 to rldr_data_max_pvs;                    /* initialize the per pv info                     */
145       rldr_data_.per_pv (pvindex) = rldr_data_nulled_pv;
146       rldr_data_.prev_wordx (pvindex) = 1;
147       rldr_data_.prev_bitx (pvindex) = 2;
148     end;
149     call hcs_$set_256K_switch ("11"b, rldr_data_.old_256K_switch, code);
150     if code ^= 0 then do;
151         call rldr_report_$error_output (rldr_datap, code, myname, "Could not enable 256KW segments.");
152         goto err;
153       end;
154     rldr_data_.data_init = "1"b;
155     code = 0;
156     query_info.version = query_info_version_5;
157     call cu_$arg_list_ptr (argp);
158     if argp = null () then do;                              /* no, no, no, we need something!                 */
159         call rldr_report_$error_output (rldr_datap, 0, myname, "This command requires arguments, please consult AM81 (MOH) for information.");
160         goto err;
161       end;
162     call rldr_arg_reader_ (rldr_datap, argp, code);
163     if code ^= 0 then goto err;
164     rldr_data_.arg_init = "1"b;
165     if rldr_data_.operator = "" | rldr_data_.npvs <= 0 then do;
166         if ((rldr_data_.operator = "") & (rldr_data_.npvs <= 0)) then
167           call rldr_report_$error_output (rldr_datap, 0, myname, "Operator name and physical volume name not specified");
168         else if (rldr_data_.operator = "") then
169           call rldr_report_$error_output (rldr_datap, 0, myname, "Operator name not specified");
170         else call rldr_report_$error_output (rldr_datap, 0, myname, "Physical volume name not specified.");
171         goto err;
172       end;
173     found_restart, volog_missing, version_1_found = "0"b;
174     do i = 1 to rldr_data_.npvs;                            /* just do this all at once                       */
175       call find_volog (i);                                  /* or else we could have many many vologs missing */
176     end;                                                    /* user would have to reinvoke reload_volume once for each*/
177     if volog_missing then do;                               /* this is set by find_volog if it can't find     */
178         call rldr_report_$online_output (rldr_datap, 0, myname, "Please start volume log recovery procedure");
179         goto finish;
180       end;
181 ^L
182 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * */
183 /*                                                                                        */
184 /* Here, if we have found any version 1 vologs, then everything MUST belong to the        */
185 /* mounted RPV, except if we are reloading an rpv. In that case, it must be the only pv   */
186 /* being reloaded. This is exactly a'la MR10.2. This support of version 1 volume logs     */
187 /* will disappear in MR12.                                                                */
188 /*                                                                                        */
189 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * */
190 
191     if version_1_found then do;
192         call mdc_$pvname_info ("rpv", rldr_data_.rpv_pvid, lvname, rldr_data_.rpv_lvid,
193              rldr_data_.rpv_disk_type, code);
194         if code ^= 0 then do;
195             call rldr_report_$error_output (rldr_datap, code, myname, "Unable to get info about rpv");
196             goto err;
197           end;
198         mounted_rpv_pvid = rldr_data_.rpv_pvid;
199         if rldr_data_.rpv then do;                          /* ok if rpv being reloaded, be sure he's alone   */
200             if rldr_data_.npvs > 1 then do;
201                 call rldr_report_$error_output (rldr_datap, 0, myname,
202                      "An implementation restriction when using version 1 volume logs.
203 This requires that the RPV be reloaded separately from other volumes.");
204                 goto err;
205               end;
206             bvlp = rldr_data_.per_pv (1).bvlp;              /* if RPV then this is his volume log             */
207             rldr_data_.rpv_pvid = backup_volume_log.info.pvid;
208             rldr_data_.rpv_lvid = backup_volume_log.info.lvid;
209             rldr_data_.disk_type (1) = rldr_data_.rpv_disk_type;
210             rldr_data_.lvname (1) = lvname;
211           end;
212         else do;                                            /* ok, not doing the RPV, all must belong to mounted RPV*/
213             do pvindex = 1 to rldr_data_.npvs;
214               pvid_missing = "0"b;                          /* check if pvname registered and get type and pvid */
215               do i = 1 to rldr_data_.npvs;                  /* do this once for the entire list               */
216                 call mdc_$pvname_info (rldr_data_.pvname (i), rldr_data_.pvid (i),
217                      rldr_data_.lvname (i), rldr_data_.lvid (i), rldr_data_.disk_type (i), code);
218                 if code ^= 0 then do;
219                     call rldr_report_$error_output (rldr_datap, code, myname, "Unable to determine pvid for ^a",
220                          rldr_data_.pvname (i));
221                     pvid_missing = "1"b;
222                   end;
223               end;
224               if pvid_missing then goto err;
225             end;
226           end;
227         rldr_data_.stranger = ^(rldr_data_.rpv_pvid = mounted_rpv_pvid);
228                                                             /* do rldr_input_ knows                           */
229       end;                                                  /* end version 1 stuff                            */
230 ^L
231 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * */
232 /*                                                                                        */
233 /* This is the section that allows for 'stranger' physical volume reloading. It is        */
234 /* executed only if all volume logs were version 2.                                       */
235 /*                                                                                        */
236 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * */
237     else do;
238         call mdc_$pvname_info ("rpv", rldr_data_.rpv_pvid, lvname, rldr_data_.rpv_lvid, rldr_data_.rpv_disk_type, code);
239         if code ^= 0 then do;
240             call rldr_report_$error_output (rldr_datap, code, myname, "Unable to get info about rpv");
241             goto err;
242           end;
243         mounted_rpv_pvid = rldr_data_.rpv_pvid;
244         rldr_data_.rpv_pvid = "0"b;
245         if rldr_data_.sys_dir ^= rldr_data_.default_sys_dir then do; /* -working_dir specified                          */
246             if rldr_data_.rpv then do;                      /* find the RPV                                   */
247                 do i = 1 to rldr_data_.npvs while (rldr_data_.per_pv (i).pvname ^= "rpv");
248                 end;
249                 bvlp = rldr_data_.per_pv (i).bvlp;          /* point to his volume log                        */
250                 rldr_data_.rpv_pvid = backup_volume_log.pvid;
251                 rldr_data_.rpv_lvid = backup_volume_log.info.lvid;
252                 goto got_rpvid;
253               end;
254             else do;                                        /* RPV not in he list, pick the first             */
255                 bvlp = rldr_data_.per_pv (1).bvlp;          /* point to the volume log                        */
256                 rldr_data_.rpv_pvid = backup_volume_log.rpv_pvid;
257               end;
258           end;                                              /* end wd mode                                    */
259         if rldr_data_.rpv_pvid = "0"b then                  /* must belong to mounted RPV                     */
260           rldr_data_.rpv_pvid = mounted_rpv_pvid;
261 got_rpvid:
262         if (validate_all_vologs ()) then ;                  /* make sure all rpv_pvid's match in the vologs   */
263         else do;                                            /* forget it...                                   */
264             call rldr_report_$error_output (rldr_datap, 0, myname, "The reload will be aborted.");
265             goto err;
266           end;
267         call fill_from_volog ();                            /* puts in the necessary per pv info              */
268         rldr_data_.stranger = ^(rldr_data_.rpv_pvid = mounted_rpv_pvid);
269                                                             /* for rldr_input_                                */
270       end;                                                  /* end the version 2 stuff                        */
271 ^L
272 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
273 /*      Back to common code...                                                                                */
274 
275     call get_temp_segments_ (myname, tp2, code);            /* create temp segs */
276     if code ^= 0 then do;
277         call rldr_report_$error_output (rldr_datap, code, myname, "Error creating temp segs ");
278         goto err;
279       end;
280     dont_query_restart = "0"b;
281     do pvindex = 1 to rldr_data_.npvs;
282       if rldr_data_.disk_model (pvindex) = "" then do;      /* if caller did not specify use registration info */
283           dev_idx = rldr_data_.disk_type (pvindex);
284           rldr_data_.usable_sectors (pvindex) = divide (sect_per_cyl (dev_idx), sect_per_rec (dev_idx), 17, 0) * sect_per_rec (dev_idx);
285           rldr_data_.unusable_sectors (pvindex) =
286                sect_per_cyl (dev_idx) - rldr_data_.usable_sectors (pvindex);
287         end;
288       rldr_data_.vtocbp (pvindex) = tp2 (1);
289       rldr_data_.labelp (pvindex) = tp2 (2);
290       cln = search (rldr_data_.pvname (pvindex), " ") - 1;  /* create control seg to allow restart */
291       if cln < 1 | cln > 24 then cln = 24;
292       control_name = substr (rldr_data_.pvname (pvindex), 1, cln) || ".control";
293 remake_control_seg:
294       call hcs_$make_seg (wdir_ (), control_name, "", 01010b, rldr_data_.controlp (pvindex), code);
295       if code ^= 0 then do;
296           if rldr_data_.common.restart & (code = error_table_$segknown | code = error_table_$namedup) then code = 0;
297           else do;
298               call command_query_$yes_no (YES, 0, myname,
299                    "A control segment was found for the specified physical volume, but -restart was not specified.
300 Do you wish a restart on the specified physical volume?",
301                    "Control segment ^a exists but -restart not specified. Do you want a restart on the physical volume? ",
302                    control_name);
303               if YES then found_restart, rldr_data_.per_pv (pvindex).restart = "1"b;
304               else do;                                      /* ok, delete the old one, and make a new one     */
305                   dont_query_restart = "1"b;
306                   call hcs_$delentry_seg (rldr_data_.controlp (pvindex), ignore);
307                   goto remake_control_seg;
308                 end;
309             end;
310         end;                                                /* end each pv                                    */
311       if ((rldr_data_.common.restart) & (^found_restart) & (^dont_query_restart)) then do;
312                                                             /* -restart specified, but didn't find a control seg.*/
313           call command_query_$yes_no (YES, 0, myname,
314                "The -restart control argument was specified, but no control segment was found.
315 A ""yes"" answer will continue with the reload, whereas a ""no"" answer will abort it. Continue the reload?",
316                "No control seg found for -restart control arg. Do you wish to continue with the reload?");
317           if YES then rldr_data_.common.restart = "0"b;     /* turn this off for rldr_input_                  */
318           else goto err;
319         end;
320     end;
321     do pvindex = 1 to rldr_data_.npvs;                      /* ok, let's go...                                */
322       controlp = rldr_data_.controlp (pvindex);
323       rldr_data_.vol_mapp (pvindex) = addr (rldr_control.vol_map);
324       rldr_data_.vtoc_headerp (pvindex) = addr (rldr_control.vtoc_header);
325       rldr_data_.labelp (pvindex) = addr (rldr_control.label);
326       call rldr_output_$init (rldr_datap, pvindex, code);   /* initialize output attachment */
327       if code ^= 0 then do;
328           call rldr_report_$error_output (rldr_datap, code, myname, "Error initializing output medium, pv ^a",
329                rldr_data_.pvname (pvindex));
330           goto err;
331         end;
332       if ^rldr_data_.per_pv.restart (pvindex) then do;      /* initialize physical volume label data base */
333           call rldr_label_$open (rldr_datap, pvindex, code);
334           if code ^= 0 then do;
335               call rldr_report_$error_output (rldr_datap, code, myname, "Label check failed for pv ^a",
336                    rldr_data_.pvname (pvindex));
337               goto err;
338             end;
339           call rldr_volume_map_$open (rldr_datap, pvindex, code); /* initialize volume map data base */
340           if code ^= 0 then do;
341               call rldr_report_$error_output (rldr_datap, code, myname, "Error opening volume map for pv ^a",
342                    rldr_data_.pvname (pvindex));
343               goto err;
344             end;
345           call rldr_vtoc_header_$open (rldr_datap, pvindex, code); /* initialize vtoc header data base */
346           if code ^= 0 then do;
347               call rldr_report_$error_output (rldr_datap, code, myname, "Unable to open vtoc header for pv ^a",
348                    rldr_data_.pvname (pvindex));
349               goto err;
350             end;
351           call rldr_check_pvol_ (rldr_datap, pvindex, code);/* cross check volume log and physical volume label */
352           if code ^= 0 then do;
353               if code > 2 then do;
354                   call rldr_report_$error_output (rldr_datap, 0, myname,
355                        "Unable to reload volume ^a. Volog and volume label have fatal mismatch",
356                        rldr_data_.pvname (pvindex));
357                   goto err;
358                 end;
359               else do;
360                   call command_query_$yes_no (YES, 0, myname, "",
361                        "Initialized physical volume ^a does not match online logical image. Do you wish to proceed",
362                        rldr_data_.pvname (pvindex));
363                   if ^YES then goto err;
364                 end;
365             end;
366           if rldr_data_.save then call update_control_seg ();
367         end;
368     end;                                                    /* <- each physical volume                        */
369     call get_temp_segments_ (myname, tp6, code);            /* a few more of these and we can start           */
370     if code ^= 0 then do;
371         call rldr_report_$error_output (rldr_datap, code, myname, "Error creating temp segs ");
372         goto err;
373       end;
374     rldr_data_.volume_record_bp = tp6 (1);
375     rldr_data_.data_object_bp = tp6 (2);
376     rldr_data_.input_vol_lstp = tp6 (3);
377     rldr_data_.infop = tp6 (4);
378     rldr_data_.skip = tp6 (5);
379     rldr_data_.input_buffer_ptr = tp6 (6);
380     rldr_data_.input_buffer_len = 0;
381     call hcs_$set_max_length_seg (rldr_data_.data_object_bp, sys_info$seg_size_256K, code);
382     if code ^= 0 then do;
383         call rldr_report_$error_output (rldr_datap, code, myname, "Could not create 256KW temporary segment.");
384         goto err;
385       end;
386 
387     call hcs_$set_max_length_seg (rldr_data_.input_buffer_ptr,
388          sys_info$seg_size_256K, code);
389     if code ^= 0 then do;
390         call rldr_report_$error_output (rldr_datap, code, myname, "Could not create 256KW temporary segment.");
391         goto err;
392       end;
393 
394     call rldr_input_$init_volume_list (rldr_datap, code);   /* generate list of dump volumes */
395     if code ^= 0 then do;
396         call rldr_report_$error_output (rldr_datap, code, myname, "Error initializing input volume list ");
397         goto err;
398       end;
399                                                             /* Inform the user */
400     call rldr_report_$online_output (rldr_datap, 0, myname, "Begin reload of volume^[s^] ^v(^a ^) at ^a",
401          (rldr_data_.npvs > 1), rldr_data_.npvs, rldr_data_.pvname (*), time_now_ ());
402                                                             /* do the actual job */
403     call reload_volume_ (rldr_datap, code);                 /* reload them all                                */
404     if code ^= 0 then                                       /* if code ^=0 then pvindex is one who failed.    */
405       call rldr_report_$error_output (rldr_datap, code, myname, "Error reloading volume ^a", rldr_data_.pvname (pvindex));
406     do pvindex = 1 to rldr_data_.npvs;                      /* Build the VTOC Map, as init_vol set it to all-free */
407       call rldr_vtoc_header_$build_vtoc_map (rldr_datap, pvindex, code);
408       if code ^= 0 then
409         call rldr_report_$error_output (rldr_datap, code, myname, "Unable to build VTOC map for pv ^a",
410              rldr_data_.pvname (pvindex));
411                                                             /* Update the vtoc header */
412       call rldr_vtoc_header_$close (rldr_datap, pvindex, code);
413       if code ^= 0 then
414         call rldr_report_$error_output (rldr_datap, code, myname, "Error closing vtoc header for pv ^a",
415              rldr_data_.pvname (pvindex));
416                                                             /* Update the volume map */
417       call rldr_volume_map_$close (rldr_datap, pvindex, code);
418       if code ^= 0 then
419         call rldr_report_$error_output (rldr_datap, code, myname, "Error closing volume map for pv ^a",
420              rldr_data_.pvname (pvindex));
421                                                             /* Update the label */
422       call rldr_label_$close (rldr_datap, pvindex, code);
423       if code ^= 0 then
424         call rldr_report_$error_output (rldr_datap, code, myname, "Error closing volume label for pv ^a",
425              rldr_data_.pvname (pvindex));
426                                                             /* Inform the user */
427       call rldr_report_$online_output (rldr_datap, 0, myname, "End reload of volume ^a at ^a",
428            rldr_data_.pvname (pvindex), time_now_ ());
429       controlp = rldr_data_.controlp (pvindex);
430       call rldr_report_$online_output (rldr_datap, 0, myname,
431            "Reloaded on volume ^a ^d records of ^d directories and  ^d records of ^d segments and ^d null vtoces",
432            rldr_data_.pvname (pvindex), rldr_control.dir_rec, rldr_control.dir_num, rldr_control.seg_rec,
433            rldr_control.seg_num, rldr_control.num_null_vtoce);
434 
435       call hcs_$delentry_seg (rldr_data_.controlp (pvindex), ignore); /* all done so delete control seg */
436       if hcs_$level_get () = 1 & get_group_id_ () = "Initializer.SysDaemon.z"
437            & rldr_data_.default_sys_dir ^= rldr_data_.sys_dir
438       then do;
439           call hcs_$delentry_seg (rldr_data_.bvlp (pvindex), ignore); /* delete temp volog */
440           rldr_data_.bvlp (pvindex) = null ();              /* and set for finish_                            */
441         end;
442     end;                                                    /* for each physical volume                       */
443 
444 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
445 
446 end_reload_volume: entry;
447 finish:
448                                                             /* clean up */
449     call rldr_finish_ (rldr_datap, areap, ignore);          /* releases temp segs and frees as required       */
450     return;
451 
452 err:
453     do pvindex = 1 to rldr_data_.npvs;
454       if rldr_data_.controlp (pvindex) ^= null then call hcs_$delentry_seg (rldr_data_.controlp (pvindex), ignore);
455     end;
456     goto finish;
457 
458 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
459 ^L
460 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
461 
462 
463 time_now_: proc returns (char (6));
464 
465 /* This proc returns a time string in a printable form */
466 
467     call date_time_ (clock (), time_string);
468     return (substr (time_string, 11, 6));
469   end time_now_;
470 
471 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
472 
473 
474 wdir_: proc returns (char (168) aligned);
475 
476 /* This proc returns the working directory */
477 
478 dcl wdir                 char (168) aligned;
479     call hcs_$fs_search_get_wdir (addr (wdir), ignore);
480     return (wdir);
481   end wdir_;
482 
483 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
484 
485 update_control_seg: proc;
486 
487 /* This proc updates the control seg look aside memory as if the data had been loaded from an input
488    volume via rldr_input_. Thus before the reload begins the control segment is up-to-date with
489    the data on the pack */
490 
491     vtocep = addr (local_vtoce);
492     labelp, old_labelp = rldr_data_.labelp (pvindex);
493     if label.volmap_version = 1 | label.volmap_version = 2
494          then time_unmounted = label.time_unmounted;
495     else time_unmounted = old_label.time_unmounted;
496     controlp = rldr_data_.controlp (pvindex);
497     vtoc_headerp = rldr_data_.vtoc_headerp (pvindex);
498     do vtocx = 0 to vtoc_header.n_vtoce - 1;
499       call rldr_output_$read_vtoce (rldr_datap, pvindex, vtocep, vtocx, 1, code);
500       if code ^= 0 then do;
501           call rldr_report_$online_output (rldr_datap, 0, code, myname, "Unable to read VTOCE ^o on pv ^a", vtocx,
502                rldr_data_.pvname (pvindex));
503           goto err;
504         end;
505       rldr_control (vtocx).uid = vtoce.uid;
506       rldr_control (vtocx).time_dumped = time_unmounted;
507     end;
508 
509   end update_control_seg;
510 
511 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
512 ^L
513 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
514 
515 
516 find_volog: proc (i);
517 
518 /* This proc attempts to locate the volog for the volume to be reloaded */
519 dcl i                    fixed bin;
520 
521 /* create volume log name */
522     call ioa_$rsnnl ("^a.^a", ename, enl, rldr_data_.pvname (i), "volog");
523     if enl > 32 then do;
524         code = error_table_$entlong;
525         goto vol_err;
526       end;
527                                                             /* get ptr to volume log */
528     call hcs_$initiate ((rldr_data_.sys_dir), ename, "", 0, 1, bvlp, code);
529     if bvlp = null then do;
530 vol_err: call rldr_report_$online_output (rldr_datap, code, myname, "Unable to locate valid volume log ^a^[>^]^a",
531              rldr_data_.sys_dir, rldr_data_.sys_dir ^= ">", ename);
532         volog_missing = "1"b;                               /* set for caller to check                        */
533         return;
534       end;
535                                                             /* check if object is a log */
536     on seg_fault_error goto vol_err;
537     if (backup_volume_log.pvname = rldr_data_.pvname (i)) & ((backup_volume_log.version = backup_volume_log_version_1)
538          | (backup_volume_log.version = backup_volume_log_version_2)
539          | (backup_volume_log.version = backup_volume_log_version_3)) then
540       if ^version_1_found then version_1_found = /* if its been set once, leave it alone            */
541              (backup_volume_log.version = backup_volume_log_version_1);
542       else do;
543           code = error_table_$improper_data_format;
544           goto vol_err;
545         end;
546     revert seg_fault_error;
547                                                             /* clear code and set ext ptr */
548     code = 0;
549     rldr_data_.bvlp (i) = bvlp;
550   end find_volog;
551 
552 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
553 
554 
555 get_max_pvs: proc (maxpvs, ec);
556 
557 dcl ec                   fixed bin (35),
558   maxpvs                 fixed bin;
559 
560     ec = -1;                                                /* just for now                                   */
561   end get_max_pvs;
562 
563 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
564 ^L
565 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
566 
567 
568 fill_from_volog:
569   proc ();
570 
571 dcl i                    fixed bin;
572 
573     do i = 1 to rldr_data_.npvs;
574       bvlp = rldr_data_.per_pv (i).bvlp;                    /* point to the volume log                        */
575       rldr_data_.per_pv (i).pvid = backup_volume_log.pvid;
576       rldr_data_.per_pv (i).disk_type = backup_volume_log.disk_type;
577       rldr_data_.per_pv (i).lvid = backup_volume_log.info.lvid;
578       rldr_data_.per_pv (i).lvname = backup_volume_log.info.lv_name;
579     end;
580 
581   end fill_from_volog;
582 
583 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
584 
585 
586 validate_all_vologs:
587   proc () returns (bit (1));
588 
589 dcl i                    fixed bin;
590 dcl mismatch             bit (1) init ("0"b);
591 
592 
593     do i = 1 to rldr_data_.npvs;
594       bvlp = rldr_data_.per_pv (i).bvlp;                    /* point at the volog                             */
595       if backup_volume_log.rpv_pvid ^= rldr_data_.rpv_pvid then do;
596           mismatch = "1"b;                                  /* flag to return                                 */
597           call rldr_report_$error_output (rldr_datap, 0, myname,
598                "The RPV pvid for physical volume ^a does not match the determined RPV pvid.",
599                rldr_data_.per_pv (i).pvname);
600         end;
601     end;
602     return (^mismatch);
603   end validate_all_vologs;
604 
605 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
606 ^L
607 %include rldr_data_;
608 ^L
609 %include backup_volume_log;
610 ^L
611 %include backup_volume_header;
612 ^L
613 %include backup_pvol_info;
614 %include rldr_control;
615 ^L
616 %include fs_dev_types;
617 ^L
618 %include fs_vol_label;
619 ^L
620 %include old_fs_vol_label;
621 ^L
622 %include vtoc_header;
623 %include vol_map;
624 ^L
625 %include vtoce;
626 ^L
627 %include query_info;
628 ^L
629 /* BEGIN MESSAGE DOCUMENTATION
630 
631 
632    Message:
633    reload_volume: Unable to locate a valid volume log for PATH: ERROR_MESS
634 
635    S:     $rld_out
636 
637    T:     $reload
638 
639    M: The volue log at PATH was not found.  This message will always cause the
640 reload to be aborted.
641 
642    A:     $tryagn
643 
644    Message:
645    reload_volume: Please start volume log recovery procedure.
646 
647    S:     $rld_out
648 
649    T:     $reload
650 
651    M: Use the recover_volume_log command to recover the specified physical
652 volumes volume log.
653 
654    A:     $tryagn
655 
656    Message:
657    reload_volume: The RPV pvid for physical volume NAME does not match the
658 determined RPV pvid.
659 
660    S:     $rld_out
661 
662    T:     $reload
663 
664    M: The backup_volume_log.rpv_pvid for NAME does not match the reloader
665 determined RPV pvid.  This could be an invalid attempt to reload a stranger
666 physical volume.
667 
668    A:     $inform
669 
670 
671    Message:
672    reload_volume: An implementation restriction when using version 1 volume logs.
673 This requires that the RPV be reloaded separately from other volumes.
674 
675    S:     $rld_out
676 
677    T:     $reload
678 
679    M:     Using version 1 volume logs, all physical volumes must belong to the mounted RPV. An exception is when reloading the RPV itself, it must be reloaded separately, then a re-boot on the new RPV will allow the other volumes to be reloaded.
680 
681    A:     $tryagn
682 
683 
684    Message:
685    reload_volume: Operator name not specified.
686 
687    S:     $rld_out
688 
689    T:     $reload
690 
691    M:     Missing input.
692 
693    A:     $tryagn
694 
695 
696    Message:
697    reload_volume: Physical volume name not specified.
698 
699    S:     $rld_out
700 
701    T:     $reload
702 
703    M:     Missing input.
704 
705    A:     $tryagn
706 
707    Message:
708    reload_volume: Could not enable 256KW segments: ERORR_MESS
709 
710    S:     $rld_out
711 
712    T:     $reload
713 
714    M:     The call to hcs_$set_256K_switch failed.
715 
716    A:     $inform
717 
718 
719    Message:
720    reload_volume: Begin reload of volume NAME at TIME
721 
722    S:     $rld_on
723 
724    T:     $reload
725 
726    M:     A volume reload is beginning.
727 
728    A:     $ignore
729 
730 
731    Message:
732    reload_volume: End reload of volume NAME at TIME
733    .br
734    reload_volume: Reloaded on volume NAME XX records of XX directories and XX records of XX segments and XX null vtoces
735 
736    S:     $rld_on
737 
738    T:     $reload
739 
740    M:     A volume reload has completed.
741    The statistics printed indicate how many records were reloaded.
742 
743    A:     $ignore
744 
745 
746    Message:
747    reload_volume: arg err: ERROR_MESS
748 
749    S:     $rld_out
750 
751    T:     $reload
752 
753    M:     Invalid input was given.
754 
755    A:     $tryagn
756 
757 
758    Message:
759    reload_volume: error closing volume label: ERROR_MESS
760 
761    S:     $rld_out
762 
763    T:     $reload
764 
765    M:     An error occurred while reloading.
766 
767    A:     $inform
768 
769 
770    Message:
771    reload_volume: error closing volume map: ERROR_MESS
772 
773    S:     $rld_out
774 
775    T:     $reload
776 
777    M:     An error occurred while reloading.
778 
779    A:     $inform
780 
781 
782    Message:
783    reload_volume: error closing vtoc header: ERROR_MESS
784 
785    S:     $rld_out
786 
787    T:     $reload
788 
789    M:     An error occurred while reloading.
790 
791    A:     $inform
792 
793 
794    Message:
795    reload_volume: error creating control seg: ERROR_MESS
796 
797    S:     $rld_out
798 
799    T:     $reload
800 
801    M:     An error occurred while reloading.
802 
803    A:     $inform
804 
805 
806    Message:
807    reload_volume: error creating temp segs: ERROR_MESS
808 
809    S:     $rld_out
810 
811    T:     $reload
812 
813    M:     An error occurred while reloading.
814 
815    A:     $inform
816 
817 
818    Message:
819    reload_volume: error initializing input volume list: ERROR_MESS
820 
821    S:     $rld_out
822 
823    T:     $reload
824 
825    M:     An error occurred while reloading.
826 
827    A:     $inform
828 
829 
830    Message:
831    reload_volume: error initializing output medium: ERROR_MESS
832 
833    S:     $rld_out
834 
835    T:     $reload
836 
837    M:     An error occurred while reloading.
838 
839    A:     $inform
840 
841 
842    Message:
843    reload_volume: error opening volume map: ERROR_MESS
844 
845    S:     $rld_out
846 
847    T:     $reload
848 
849    M:     An error occurred while reloading.
850 
851    A:     $inform
852 
853 
854    Message:
855    reload_volume: error reloading volume NAME: ERROR_MESS
856 
857    S:     $rld_out
858 
859    T:     $reload
860 
861    M:     An error occurred while reloading.
862 
863    A:     $inform
864 
865 
866    Message:
867    reload_volume: label check failed: ERROR_MESS
868 
869    S:     $rld_out
870 
871    T:     $reload
872 
873    M:     An error occurred while reloading.
874 
875    A:     $inform
876 
877 
878    Message:
879    reload_volume: Operator name and physical volume name not specified
880 
881    S:     $rld_out
882 
883    T:     $reload
884 
885    M:     Invalid input was typed.
886 
887    A:     $tryagn
888 
889 
890    Message:
891    reload_volume: unable to determine pvid for NAME: ERROR_MESS
892 
893    S:     $rld_out
894 
895    T:     $reload
896 
897    M: The volume registration information does not contain the physical volume
898 NAME.  This could be an invalid attempt to reload a stranger physical volume.
899 
900    A:     $inform
901 
902 
903    Message:
904    reload_volume: unable to get info about rpv: ERROR_MESS
905 
906    S:     $rld_out
907 
908    T:     $reload
909 
910    M:     An error occurred while reloading.
911 
912    A:     $inform
913 
914 
915    Message:
916    reload_volume: unable to open vtoc header: ERROR_MESS
917 
918    S:     $rld_out
919 
920    T:     $reload
921 
922    M:     An error occurred while reloading.
923 
924    A:     $inform
925 
926 
927    Message:
928    reload_volume: unable to build VTOC map: ERROR_MESS
929 
930    S:     $rld_out
931 
932    T:     $reload
933 
934    M:     An error occurred while reloading.
935 
936    A:     $inform
937 
938 
939    END MESSAGE DOCUMENTATION */
940 
941   end reloader;