?? NEWTITLE := '  NOS/VE Set Management ' ??
MODULE stm$manage_io_on_vst;
?? RIGHT := 110 ??

{  PURPOSE:
{    This module manages the interfaces to device management.
{
?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc stc$current_vst_version_name
*copyc stc$maximum_vst_size
*copyc ste$error_condition_codes
*copyc dmt$active_volume_table_index
*copyc gft$system_file_identifier
*copyc ost$status
*copyc ost$user_identification
*copyc rmt$recorded_vsn
*copyc stt$set_ordinal
*copyc stt$vol_set_table
?? POP ??
*copyc dmp$attach_device_file
*copyc dmp$close_file
*copyc dmp$create_device_file
*copyc dmp$destroy_device_file
*copyc dmp$detach_device_file
*copyc dmp$get_active_vol_attributes
*copyc dmp$open_file
*copyc mmp$write_modified_pages
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal
*copyc osp$system_error
?? OLDTITLE ??
?? NEWTITLE := '[inline] STP$BUILD_VST_DF_NAME', EJECT ??

  PROCEDURE [INLINE] p$build_vst_df_name
    (    vsn: rmt$recorded_vsn;
     VAR vst_name: ost$name);

    CONST
      stc$vst_device_file_name = 'STF$VOLUME_SET_TABLE';

    vst_name := stc$vst_device_file_name;
    vst_name ((20 + 1), * ) := vsn;

  PROCEND p$build_vst_df_name;
?? OLDTITLE ??
?? NEWTITLE := '[inline] P$CLEAR_VST_BEING_MODIFIED', EJECT ??

  PROCEDURE [INLINE] p$clear_vst_being_modified
    (    p_vst: ^stt$vol_set_table;
     VAR status: ost$status);

    mmp$write_modified_pages (p_vst, stc$maximum_vst_size, osc$wait, status);
    IF status.normal THEN
      p_vst^.data_being_modified := 'FALSE';
      mmp$write_modified_pages (p_vst, stc$maximum_vst_size, osc$wait, status);
    IFEND;

  PROCEND p$clear_vst_being_modified;
?? OLDTITLE ??
?? NEWTITLE := '[inline] P$OPEN_DEVICE_FILE ', EJECT ??

  PROCEDURE [INLINE] p$open_device_file
    (    vol: rmt$recorded_vsn;
         sfid: gft$system_file_identifier;
     VAR segment_pointer: mmt$segment_pointer;
     VAR status: ost$status);

{  This interfaces to Device Management to open a device file.

    segment_pointer.kind := mmc$cell_pointer;
    dmp$open_file (sfid, 3, 3, mmc$sar_write_extend, mmc$as_random, segment_pointer, status);
    IF NOT status.normal THEN
      osp$set_status_abnormal (stc$set_management_id, ste$open_error, vol, status);
    IFEND;

  PROCEND p$open_device_file;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] stp$attach_vst', EJECT ??
*copyc sth$attach_vst

  PROCEDURE [XDCL, #GATE] stp$attach_vst
    (    vsn: rmt$recorded_vsn;
     VAR sfid: gft$system_file_identifier;
     VAR status: ost$status);

    VAR
      vst_df_name: ost$name;

    p$build_vst_df_name (vsn, vst_df_name);
    dmp$attach_device_file (vsn, vst_df_name, sfid, status);
    IF NOT status.normal THEN
      IF status.condition = dme$unknown_device_file THEN
        osp$set_status_abnormal (stc$set_management_id, ste$vol_not_in_set, vsn, status);
      ELSE
        osp$set_status_abnormal (stc$set_management_id, ste$attach_df_error, vsn, status);
      IFEND;
    IFEND;

  PROCEND stp$attach_vst;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$create_vst', EJECT ??
*copyc sth$create_vst

  PROCEDURE [XDCL, #GATE] stp$create_vst
    (    vsn: rmt$recorded_vsn;
     VAR vst_sfid: gft$system_file_identifier;
     VAR vst_segment_pointer: mmt$segment_pointer;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      p_file_attributes: ^array [1 .. * ] of dmt$new_device_file_attribute,
      p_vst: ^stt$vol_set_table,
      vst_df_name: ost$name;

    PUSH p_file_attributes: [1 .. 1];
    IF p_file_attributes = NIL THEN
      osp$set_status_abnormal (stc$set_management_id, ste$push_failed, stc$null_parameter, status);
      osp$append_status_integer (osc$status_parameter_delimiter, 1, 10, FALSE, status);
    ELSE
      p_file_attributes^ [1].keyword := dmc$file_limit;
      p_file_attributes^ [1].limit := UPPERVALUE (amt$file_limit);
      p$build_vst_df_name (vsn, vst_df_name);
      dmp$create_device_file (vst_df_name, vsn, p_file_attributes, stc$maximum_vst_size, vst_sfid, status);
    IFEND;

    IF status.normal THEN
      p$open_device_file (vsn, vst_sfid, vst_segment_pointer, status);
      IF status.normal THEN

        p_vst := vst_segment_pointer.cell_pointer;
        stp$store_vst_being_modified (p_vst, status);
        IF status.normal THEN
          p_vst^.version_name := stc$current_vst_version_name;
        IFEND;
      ELSE
        stp$destroy_vst (vsn, local_status);
      IFEND;
    IFEND;

  PROCEND stp$create_vst;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$destroy_vst', EJECT ??
*copyc sth$destroy_vst

  PROCEDURE [XDCL, #GATE] stp$destroy_vst
    (    vsn: rmt$recorded_vsn;
     VAR status: ost$status);

    VAR
      vst_df_name: ost$name;

    p$build_vst_df_name (vsn, vst_df_name);
    dmp$destroy_device_file (vsn, vst_df_name, status);

  PROCEND stp$destroy_vst;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$detach_vst', EJECT ??
*copyc sth$detach_vst

  PROCEDURE [XDCL, #GATE] stp$detach_vst
    (    sfid: gft$system_file_identifier;
     VAR status: ost$status);

    VAR
      file_modified: boolean,
      fmd_modified: boolean;

    dmp$detach_device_file (sfid, file_modified, fmd_modified, status);

  PROCEND stp$detach_vst;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$dm_check_if_files_on_vol', EJECT ??
*copyc sth$dm_check_if_files_on_vol

  PROCEDURE [XDCL, #GATE] stp$dm_check_if_files_on_vol
    (    volume: rmt$recorded_vsn;
     VAR files_on_vol: boolean);

    files_on_vol := FALSE;

  PROCEND stp$dm_check_if_files_on_vol;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$dm_mount_volume ', EJECT ??
*copyc sth$dm_mount_volume

  PROCEDURE [XDCL, #GATE] stp$dm_mount_volume
    (    volume: rmt$recorded_vsn;
     VAR status: ost$status);

    osp$set_status_abnormal (stc$set_management_id, ste$impossible_to_mount, volume, status);

  PROCEND stp$dm_mount_volume;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$open_attached_vst', EJECT ??
*copyc sth$open_attached_vst

  PROCEDURE [XDCL] stp$open_attached_vst
    (    vol: rmt$recorded_vsn;
         data_to_be_modified: boolean;
         sfid: gft$system_file_identifier;
     VAR vst_segment_pointer: mmt$segment_pointer;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      p_vst: ^stt$vol_set_table;

    p$open_device_file (vol, sfid, vst_segment_pointer, status);

    IF status.normal THEN
      p_vst := vst_segment_pointer.cell_pointer;
      IF p_vst^.data_being_modified <> 'FALSE' THEN
        stp$return_opened_vst (sfid, vst_segment_pointer, local_status);
        osp$set_status_abnormal (stc$set_management_id, ste$vol_set_table_lost_data, vol, status);
        osp$system_error (' ST - VST LOST DATA', ^status);
      ELSEIF p_vst^.version_name <> stc$current_vst_version_name THEN
        stp$return_opened_vst (sfid, vst_segment_pointer, status);
        osp$set_status_abnormal (stc$set_management_id, ste$incompatible_vst_version, vol, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, p_vst^.version_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, stc$current_vst_version_name, status);
        osp$system_error ('ST - INCOMPATIBLE VST ', ^status);
      IFEND;
    IFEND;

    IF status.normal AND data_to_be_modified THEN
      stp$store_vst_being_modified (p_vst, status);
      IF NOT status.normal THEN
        stp$return_opened_vst (sfid, vst_segment_pointer, status);
      IFEND;
    IFEND;

  PROCEND stp$open_attached_vst;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$open_vst', EJECT ??
*copyc sth$open_vst

  PROCEDURE [XDCL, #GATE] stp$open_vst
    (    vsn: rmt$recorded_vsn;
         data_to_be_modified: boolean;
     VAR sfid: gft$system_file_identifier;
     VAR vst_segment_pointer: mmt$segment_pointer;
     VAR status: ost$status);


    VAR
      local_status: ost$status;

    stp$attach_vst (vsn, sfid, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    stp$open_attached_vst (vsn, data_to_be_modified, sfid, vst_segment_pointer, status);
    IF NOT status.normal THEN
      stp$detach_vst (sfid, local_status);
    IFEND;

  PROCEND stp$open_vst;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$request_dm_volume_info', EJECT ??
*copyc sth$request_dm_volume_info

  PROCEDURE [XDCL, #GATE] stp$request_dm_volume_info
    (    volume: rmt$recorded_vsn;
     VAR internal_vsn: dmt$internal_vsn;
     VAR volume_owner: ost$user_identification;
     VAR active_volume_table_index: dmt$active_volume_table_index;
     VAR volume_found: boolean);

    VAR
      active_volume_attributes: array [1 .. 2 {3} ] of dmt$assigned_ms_vol_attribute,
      search_avt_index: dmt$active_volume_table_index;

    search_avt_index := 0;
    active_volume_attributes [1].keyword := dmc$avt_index;
    active_volume_attributes [2].keyword := dmc$ms_internal_vsn;
{   active_volume_attributes [3].keyword := dmc$ms_volume_owner;
    dmp$get_active_vol_attributes (volume, search_avt_index, active_volume_attributes, volume_found);
    IF volume_found THEN
      active_volume_table_index := active_volume_attributes [1].index;
      internal_vsn := active_volume_attributes [2].internal_vsn;
{      volume_owner := p_active_volume_attributes^ [3].volume_owner;
      volume_owner.family := '$SYSTEM';
      volume_owner.user := '$SYSTEM';
    IFEND;

  PROCEND stp$request_dm_volume_info;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$return_opened_vst', EJECT ??
*copyc sth$return_opened_vst

  PROCEDURE [XDCL, #GATE] stp$return_opened_vst
    (    sfid: gft$system_file_identifier;
     VAR vst_segment_pointer: mmt$segment_pointer;
     VAR status: ost$status);

    VAR
      p_vst: ^stt$vol_set_table;

    p_vst := vst_segment_pointer.cell_pointer;
    IF p_vst^.data_being_modified = 'TRUE ' THEN
      p$clear_vst_being_modified (p_vst, status);
    IFEND;

    IF status.normal THEN
      dmp$close_file (p_vst, status);
      IF status.normal THEN
        stp$detach_vst (sfid, status);
      IFEND;
    IFEND;

  PROCEND stp$return_opened_vst;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$store_vst_being_modified', EJECT ??
*copyc sth$store_vst_being_modified

  PROCEDURE [XDCL, #GATE] stp$store_vst_being_modified
    (    p_vst: ^stt$vol_set_table;
     VAR status: ost$status);

    p_vst^.data_being_modified := 'TRUE ';
    mmp$write_modified_pages (p_vst, stc$maximum_vst_size, osc$wait, status);

  PROCEND stp$store_vst_being_modified;
?? OLDTITLE ??
MODEND stm$manage_io_on_vst;
