//////////////////////////////////////////////////////////////////////////// ////////////////////// COMMON METHODS /////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /// <summary> /// Attach new address space. Return 0 - successful; -1 - error /// </summary> /// <param name="_path"></param> /// <param name="_cat_file"></param> /// <param name="idx"></param> /// <returns></returns> internal string Attach(VSCatalogDescriptor desc, VSVirtualMemoryManager vmm, VSTransaction ta, bool imo) { DESCRIPTOR = desc; vm = vmm; vs_imo = imo; // Check if restore is not completed long l = vm.ReadLong(DEFS.SYSTEM_STATUS_ADDRESS); if (l != 0) { return(VSException.GetMessage(DEFS.E0009_RESTORE_NOT_COMPLETED_CODE) + " Space: " + Name); } // Build index list index_list = new List <VSIndex>(); index_list_full = new List <VSIndex>(); long addr = GetRootAddress(DEFS.POOL_INDEX); // Get 1st ADSC addredd while (addr > 0) { VSIndex xd = new VSIndex(this, addr); index_list_full.Add(xd); if (xd.Name.IndexOf(DEFS.INDEX_CROSS_REFERENCES) < 0) { index_list.Add(xd); } addr = xd.NEXT; } // Set ref indexes for (int i = 0; i < index_list.Count; i++) { set_ref_index(index_list[i]); } return(""); }
/// <summary> /// Open new address space: _path - root folder path; _cat_file - catalog file name; idx - index in the catalog. Return: space id or -1(if error) /// </summary> /// <param name="_path"></param> /// <param name="_cat_file"></param> /// <param name="idx"></param> /// <returns></returns> public string Open(VSCatalogDescriptor desc, VSTransaction ta) { this.DESCRIPTOR = desc; this.page_size = DESCRIPTOR.PageSize; this.imo = DESCRIPTOR.IMO; e_key = VSLib.ConvertStringToByte(DEFS.ENCRYPT_SPACE); e_buf = new byte[page_size]; _ta = ta; ////////////////////////////////////////////// ///////////// Initiate partitions //////////// ////////////////////////////////////////////// this.pd = new partition_descriptor[DESCRIPTOR.Partitions]; //Check if all partitions exists if (imo) { pd[0].start_page = 0; //Start Page pd[0].end_page = DESCRIPTOR.space_size_pg - 1; //End Page } else { for (int i = 0; i < DESCRIPTOR.Partitions; i++) { short j = (short)(i + 1); pd[i].file_name = DESCRIPTOR.Path + "\\" + DEFS.SPACE_FILE_NAME(DESCRIPTOR.Name, i); if (!System.IO.File.Exists(pd[i].file_name)) { return("Error: space file is not found - " + pd[i].file_name); } //FileStream f = null; //f = File.Open(pd[i].file_name, FileMode.Open, FileAccess.ReadWrite, FileShare.None); pd[i].fs = new VSIO(pd[i].file_name, VSIO.FILE_MODE_OPEN, DEFS.ENCRYPT_SPACE); pd[i].fs.SetEncryption(false); pd[i].start_page = (i == 0) ? 0 : pd[i - 1].end_page + 1; //Start Page pd[i].end_page = pd[i].start_page + ((pd[i].fs.GetLength()) / page_size) - 1; //End Page } } ////////////////////////////////////////////// ///////////// Initiate cache ///////////////// ////////////////////////////////////////////// // Create segment table segment_table = new page_segment_descriptor[DEFS.PAGE_SEGMENTS_NUMBER]; // Create page table for 1st segment segment_table[0] = new page_segment_descriptor(); segment_table[0].start_page = 0; segment_table[0].end_page = DESCRIPTOR.space_size_pg - 1; // Set initial number of segments used segments_used = 1; // Calculate cache size in pages if (imo) { cache_size_pages = DESCRIPTOR.space_size_pg; cache_size_bytes = DESCRIPTOR.SpaceSize; } else { string confs = VSLib.VSGetKey(DEFS.VM_CACHE_SIZE_KEY); if (confs == "") { confs = DEFS.VM_CACHE_SIZE_DEFAULT; VSLib.VSSetKey(DEFS.VM_CACHE_SIZE_KEY, confs); } int csize = VSLib.ConvertStringToInt(confs); cache_size_bytes = ((csize < 2) ? 2 : csize) * 1048576; if (cache_size_bytes < (page_size * 10)) { cache_size_bytes = page_size * 10; } cache_size_pages = (cache_size_bytes / page_size) + 1; } // Initialize cache segment_table[0].cache = new page_buffer[cache_size_pages]; for (int i = 0; i < cache_size_pages; i++) { segment_table[0].cache[i].buf = new byte[page_size]; segment_table[0].cache[i].tbuf = null; segment_table[0].cache[i].last_access = 0; segment_table[0].cache[i].access_count = 0; if (imo) { segment_table[0].cache[i].page_no = i; // Page no = Buf no segment_table[0].cache[i].prev = -1; segment_table[0].cache[i].next = -1; } else { segment_table[0].cache[i].page_no = -1; segment_table[0].cache[i].prev = i - 1; segment_table[0].cache[i].next = ((i + 1) == cache_size_pages) ? -1 : i + 1; } } // Initialize queues (not IMO) if (!imo) { q_read = new int[3]; q_read[number] = 0; q_read[first] = -1; q_read[last] = -1; q_write = new int[3]; q_write[number] = 0; q_write[first] = -1; q_write[last] = -1; q_free = new int[3]; q_free[number] = (int)cache_size_pages; q_free[first] = 0; q_free[last] = (int)cache_size_pages - 1; } ////////////////////////////////////////////// ///////////// Initiate page table //////////// ////////////////////////////////////////////// segment_table[0].page_table = new page_descriptor[DESCRIPTOR.space_size_pg]; for (int i = 0; i < segment_table[0].page_table.Length; i++) { if (imo) { segment_table[0].page_table[i].page_state = DEFS.PAGE_READ; segment_table[0].page_table[i].page_lock = DEFS.PAGE_LOCKED; segment_table[0].page_table[i].bufno = i; // For IMO bufno = page table element } else { segment_table[0].page_table[i].page_state = DEFS.PAGE_FREE; segment_table[0].page_table[i].page_lock = DEFS.PAGE_UNLOCKED; segment_table[0].page_table[i].bufno = -1; } } // Set state 'Opened' this.state = DEFS.SPACE_OPENED; // For IMO: write owner 'undefined'; otherwise: load and lock page 0. if (imo) { this.Write(DEFS.SYSTEM_OWNER_ADDRESS, DEFS.SYSTEM_OWNER_UNDEFINED.PadRight((int)DEFS.SYSTEM_OWNER_LENGTH)); } else { fetch(0, 0, 0, DEFS.PAGE_READ); this.lock_page(0); // lock 1st page } return(""); }
/// <summary> /// Open storage (all address spaces) /// </summary> /// <returns></returns> public void Open(string path = "", string encrypt = "") { if (state == DEFS.STATE_OPENED) { return; } string p = (root_path == DEFS.PATH_UNDEFINED) ? path : root_path; root_path = p.Trim(); this.Set(p); // Space list sl = new List <VSpace>(); // VMs list vl = new List <VSVirtualMemoryManager>(); // Check if app directory exists. Create if missing if (!Directory.Exists(DEFS.APP_ROOT_DATA)) { Directory.CreateDirectory(DEFS.APP_ROOT_DATA); } // Check if keys directory exists. Create if missing if (!Directory.Exists(DEFS.KEY_DIRECTORY)) { Directory.CreateDirectory(DEFS.KEY_DIRECTORY); } /////////////////////////////////////////////////////// TA = new VSTransaction(TransactionFileName); if (!this.Lock()) { throw new VSException(DEFS.E0001_UNABLE_TO_LOCK_CODE); } // Attach spaces for (int i = 0; i < CATALOG.Count; i++) { VSpace sp = new VSpace(); VSVirtualMemoryManager vm = new VSVirtualMemoryManager(); string err = vm.Open(CATALOG[i], TA); if (err == "") { err = sp.Attach(CATALOG[i], vm, TA, IMO); } if (err != "") { this.Release(); throw new VSException(DEFS.E0017_ATTACH_SPACE_ERROR_CODE, "- " + err); } else { vl.Add(vm); sl.Add(sp); } } // Add index spaces references for (int i = 0; i < sl.Count; i++) { if (CATALOG[i].IndexSpace != "") { for (int j = 0; j < sl.Count; j++) { if (sl[j].Name == CATALOG[i].IndexSpace) { sl[i].IndexSpace = sl[j]; break; } } } } // Presistent only - check if rollback required if (!IMO) { if (TA.Pending) { RollBackChanges(); } } //Process new FSAT creation and new allocation descriptors, Initialize KEyManager for (int i = 0; i < sl.Count; i++) { sl[i].VerifySpaceChanges(); } this.Commit(); state = DEFS.STATE_OPENED; if (encrypt.Trim() != "") { this.encrypt = (encrypt.ToUpper().Substring(0, 1) == DEFS.CT_ENCRYPTED); } return; }