diff --git a/include/GParted_Core.h b/include/GParted_Core.h index 0b5f8fb7..e1656d82 100644 --- a/include/GParted_Core.h +++ b/include/GParted_Core.h @@ -65,7 +65,6 @@ private: void read_mountpoints_from_file_swaps( const Glib::ustring & filename, std::map< Glib::ustring, std::vector > & map ) ; - std::vector get_alternate_paths( const Glib::ustring & path ) ; Glib::ustring get_partition_path( PedPartition * lp_partition ) ; void set_device_partitions( Device & device ) ; GParted::FILESYSTEM get_filesystem() ; @@ -202,8 +201,6 @@ private: std::map< Glib::ustring, std::vector > mount_info ; std::map< Glib::ustring, std::vector > fstab_info ; - std::map< Glib::ustring, Glib::ustring > alternate_paths ; - std::map< Glib::ustring, Glib::ustring >::iterator iter ; std::map< Glib::ustring, std::vector >::iterator iter_mp ; PedDevice *lp_device ; diff --git a/include/Makefile.am b/include/Makefile.am index 26bd12fb..030e59f9 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -30,6 +30,7 @@ EXTRA_DIST = \ OperationResizeMove.h \ OperationLabelPartition.h \ Partition.h \ + Proc_Partitions_Info.h \ SWRaid.h \ TreeView_Detail.h \ Utils.h \ diff --git a/include/Proc_Partitions_Info.h b/include/Proc_Partitions_Info.h new file mode 100644 index 00000000..1f0c86a7 --- /dev/null +++ b/include/Proc_Partitions_Info.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2010 Curtis Gedak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + + +/* Proc_Partitions_Info + * + * A persistent cache of information from the file /proc/partitions + * that helps to minimize the number of required disk reads. + */ + +#ifndef PROC_PARTITONS_INFO_H_ +#define PROC_PARTITONS_INFO_H_ + +#include "../include/Utils.h" + +namespace GParted +{ + +class Proc_Partitions_Info +{ +public: + Proc_Partitions_Info() ; + Proc_Partitions_Info( bool do_refresh ) ; + ~Proc_Partitions_Info() ; + std::vector get_alternate_paths( const Glib::ustring & path ) ; +private: + void load_proc_partitions_info_cache() ; + static bool proc_partitions_info_cache_initialized ; + static std::map< Glib::ustring, Glib::ustring > alternate_paths_cache ; +}; + +}//GParted + +#endif /*PROC_PARTITONS_INFO_H_*/ diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc index a94b672b..f142cac5 100644 --- a/src/GParted_Core.cc +++ b/src/GParted_Core.cc @@ -27,6 +27,7 @@ #include "../include/OperationFormat.h" #include "../include/OperationResizeMove.h" #include "../include/OperationLabelPartition.h" +#include "../include/Proc_Partitions_Info.h" #include "../include/btrfs.h" #include "../include/ext2.h" @@ -156,6 +157,7 @@ void GParted_Core::set_devices( std::vector & devices ) { devices .clear() ; Device temp_device ; + Proc_Partitions_Info pp_info( true ) ; //Refresh cache of proc partition information FS_Info fs_info( true ) ; //Refresh cache of file system information DMRaid dmraid( true ) ; //Refresh cache of dmraid device information SWRaid swraid( true ) ; //Refresh cache of swraid device information @@ -297,7 +299,7 @@ void GParted_Core::set_devices( std::vector & devices ) //device info.. temp_device .add_path( device_paths[ t ] ) ; - temp_device .add_paths( get_alternate_paths( temp_device .get_path() ) ) ; + temp_device .add_paths( pp_info .get_alternate_paths( temp_device .get_path() ) ) ; temp_device .model = lp_device ->model ; temp_device .length = lp_device ->length ; @@ -363,7 +365,6 @@ void GParted_Core::set_devices( std::vector & devices ) //clear leftover information... //NOTE that we cannot clear mountinfo since it might be needed in get_all_mountpoints() set_thread_status_message("") ; - alternate_paths .clear() ; fstab_info .clear() ; } @@ -743,7 +744,6 @@ Glib::ustring GParted_Core::get_libparted_version() void GParted_Core::init_maps() { - alternate_paths .clear() ; mount_info .clear() ; fstab_info .clear() ; @@ -761,34 +761,6 @@ void GParted_Core::init_maps() std::unique( iter_mp ->second .begin(), iter_mp ->second .end() ), iter_mp ->second .end() ) ; } - - //initialize alternate_paths... - std::string line ; - std::ifstream proc_partitions( "/proc/partitions" ) ; - if ( proc_partitions ) - { - char c_str[4096+1] ; - - while ( getline( proc_partitions, line ) ) - if ( sscanf( line .c_str(), "%*d %*d %*d %4096s", c_str ) == 1 ) - { - line = "/dev/" ; - line += c_str ; - - //FIXME: it seems realpath is very unsafe to use (manpage)... - if ( file_test( line, Glib::FILE_TEST_EXISTS ) && - realpath( line .c_str(), c_str ) && - line != c_str ) - { - //because we can make no assumption about which path libparted will detect - //we add all combinations. - alternate_paths[ c_str ] = line ; - alternate_paths[ line ] = c_str ; - } - } - - proc_partitions .close() ; - } } void GParted_Core::read_mountpoints_from_file( @@ -850,17 +822,6 @@ void GParted_Core::read_mountpoints_from_file_swaps( } } -std::vector GParted_Core::get_alternate_paths( const Glib::ustring & path ) -{ - std::vector paths ; - - iter = alternate_paths .find( path ) ; - if ( iter != alternate_paths .end() ) - paths .push_back( iter ->second ) ; - - return paths ; -} - Glib::ustring GParted_Core::get_partition_path( PedPartition * lp_partition ) { DMRaid dmraid; //Use cache of dmraid device information @@ -888,6 +849,7 @@ Glib::ustring GParted_Core::get_partition_path( PedPartition * lp_partition ) void GParted_Core::set_device_partitions( Device & device ) { int EXT_INDEX = -1 ; + Proc_Partitions_Info pp_info ; //Use cache of proc partitions information FS_Info fs_info ; //Use cache of file system information DMRaid dmraid ; //Use cache of dmraid device information @@ -936,7 +898,7 @@ void GParted_Core::set_device_partitions( Device & device ) lp_partition ->type, partition_is_busy ) ; - partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ; + partition_temp .add_paths( pp_info .get_alternate_paths( partition_temp .get_path() ) ) ; set_flags( partition_temp ) ; if ( partition_temp .busy && partition_temp .partition_number > device .highest_busy ) @@ -976,7 +938,7 @@ void GParted_Core::set_device_partitions( Device & device ) false, partition_is_busy ) ; - partition_temp .add_paths( get_alternate_paths( partition_temp .get_path() ) ) ; + partition_temp .add_paths( pp_info .get_alternate_paths( partition_temp .get_path() ) ) ; set_flags( partition_temp ) ; EXT_INDEX = device .partitions .size() ; diff --git a/src/Makefile.am b/src/Makefile.am index b42000a5..c76ec37f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,6 +39,7 @@ gpartedbin_SOURCES = \ OperationResizeMove.cc \ OperationLabelPartition.cc \ Partition.cc \ + Proc_Partitions_Info.cc \ SWRaid.cc \ TreeView_Detail.cc \ Utils.cc \ diff --git a/src/Proc_Partitions_Info.cc b/src/Proc_Partitions_Info.cc new file mode 100644 index 00000000..0595c01b --- /dev/null +++ b/src/Proc_Partitions_Info.cc @@ -0,0 +1,104 @@ +/* Copyright (C) 2010 Curtis Gedak + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "../include/Proc_Partitions_Info.h" + +#include + +namespace GParted +{ + +//Initialize static data elements +bool Proc_Partitions_Info::proc_partitions_info_cache_initialized = false ; +std::map< Glib::ustring, Glib::ustring > Proc_Partitions_Info::alternate_paths_cache ; + +Proc_Partitions_Info::Proc_Partitions_Info() +{ + //Ensure that cache has been loaded at least once + if ( ! proc_partitions_info_cache_initialized ) + { + proc_partitions_info_cache_initialized = true ; + load_proc_partitions_info_cache() ; + } +} + +Proc_Partitions_Info::Proc_Partitions_Info( bool do_refresh ) +{ + //Ensure that cache has been loaded at least once + if ( ! proc_partitions_info_cache_initialized ) + { + proc_partitions_info_cache_initialized = true ; + if ( do_refresh == false ) + load_proc_partitions_info_cache() ; + } + + if ( do_refresh ) + load_proc_partitions_info_cache() ; +} + +Proc_Partitions_Info::~Proc_Partitions_Info() +{ +} + +std::vector Proc_Partitions_Info::get_alternate_paths( const Glib::ustring & path ) +{ + std::vector paths ; + std::map< Glib::ustring, Glib::ustring >::iterator iter ; + + iter = alternate_paths_cache .find( path ) ; + if ( iter != alternate_paths_cache .end() ) + paths .push_back( iter ->second ) ; + + return paths ; +} + +//Private Methods +void Proc_Partitions_Info::load_proc_partitions_info_cache() +{ + alternate_paths_cache .clear(); + + //Initialize alternate_paths + std::string line ; + std::ifstream proc_partitions( "/proc/partitions" ) ; + if ( proc_partitions ) + { + char c_str[4096+1] ; + + while ( getline( proc_partitions, line ) ) + if ( sscanf( line .c_str(), "%*d %*d %*d %4096s", c_str ) == 1 ) + { + line = "/dev/" ; + line += c_str ; + + //FIXME: it seems realpath is very unsafe to use (manpage)... + if ( file_test( line, Glib::FILE_TEST_EXISTS ) + && realpath( line .c_str(), c_str ) + //&& line != c_str + ) + { + //Because we can make no assumption about which path libparted will + //detect, we add all combinations. + alternate_paths_cache[ c_str ] = line ; + alternate_paths_cache[ line ] = c_str ; + } + } + + proc_partitions .close() ; + } +} + +}//GParted