def delete(self, file_name): ''' Delete a file from the file system and delete all its references, index blocks, and data blocks. ''' the_path = self.get_current_path() if self.search_file_in_memory(the_path + '/' + file_name) is not None: raise OSException("Error: Can't delete. The file is in memory.") (file_i, file_b) = self.search_file_name(file_name) fst_lev = file_b.get_level_one_blocks() self.get_llfm().remove_db_from_ib(self.get_llfm().get_disk_at(fst_lev)) self.get_llfm().remove_block(fst_lev) snd_i = file_b.get_level_two_blocks() if snd_i is not None: snd_b = self.get_llfm().get_disk_at(snd_i) for b in snd_b.get_blocks(): block = self.get_llfm().get_disk_at(b) self.get_llfm().remove_db_from_ib(block) self.get_llfm().remove_db_from_ib(snd_b) self.get_llfm().remove_block(snd_i) self.get_llfm().remove_block(file_i) try: self.get_level_one_current_dir()[1].remove_index(file_i) except: lt = self.get_level_two_current_dir()[1] if lt is not None: for b in lt.get_blocks(): try: self.get_llfm().get_disk_at(b).remove_index(file_i) except: continue self.get_llfm().dump_new_data() Logger.get_instance().log_del(file_name, 'file')
def start(self): '''Main method to manage CPU and I/O instructions.''' self.set_active() while self.is_active(): if self.get_current_pcb() is not None: curr_pcb = self.get_current_pcb() curr_pcb.set_state('Running') if curr_pcb.finished(): curr_pcb.set_state('Finished') self.no_current_process() ProcessKiller.get_instance().kill_pcb(curr_pcb) continue curr_inst = curr_pcb.get_next_inst() if curr_inst.is_io_inst(): self.process_io_inst(curr_inst, curr_pcb) continue else: self.process_cpu_inst(curr_inst, curr_pcb) if self.is_expropiated() or self.check_burst(curr_pcb): Logger.get_instance().log_expropiate(curr_pcb.get_pid()) self.context_switch_out(curr_pcb) self.get_process_store().put_in_ready_queue(curr_pcb) self.no_current_process() time.sleep(CPU_SLEEP_TIME) self.set_inactive()
def ren_file(self, old_name, new_name): '''Rename a file in the current directory. Fail if it's in memory.''' the_path = self.get_current_path() if self.search_file_in_memory(the_path + '/' + old_name) is not None: raise OSException("Error: Can't delete. The file is in memory.") self.rename(old_name, new_name, lambda x: x.is_file()) Logger.get_instance().log_rename(old_name, new_name, 'file')
def open(self, name, rw=True): ''' Loads a file into the memory. If it's already loaded, updates its ref_count. ''' complete_name = self.get_cwd()[0] + '/' + name if self.is_opened(complete_name): self.search_file_in_memory(complete_name).inc_ref_count() else: (file_i, file_b) = self.search_file_name(name) res = '' fst_ib = self.get_llfm().get_disk_at(file_b.get_level_one_blocks()) for index in fst_ib.get_blocks(): curr_db = self.get_llfm().get_disk_at(index) if curr_db is not None: res += curr_db.get_data() #appending each block (1st ind) snd_ib = self.get_llfm().get_disk_at(file_b.get_level_two_blocks()) if snd_ib is not None: #there are more data for ib in snd_ib.get_blocks(): iblock = self.get_llfm().get_disk_at(ib) for dbi in iblock.get_blocks(): curr_db = self.get_llfm().get_disk_at(dbi) if curr_db is not None: res += curr_db.get_data() if not self.check_available_space(): raise OSException('Error: Full memory.') else: date = file_b.get_date() size = file_b.get_size() open_file = File(complete_name, rw, date, res, file_i, size) pos = self.store_in_memory(open_file) Logger.get_instance().log_openfile(name, pos) return pos
def save(self, file_name): ''' Synchronize the contents of a file in memory and persist its data in the disk. ''' the_path = self.get_current_path() the_file = self.search_file_in_memory(the_path + '/' + file_name) if the_file is None: raise OSException("Error: File isn't in memory or doesn't exists.") data = the_file.get_data() file_inode = self.get_llfm().get_disk_at(the_file.get_disk_pos()) file_inode.set_size(the_file.get_size()) fst_ib = self.get_llfm().get_disk_at(file_inode.get_level_one_blocks()) data = self.set_data_to_blocks(fst_ib, data) if file_inode.get_level_two_blocks() is None and not data == '': ltb = self.get_llfm().create_ib_for_two_level() file_inode.set_level_two_blocks(ltb) snd_ib = self.get_llfm().get_disk_at(file_inode.get_level_two_blocks()) if not data == '': for iblock in snd_ib.get_blocks(): curr_ib = self.get_llfm().get_disk_at(iblock) data = self.set_data_to_blocks(curr_ib, data) if data == '': break self.get_llfm().dump_new_data() Logger.get_instance().log_datasaved(file_name)
def remove_directory(self, dir_name): '''Remove a directory in the current path, if exists.''' ib = self.get_level_one_current_dir()[1] f = lambda x: x.is_directory() del_ref = self.search_name_in_ib(ib, dir_name, False, f) if del_ref is None: ib = self.get_level_two_current_dir()[1] if ib is None: raise OSException("Error: Directory not found.") for b in ib.get_blocks(): ib = self.get_llfm().get_disk_at(b) del_ref = self.search_name_in_ib(ib, dir_name, True, f) if del_ref is not None: break if del_ref is None: raise OSException("Error: Directory not found.") elif self.get_llfm().check_empty_dir(del_ref): ib.remove_index(del_ref) self.get_llfm().delete_indirections(del_ref) self.get_llfm().remove_block(del_ref) self.get_llfm().dump_new_data() Logger.get_instance().log_del(dir_name, 'directory') else: raise OSException( "Error: Attempt to delete a non-empty directory.")
def shutdown(self): self.set_inactive() self.get_cpu().shutdown() self.get_lt_scheduler().set_inactive() self.get_scheduler().set_inactive() for d in self.get_io_devices(): self.get_io_devices()[d].shutdown() Memory.get_instance().clear_all() Logger.get_instance().close_log_file() self.reset()
def __init__(self, is_console): ''' Constructor of FileManager. This class can be instantiated by the operating system, or by the console. ''' if is_console: Memory() Logger() Logger.get_instance().open_log_file() self._limit_address = MAX_OPENED_FILES self._current_dir = ('/', 0) #the root directory self._low_level_fm = LowerLevelFM()
def start(self): try: Logger.get_instance().open_log_file() except IOError: print('Error in the log file. Aborting.') return self.set_active() self.start_scheduler_threads() self.start_cpu_thread() self.start_io_devices_threads() while self.is_active(): time.sleep(OS_SLEEP_TIME) self.set_inactive()
def close(self, file_name): ''' Decrement the ref_count of the file. If ref_count reaches 0, removes the file from memory. ''' complete_name = self.get_current_path() + '/' + file_name for a in range(self.get_limit_address()): the_file = Memory.get_instance().get_value_at(a) if the_file is not None and the_file.get_name() == complete_name: the_file.dec_ref_count() if the_file.get_ref_count() <= 0: Memory.get_instance().remove(a) break Logger.get_instance().log_closefile(file_name)
def process_request(self, inst, pcb): ''' Processes a request. @raise OSException: if the request is greater than the need declared. ''' try: # handling for wrong requests req_args = tuple(inst.get_args_as_int()) pid = pcb.get_pid() if not self.get_banker().request_algorithm(pid, req_args): self.context_switch_out(pcb) self.get_process_store().put_in_ready_queue(pcb) self.no_current_process() Logger.get_instance().log_request(pid, req_args, 'rejected') else: Logger.get_instance().log_request(pid, req_args, 'approved') pcb.inc_pc() except OSException: ProcessKiller.get_instance().kill_pcb(pcb) self.no_current_process()
def process_cpu_inst(self, inst, pcb): ''' Process a CPU instruction. @raise OSException: if the process make request larger than the total resources. ''' if inst.is_request(): self.process_request(inst, pcb) elif inst.is_free(): try: #handling for wrong max requests self.get_banker().do_free(pcb) pcb.inc_pc() Logger.get_instance().log_free(pcb) except OSException: ProcessKiller.get_instance().kill_pcb(pcb) self.no_current_process() else: self.get_inst_set().execute(inst, pcb) Logger.get_instance().log_execinst(pcb) pcb.set_remaining_time(pcb.get_remaining_time() - inst.get_time()) pcb.set_next_burst(pcb.get_next_burst() - inst.get_time()) pcb.inc_pc()
def __init__(self): ''' Constructor of OS.''' Memory() #create the singleton memory Logger() #initialize the logger self._parser = OSParser() self._file_manager = FileManager(False) self._proc_store = ProcessStore() self._io_devices = self.create_io_devices() banker = BankersAlgorithm(self.get_total_resources()) ProcessKiller(banker, self._proc_store) self._cpu = CPU(banker, self._io_devices, self._proc_store) self._scheduler = self.create_scheduler(self._cpu, self._proc_store) self._lt_scheduler = LTScheduler(self._proc_store) self._active = False
def ren_dir(self, old_name, new_name): '''Rename a directory in the current directory.''' self.rename(old_name, new_name, lambda x: x.is_directory()) Logger.get_instance().log_rename(old_name, new_name, 'directory')
def kill_pcb(self, pcb): '''Delete all the references and the data of the PCB given.''' self.get_banker().process_finished(pcb.get_pid()) self.get_process_store().kill_pid(pcb.get_pid()) Logger.get_instance().log_killprocess(pcb)
def create_file(self, name): '''Creates a file inside the current directory.''' self.create_generic(name, FileInode) Logger.get_instance().log_create(name, self.get_current_path(), 'file')
def store_at(self, address, value): '''Store a value given in an address given.''' self._data[address] = value Logger.get_instance().write('Memory store at #' \ + str(address) + ' the value ' + value.__repr__())
def __store(self, proc): self.get_process_store().put_in_work_queue(proc.get_pcb()) self.get_process_store().put_in_all_process(proc) Logger.get_instance().log_newprocess(proc)
def do_exit(self, arg): Logger.get_instance().close_log_file() return True
def create_directory(self, name): '''Creates a directory inside the current directory.''' self.create_generic(name, DirectoryInode) Logger.get_instance().log_create(name, self.get_current_path(), 'directory')