/** * \brief Find a random file matching a pattern name. * \param name The pattern of the file to find. * \param m The maximum number of files to find. * \return True if we found a file; false otherwise. */ bool bf::path_configuration::find_random_file_name_on_disk ( std::string& name, std::size_t m, const std::string& w ) const { workspaces_const_iterator it_map; workspace::path_list_const_iterator it; std::list<std::string> candidates; bool result(false); it_map = m_workspaces.find( w ); if ( it_map != m_workspaces.end() ) for ( it = it_map->second.data_begin(); (it != it_map->second.data_end()) && (candidates.size() < m); ++it ) { const boost::filesystem::path dirpath( *it ); if ( boost::filesystem::exists( dirpath ) ) if ( boost::filesystem::is_directory( dirpath ) ) // plus 1 for the trailing slash of the root directory find_all_files_in_dir (*it, name, it->length() + 1, m, candidates); } if ( !candidates.empty() ) { const std::size_t i ( (double)candidates.size() * rand() / (RAND_MAX+1.0) ); it = candidates.begin(); std::advance(it, i); std::string pattern(name); name = *it; result = true; // put the result at the beginning of the cache m_cached_random_file.push_front ( random_file_result(pattern, m, candidates) ); if ( m_cached_random_file.size() > m_max_cached_files ) m_cached_random_file.pop_back(); } return result; } // path_configuration::find_random_file_name_on_disk()
void VMType::createInitialFileList() { MyString intermediate_files; StringList intermediate_file_list(NULL, ","); MyString input_files; StringList input_file_list(NULL, ","); m_initial_working_files.clearAll(); m_transfer_intermediate_files.clearAll(); m_transfer_input_files.clearAll(); // Create m_initial_working_files find_all_files_in_dir(m_workingpath.Value(), m_initial_working_files, true); // Read Intermediate files from Job classAd m_classAd.LookupString( ATTR_TRANSFER_INTERMEDIATE_FILES, intermediate_files); if( intermediate_files.IsEmpty() == false ) { intermediate_file_list.initializeFromString(intermediate_files.Value()); } // Read Input files from Job classAd m_classAd.LookupString( ATTR_TRANSFER_INPUT_FILES, input_files); if( input_files.IsEmpty() == false ) { input_file_list.initializeFromString(input_files.Value()); } // Create m_transfer_intermediate_files and m_transfer_input_files with fullpath. const char *tmp_file = NULL; m_initial_working_files.rewind(); while( (tmp_file = m_initial_working_files.next()) != NULL ) { // Create m_transfer_intermediate_files if( filelist_contains_file(tmp_file, &intermediate_file_list, true) ) { m_transfer_intermediate_files.append(tmp_file); } // Create m_transfer_input_files if( filelist_contains_file(tmp_file, &input_file_list, true) ) { m_transfer_input_files.append(tmp_file); } } }
void VMType::deleteNonTransferredFiles() { // Rebuild m_initial_working_files m_initial_working_files.clearAll(); // Find all files in working directory find_all_files_in_dir(m_workingpath.Value(), m_initial_working_files, true); const char *tmp_file = NULL; m_initial_working_files.rewind(); while( (tmp_file = m_initial_working_files.next()) != NULL ) { if( m_transfer_input_files.contains(tmp_file) == false ) { // This file was created after starting a job IGNORE_RETURN unlink(tmp_file); m_initial_working_files.deleteCurrent(); } } m_transfer_intermediate_files.clearAll(); }
void VirshType::updateLocalWriteDiskTimestamp(time_t timestamp) { char *tmp_file = NULL; StringList working_files; struct utimbuf timewrap; find_all_files_in_dir(m_workingpath.Value(), working_files, true); working_files.rewind(); while( (tmp_file = working_files.next()) != NULL ) { // In Virsh, disk file is generally used via loopback-mounted // file. However, mtime of those files is not updated // even after modification. // So we manually update mtimes of writable disk files. if( writableXenDisk(tmp_file) ) { timewrap.actime = timestamp; timewrap.modtime = timestamp; utime(tmp_file, &timewrap); } } }
/** * \brief Find all files matching a given pattern. * \param dirname The name of the directory to explore. * \param pattern The pattern of the name of the files to find. * \param offset The length of the path to the root directory. * \param m The maximum number of files to find. * \param result (out) The paths of the files. * * \sa glob_match */ void bf::path_configuration::find_all_files_in_dir ( const std::string& dirname, const std::string& pattern, std::size_t offset, std::size_t m, std::list<std::string>& result ) const { const boost::filesystem::path path( dirname ); CLAW_PRECOND( boost::filesystem::is_directory(path) ); boost::filesystem::directory_iterator it(path); const boost::filesystem::directory_iterator eit; for ( ; (it!=eit) && (result.size() < m); ++it ) { const std::string entry_path( it->path().string() ); if ( boost::filesystem::is_directory(*it) ) { if ( glob_potential_match(pattern, entry_path, offset) ) find_all_files_in_dir(entry_path, pattern, offset, m, result); } else if ( glob_match(pattern, entry_path, offset) ) result.push_back( entry_path ); } } // path_configuration::find_all_files_in_dir()
bool VirshType::parseXenDiskParam(const char *format) { if( !format || (format[0] == '\0') ) { return false; } vmprintf(D_FULLDEBUG, "format = %s\n", format); StringList working_files; find_all_files_in_dir(m_workingpath.Value(), working_files, true); StringList disk_files(format, ","); if( disk_files.isEmpty() ) { return false; } disk_files.rewind(); const char *one_disk = NULL; while( (one_disk = disk_files.next() ) != NULL ) { // found a disk file StringList single_disk_file(one_disk, ":"); int iNumParams = single_disk_file.number(); if( iNumParams < 3 || iNumParams > 4 ) { return false; } single_disk_file.rewind(); // name of a disk file MyString dfile = single_disk_file.next(); if( dfile.IsEmpty() ) { return false; } dfile.trim(); const char* tmp_base_name = condor_basename(dfile.Value()); if( !tmp_base_name ) { return false; } // Every disk file for Virsh must have full path name MyString disk_file; if( filelist_contains_file(dfile.Value(), &working_files, true) ) { // file is transferred disk_file = m_workingpath; disk_file += DIR_DELIM_CHAR; disk_file += tmp_base_name; m_has_transferred_disk_file = true; }else { // file is not transferred. if( fullpath(dfile.Value()) == false) { vmprintf(D_ALWAYS, "File(%s) for xen disk " "should have full path name\n", dfile.Value()); return false; } disk_file = dfile; } // device name MyString disk_device = single_disk_file.next(); disk_device.trim(); disk_device.lower_case(); // disk permission MyString disk_perm = single_disk_file.next(); disk_perm.trim(); if( !strcasecmp(disk_perm.Value(), "w") || !strcasecmp(disk_perm.Value(), "rw")) { // check if this disk file is writable if( check_vm_write_access_file(disk_file.Value(), false) == false ) { vmprintf(D_ALWAYS, "xen disk image file('%s') cannot be modified\n", disk_file.Value()); return false; } }else { // check if this disk file is readable if( check_vm_read_access_file(disk_file.Value(), false) == false ) { vmprintf(D_ALWAYS, "xen disk image file('%s') cannot be read\n", disk_file.Value()); return false; } } XenDisk *newdisk = new XenDisk; ASSERT(newdisk); newdisk->filename = disk_file; newdisk->device = disk_device; newdisk->permission = disk_perm; // only when a format is specified do we check if (iNumParams == 4 ) { newdisk->format = single_disk_file.next(); newdisk->format.trim(); newdisk->format.lower_case(); } m_disk_list.Append(newdisk); } if( m_disk_list.Number() == 0 ) { vmprintf(D_ALWAYS, "No valid Virsh disk\n"); return false; } return true; }