def open(self, path, flags): full_path = self._full_path(path) realpath = self.getrealpath(full_path) main_logger.info(" open "+ realpath) #update read count if not FileMeta.path_to_uuid_map[realpath]: file_id = self.db_conn.getFileId(realpath) FileMeta.path_to_uuid_map[realpath] = file_id else: file_id = FileMeta.path_to_uuid_map[realpath] if file_id: #Aquire lock so that policy thread wont interfere. Unlock in release method lock = FileMeta.lock_map[file_id] else: file_id = str(uuid.uuid1()) FileMeta.path_to_uuid_map[realpath] = file_id lock = FileMeta.lock_map[file_id] lock.acquire() FileMeta.access_count_map[FileMeta.path_to_uuid_map[realpath]] += 1 return os.open(full_path, flags)
def create(self, path, mode, fi=None): full_path = self._full_path(path) file_id = str(uuid.uuid1()) # fh = os.open("./st1/yahoo.txt", os.O_WRONLY | os.O_CREAT, mode) #os.close(fh) #Aquire lock so that policy thread wont interfere. Unlock in release method lock = FileMeta.lock_map[file_id] lock.acquire() actual_path = os.path.abspath(FileMeta.disk_to_path_map[FileMeta.DEFAULT_DISK]) actual_path += path main_logger.info("Actually writing to = "+ actual_path) main_logger.info("create(): "+ full_path) #Prepare query last_update_time = last_move_time = create_time = str(time.time()) access_count = write_count = "1" volume_info = FileMeta.DEFAULT_DISK file_tag = "tada!" query = "insert into file_meta values( \'" + file_id+"\', \'" \ + actual_path +"\', \'0\', \'" + create_time+ "\', \'" + last_update_time+"\', \'" + last_move_time\ +"\', \'" + str(access_count)+"\', \'" + str(write_count)+"\', \'" + volume_info+"\', \'" + file_tag+"\');" self.db_conn.insert(query) main_logger.info("DB update finished.") #Add path and uuid to dictionary FileMeta.path_to_uuid_map[actual_path] = file_id main_logger.info("update usage count...") FileMeta.access_count_map[file_id] += 1 FileMeta.write_count_map[file_id] += 1 os.symlink(actual_path, self._full_path(path)) return os.open(actual_path, os.O_WRONLY | os.O_CREAT, mode)
def getattr(self, path, fh=None): full_path = self.getrealpath(self._full_path(path)) main_logger.info("getattr "+ path + self._full_path(path)+ full_path) st = os.lstat(full_path) return dict((key, getattr(st, key)) for key in ('st_atime', 'st_ctime', 'st_gid', 'st_mode', 'st_mtime', 'st_nlink', 'st_size', 'st_uid'))
def chown(self, path, uid, gid): main_logger.info("chown") full_path = self.getrealpath(self._full_path(path)) os.chown(self._full_path(path), uid, gid) return os.chown(full_path, uid, gid)
def chmod(self, path, mode): main_logger.info("chmod") full_path = self.getrealpath(self._full_path(path)) os.chmod(self._full_path(path), mode) return os.chmod(full_path, mode)
def access(self, path, mode): full_path = self._full_path(path) main_logger.info("access") if not os.access(full_path, mode): raise FuseOSError(errno.EACCES)
def fsync(self, path, fdatasync, fh): main_logger.info(" fsync "+ path) return self.flush(path, fh)
def flush(self, path, fh): main_logger.info(" flush "+ self.getrealpath(self._full_path(path))) return os.fsync(fh)
def mkdir(self, path, mode): main_logger.info("mkdir") return os.mkdir(self.getrealpath(self._full_path(path)), mode)
def read(self, path, length, offset, fh): realpath = self.getrealpath(self._full_path(path)) main_logger.info(" read "+ realpath) os.lseek(fh, offset, os.SEEK_SET) return os.read(fh, length)
def utimens(self, path, times=None): main_logger.info(" utimes") return os.utime(self.getrealpath(self._full_path(path)), times)
def link(self, target, name): main_logger.info(" link") return os.link(self._full_path(target), self._full_path(name))
def symlink(self, target, name): target = self.getrealpath(self._full_path(target)) main_logger.info(" symlink"+ target+ self._full_path(name)) return os.symlink(target, self._full_path(name))
def mknod(self, path, mode, dev): main_logger.info("mknode") return os.mknod(self.getrealpath(self._full_path(path)), mode, dev)
def truncate(self, path, length, fh=None): realpath = self.getrealpath(self._full_path(path)) main_logger.info(" truncate "+ realpath) with open(realpath, 'r+') as f: f.truncate(length)
def rmdir(self, path): main_logger.info("rmdir") full_path = self.getrealpath(self._full_path(path)) return os.rmdir(full_path)
def relocateFile(disk_id, src_path, dst_path, metric): if src_path == dst_path: main_logger.error( "src_path = dst_path! Crazy. FIXME. Denying request.") return None main_logger.info("Trying to move " + src_path + " to " + dst_path + "...") if not os.path.exists(src_path): main_logger.info("Removing stale DB entry.") DBUtil().removeStaleEntry(src_path) return None # 1. check if dst has enough space available = DiskUtil.get_available_space(disk_id) if available <= os.path.getsize(src_path): main_logger.info("Available:" + str(available) + "File size:" + str(os.path.getsize(src_path))) # not enough space! Free diff+1024 (just a number) status = TravelAgent.cleanupDisk( disk_id, os.path.getsize(src_path) - available + 1024, metric) if status is None: return None else: main_logger.info("We are good! Available:" + str(available) + "File size:" + str(os.path.getsize(src_path))) #Get the file id and take lock file_id = FileMeta.path_to_uuid_map[src_path] if not file_id: file_id = DBUtil().getFileId(src_path) FileMeta.path_to_uuid_map[src_path] = file_id if file_id: #Aquire lock so that policy thread wont interfere. Unlock in release method lock = FileMeta.lock_map[file_id] else: file_id = str(uuid.uuid1()) FileMeta.path_to_uuid_map[src_path] = file_id lock = FileMeta.lock_map[file_id] lock.acquire() # 3. move file try: shutil.move(src_path, dst_path) except IOError: main_logger.info("Something went wrong. Retrying...") TravelAgent.relocateFile(disk_id, src_path, dst_path, metric) #But we need to update the path to id map FileMeta.path_to_uuid_map.pop(src_path, None) DBUtil().updateFilePath(file_id, dst_path) FileMeta.path_to_uuid_map[dst_path] = file_id # Remove the symlink #get the symlink first symlinkname = src_path.replace( FileMeta.disk_to_path_map[DiskUtil.getDiskId(src_path)], FileMeta.USER_DIRECTORY) os.unlink(symlinkname) os.symlink(dst_path, symlinkname) #Release lock lock.release() main_logger.info("Move " + src_path + " to " + dst_path + " successful!") return 0