Reduce threading (#685740)
Win_Gparted and Dialog_Progress were creating threads to perform most functions in the background. Most of the time, the only reason the threads blocked was to execute an external command. The external command execution has been changed to spawn the command asynchronously and wait for completion with a nested main loop. While waiting for completion, the pipe output is captured via events. In the future, this will allow for it to be parsed in real time to obtain progress information. Those tasks in GParted_Core that still block now spawn a background thread and wait for it to complete with a nested main loop to avoid hanging the gui. Part of Bug #685740 - Refactor to use asynchronous command execution
This commit is contained in:
parent
2706f0174a
commit
52a2a9b00a
|
@ -46,11 +46,10 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void on_signal_update( const OperationDetail & operationdetail ) ;
|
void on_signal_update( const OperationDetail & operationdetail ) ;
|
||||||
void dispatcher_on_update_gui_elements() ;
|
void update_gui_elements() ;
|
||||||
void on_signal_show() ;
|
void on_signal_show() ;
|
||||||
void on_expander_changed() ;
|
void on_expander_changed() ;
|
||||||
void on_cell_data_description( Gtk::CellRenderer * renderer, const Gtk::TreeModel::iterator & iter) ;
|
void on_cell_data_description( Gtk::CellRenderer * renderer, const Gtk::TreeModel::iterator & iter) ;
|
||||||
void thread_apply_operation();
|
|
||||||
void on_cancel() ;
|
void on_cancel() ;
|
||||||
void on_save() ;
|
void on_save() ;
|
||||||
void echo_operation_details( const OperationDetail & operation_detail, std::ofstream & out ) ;
|
void echo_operation_details( const OperationDetail & operation_detail, std::ofstream & out ) ;
|
||||||
|
@ -97,7 +96,6 @@ private:
|
||||||
double fraction ;
|
double fraction ;
|
||||||
unsigned int t, warnings ;
|
unsigned int t, warnings ;
|
||||||
sigc::connection pulsetimer;
|
sigc::connection pulsetimer;
|
||||||
Glib::Dispatcher dispatcher_update_gui_elements ;
|
|
||||||
Glib::ustring label_current_sub_text ;
|
Glib::ustring label_current_sub_text ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define DEFINE_FILESYSTEM
|
#define DEFINE_FILESYSTEM
|
||||||
|
|
||||||
#include "../include/Operation.h"
|
#include "../include/Operation.h"
|
||||||
|
#include "../include/PipeCapture.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
@ -56,12 +57,12 @@ public:
|
||||||
OperationDetail & operationdetail ) = 0 ;
|
OperationDetail & operationdetail ) = 0 ;
|
||||||
virtual bool check_repair( const Partition & partition, OperationDetail & operationdetail ) = 0 ;
|
virtual bool check_repair( const Partition & partition, OperationDetail & operationdetail ) = 0 ;
|
||||||
virtual bool remove( const Partition & partition, OperationDetail & operationdetail ) = 0 ;
|
virtual bool remove( const Partition & partition, OperationDetail & operationdetail ) = 0 ;
|
||||||
|
bool success;
|
||||||
protected:
|
protected:
|
||||||
int execute_command( const Glib::ustring & command, OperationDetail & operationdetail ) ;
|
int execute_command( const Glib::ustring & command, OperationDetail & operationdetail, bool checkstatus = false );
|
||||||
int execute_command_timed( const Glib::ustring & command
|
int execute_command_timed( const Glib::ustring & command, OperationDetail & operationdetail ) {
|
||||||
, OperationDetail & operationdetail
|
return execute_command( command, operationdetail, true ); }
|
||||||
, bool check_status = true ) ;
|
void execute_command_eof();
|
||||||
Glib::ustring mk_temp_dir( const Glib::ustring & infix, OperationDetail & operationdetail ) ;
|
Glib::ustring mk_temp_dir( const Glib::ustring & infix, OperationDetail & operationdetail ) ;
|
||||||
void rm_temp_dir( const Glib::ustring dir_name, OperationDetail & operationdetail ) ;
|
void rm_temp_dir( const Glib::ustring dir_name, OperationDetail & operationdetail ) ;
|
||||||
|
|
||||||
|
@ -72,7 +73,9 @@ protected:
|
||||||
unsigned int index ;
|
unsigned int index ;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void store_exit_status( GPid pid, int status );
|
||||||
|
bool running;
|
||||||
|
int pipecount;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //GParted
|
} //GParted
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
void find_supported_filesystems() ;
|
void find_supported_filesystems() ;
|
||||||
void set_user_devices( const std::vector<Glib::ustring> & user_devices ) ;
|
void set_user_devices( const std::vector<Glib::ustring> & user_devices ) ;
|
||||||
void set_devices( std::vector<Device> & devices ) ;
|
void set_devices( std::vector<Device> & devices ) ;
|
||||||
|
void set_devices_thread( std::vector<Device> * pdevices );
|
||||||
void guess_partition_table(const Device & device, Glib::ustring &buff);
|
void guess_partition_table(const Device & device, Glib::ustring &buff);
|
||||||
|
|
||||||
bool snap_to_cylinder( const Device & device, Partition & partition, Glib::ustring & error ) ;
|
bool snap_to_cylinder( const Device & device, Partition & partition, Glib::ustring & error ) ;
|
||||||
|
|
|
@ -55,4 +55,5 @@ EXTRA_DIST = \
|
||||||
reiser4.h \
|
reiser4.h \
|
||||||
reiserfs.h \
|
reiserfs.h \
|
||||||
ufs.h \
|
ufs.h \
|
||||||
xfs.h
|
xfs.h \
|
||||||
|
PipeCapture.h
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef PIPECAPTURE_H
|
||||||
|
#define PIPECAPTURE_H
|
||||||
|
|
||||||
|
#include <glibmm/ustring.h>
|
||||||
|
#include <glibmm/main.h>
|
||||||
|
#include <glibmm/iochannel.h>
|
||||||
|
|
||||||
|
namespace GParted {
|
||||||
|
|
||||||
|
// captures output pipe of subprocess into a ustring and emits a signal on eof
|
||||||
|
class PipeCapture
|
||||||
|
{
|
||||||
|
Glib::ustring &buff;
|
||||||
|
unsigned int backcount;
|
||||||
|
unsigned int linelength;
|
||||||
|
Glib::RefPtr<Glib::IOChannel> channel;
|
||||||
|
sigc::connection connection;
|
||||||
|
bool OnReadable( Glib::IOCondition condition );
|
||||||
|
public:
|
||||||
|
PipeCapture( int fd, Glib::ustring &buffer );
|
||||||
|
void connect_signal( int fd );
|
||||||
|
~PipeCapture();
|
||||||
|
sigc::signal<void> eof;
|
||||||
|
sigc::signal<void> update;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namepace GParted
|
||||||
|
|
||||||
|
#endif
|
|
@ -178,7 +178,6 @@ public:
|
||||||
const char drive_letter, const Glib::ustring & device_path ) ;
|
const char drive_letter, const Glib::ustring & device_path ) ;
|
||||||
static Glib::ustring delete_mtoolsrc_file( const char file_name[] ) ;
|
static Glib::ustring delete_mtoolsrc_file( const char file_name[] ) ;
|
||||||
static Glib::ustring trim( const Glib::ustring & src, const Glib::ustring & c = " \t\r\n" ) ;
|
static Glib::ustring trim( const Glib::ustring & src, const Glib::ustring & c = " \t\r\n" ) ;
|
||||||
static Glib::ustring cleanup_cursor( const Glib::ustring & text ) ;
|
|
||||||
static Glib::ustring get_lang() ;
|
static Glib::ustring get_lang() ;
|
||||||
static void tokenize( const Glib::ustring& str,
|
static void tokenize( const Glib::ustring& str,
|
||||||
std::vector<Glib::ustring>& tokens,
|
std::vector<Glib::ustring>& tokens,
|
||||||
|
@ -196,7 +195,6 @@ private:
|
||||||
static bool get_kernel_version( int & major_ver, int & minor_ver, int & patch_ver ) ;
|
static bool get_kernel_version( int & major_ver, int & minor_ver, int & patch_ver ) ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}//GParted
|
}//GParted
|
||||||
|
|
||||||
#endif //UTILS
|
#endif //UTILS
|
||||||
|
|
|
@ -55,7 +55,7 @@ private:
|
||||||
|
|
||||||
void refresh_combo_devices() ;
|
void refresh_combo_devices() ;
|
||||||
void show_pulsebar( const Glib::ustring & status_message ) ;
|
void show_pulsebar( const Glib::ustring & status_message ) ;
|
||||||
|
void hide_pulsebar();
|
||||||
//Fill txtview_device_info_buffer with some information about the selected device
|
//Fill txtview_device_info_buffer with some information about the selected device
|
||||||
void Fill_Label_Device_Info( bool clear = false );
|
void Fill_Label_Device_Info( bool clear = false );
|
||||||
|
|
||||||
|
@ -126,12 +126,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
//threads..
|
//threads..
|
||||||
void thread_refresh_devices() ;
|
void unmount_partition( bool * succes, Glib::ustring * error );
|
||||||
void thread_unmount_partition( bool * succes, Glib::ustring * error ) ;
|
|
||||||
void thread_mount_partition( Glib::ustring mountpoint, bool * succes, Glib::ustring * error ) ;
|
|
||||||
void thread_toggle_swap( bool * succes, Glib::ustring * error ) ;
|
|
||||||
void thread_toggle_lvm2_pv( bool * succes, Glib::ustring * error ) ;
|
|
||||||
void thread_guess_partition_table();
|
|
||||||
|
|
||||||
//signal handlers
|
//signal handlers
|
||||||
void open_operationslist() ;
|
void open_operationslist() ;
|
||||||
|
@ -260,6 +255,7 @@ private:
|
||||||
|
|
||||||
//stuff for progress overview and pulsebar
|
//stuff for progress overview and pulsebar
|
||||||
bool pulsebar_pulse();
|
bool pulsebar_pulse();
|
||||||
|
sigc::connection pulsetimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //GParted
|
} //GParted
|
||||||
|
|
|
@ -38,9 +38,6 @@ Dialog_Progress::Dialog_Progress( const std::vector<Operation *> & operations )
|
||||||
|
|
||||||
fraction = 1.00 / operations .size() ;
|
fraction = 1.00 / operations .size() ;
|
||||||
|
|
||||||
dispatcher_update_gui_elements .connect(
|
|
||||||
sigc::mem_fun( this, &Dialog_Progress::dispatcher_on_update_gui_elements ) ) ;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Gtk::VBox* vbox(manage(new Gtk::VBox()));
|
Gtk::VBox* vbox(manage(new Gtk::VBox()));
|
||||||
|
|
||||||
|
@ -158,12 +155,12 @@ void Dialog_Progress::on_signal_update( const OperationDetail & operationdetail
|
||||||
if ( operationdetail .get_status() == STATUS_EXECUTE )
|
if ( operationdetail .get_status() == STATUS_EXECUTE )
|
||||||
label_current_sub_text = operationdetail .get_description() ;
|
label_current_sub_text = operationdetail .get_description() ;
|
||||||
|
|
||||||
dispatcher_update_gui_elements() ;
|
|
||||||
if ( operationdetail.fraction >= 0 ) {
|
if ( operationdetail.fraction >= 0 ) {
|
||||||
pulsetimer.disconnect();
|
pulsetimer.disconnect();
|
||||||
progressbar_current.set_fraction( operationdetail.fraction > 1.0 ? 1.0 : operationdetail.fraction );
|
progressbar_current.set_fraction( operationdetail.fraction > 1.0 ? 1.0 : operationdetail.fraction );
|
||||||
} else if( !pulsetimer.connected() )
|
} else if( !pulsetimer.connected() )
|
||||||
pulsetimer = Glib::signal_timeout().connect( sigc::mem_fun(*this, &Dialog_Progress::pulsebar_pulse), 100 );
|
pulsetimer = Glib::signal_timeout().connect( sigc::mem_fun(*this, &Dialog_Progress::pulsebar_pulse), 100 );
|
||||||
|
update_gui_elements();
|
||||||
}
|
}
|
||||||
else//it's an new od which needs to be added to the model.
|
else//it's an new od which needs to be added to the model.
|
||||||
{
|
{
|
||||||
|
@ -182,7 +179,7 @@ void Dialog_Progress::on_signal_update( const OperationDetail & operationdetail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dialog_Progress::dispatcher_on_update_gui_elements()
|
void Dialog_Progress::update_gui_elements()
|
||||||
{
|
{
|
||||||
label_current_sub .set_markup( "<i>" + label_current_sub_text + "</i>\n" ) ;
|
label_current_sub .set_markup( "<i>" + label_current_sub_text + "</i>\n" ) ;
|
||||||
|
|
||||||
|
@ -216,11 +213,7 @@ void Dialog_Progress::on_signal_show()
|
||||||
//set focus...
|
//set focus...
|
||||||
treeview_operations .set_cursor( static_cast<Gtk::TreePath>( treerow ) ) ;
|
treeview_operations .set_cursor( static_cast<Gtk::TreePath>( treerow ) ) ;
|
||||||
|
|
||||||
//and start..
|
succes = signal_apply_operation.emit( operations[t] );
|
||||||
Glib::Thread::create( sigc::mem_fun(
|
|
||||||
*this, &Dialog_Progress::thread_apply_operation ),
|
|
||||||
false );
|
|
||||||
Gtk::Main::run();
|
|
||||||
|
|
||||||
//set status (succes/error) for this operation
|
//set status (succes/error) for this operation
|
||||||
operations[ t ] ->operation_detail .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
operations[ t ] ->operation_detail .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
|
||||||
|
@ -299,18 +292,6 @@ void Dialog_Progress::on_cell_data_description( Gtk::CellRenderer * renderer, co
|
||||||
static_cast<Gtk::TreeRow>( *iter )[ treeview_operations_columns .operation_description ] ;
|
static_cast<Gtk::TreeRow>( *iter )[ treeview_operations_columns .operation_description ] ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _mainquit( void *dummy )
|
|
||||||
{
|
|
||||||
Gtk::Main::quit();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dialog_Progress::thread_apply_operation()
|
|
||||||
{
|
|
||||||
succes = signal_apply_operation.emit( operations[t] );
|
|
||||||
g_idle_add( (GSourceFunc)_mainquit, NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dialog_Progress::on_cancel()
|
void Dialog_Progress::on_cancel()
|
||||||
{
|
{
|
||||||
Gtk::MessageDialog dialog( *this,
|
Gtk::MessageDialog dialog( *this,
|
||||||
|
|
|
@ -17,8 +17,12 @@
|
||||||
|
|
||||||
|
|
||||||
#include "../include/FileSystem.h"
|
#include "../include/FileSystem.h"
|
||||||
|
#include "../include/GParted_Core.h"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
#include <iostream>
|
||||||
|
#include <gtkmm/main.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
namespace GParted
|
namespace GParted
|
||||||
{
|
{
|
||||||
|
@ -48,46 +52,89 @@ const Glib::ustring FileSystem::get_generic_text( CUSTOM_TEXT ttype, int index )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSystem::execute_command( const Glib::ustring & command, OperationDetail & operationdetail )
|
void FileSystem::store_exit_status( GPid pid, int status )
|
||||||
{
|
{
|
||||||
operationdetail .add_child( OperationDetail( command, STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
|
exit_status = status;
|
||||||
|
running = false;
|
||||||
int exit_status = Utils::execute_command( "nice -n 19 " + command, output, error ) ;
|
if (pipecount == 0) // pipes finished first
|
||||||
|
Gtk::Main::quit();
|
||||||
if ( ! output .empty() )
|
Glib::spawn_close_pid( pid );
|
||||||
operationdetail .get_last_child() .add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ) ;
|
|
||||||
|
|
||||||
if ( ! error .empty() )
|
|
||||||
operationdetail .get_last_child() .add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ) ;
|
|
||||||
|
|
||||||
return exit_status ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Time command, add results to operation detail and by default set success or failure
|
static void relay_update( OperationDetail *operationdetail, Glib::ustring *str )
|
||||||
int FileSystem::execute_command_timed( const Glib::ustring & command
|
|
||||||
, OperationDetail & operationdetail
|
|
||||||
, bool check_status )
|
|
||||||
{
|
{
|
||||||
operationdetail .add_child( OperationDetail( command, STATUS_EXECUTE, FONT_BOLD_ITALIC ) ) ;
|
operationdetail->set_description( *str, FONT_ITALIC );
|
||||||
|
}
|
||||||
|
|
||||||
int exit_status = Utils::execute_command( "nice -n 19 " + command, output, error ) ;
|
int FileSystem::execute_command( const Glib::ustring & command, OperationDetail & operationdetail, bool checkstatus )
|
||||||
if ( check_status )
|
|
||||||
{
|
{
|
||||||
|
operationdetail .add_child( OperationDetail( command, checkstatus ? STATUS_EXECUTE : STATUS_NONE, FONT_BOLD_ITALIC ) ) ;
|
||||||
|
Glib::Pid pid;
|
||||||
|
// set up pipes for capture
|
||||||
|
int out, err;
|
||||||
|
// spawn external process
|
||||||
|
running = true;
|
||||||
|
try {
|
||||||
|
Glib::spawn_async_with_pipes(
|
||||||
|
std::string(),
|
||||||
|
Glib::shell_parse_argv( command ),
|
||||||
|
Glib::SPAWN_DO_NOT_REAP_CHILD | Glib::SPAWN_SEARCH_PATH,
|
||||||
|
sigc::slot< void >(),
|
||||||
|
&pid,
|
||||||
|
0,
|
||||||
|
&out,
|
||||||
|
&err );
|
||||||
|
} catch (Glib::SpawnError &e) {
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
operationdetail.get_last_child().add_child(
|
||||||
|
OperationDetail( e.what(), STATUS_ERROR, FONT_ITALIC ) );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fcntl( out, F_SETFL, O_NONBLOCK );
|
||||||
|
fcntl( err, F_SETFL, O_NONBLOCK );
|
||||||
|
Glib::signal_child_watch().connect( sigc::mem_fun( *this, &FileSystem::store_exit_status ), pid );
|
||||||
|
output.clear();
|
||||||
|
error.clear();
|
||||||
|
pipecount = 2;
|
||||||
|
PipeCapture outputcapture( out, output );
|
||||||
|
PipeCapture errorcapture( err, error );
|
||||||
|
outputcapture.eof.connect( sigc::mem_fun( *this, &FileSystem::execute_command_eof ) );
|
||||||
|
errorcapture.eof.connect( sigc::mem_fun( *this, &FileSystem::execute_command_eof ) );
|
||||||
|
operationdetail.get_last_child().add_child(
|
||||||
|
OperationDetail( output, STATUS_NONE, FONT_ITALIC ) );
|
||||||
|
operationdetail.get_last_child().add_child(
|
||||||
|
OperationDetail( error, STATUS_NONE, FONT_ITALIC ) );
|
||||||
|
std::vector<OperationDetail> &children = operationdetail.get_last_child().get_childs();
|
||||||
|
outputcapture.update.connect( sigc::bind( sigc::ptr_fun( relay_update ),
|
||||||
|
&(children[children.size() - 2]),
|
||||||
|
&output ) );
|
||||||
|
errorcapture.update.connect( sigc::bind( sigc::ptr_fun( relay_update ),
|
||||||
|
&(children[children.size() - 1]),
|
||||||
|
&error ) );
|
||||||
|
outputcapture.connect_signal( out );
|
||||||
|
errorcapture.connect_signal( err );
|
||||||
|
|
||||||
|
Gtk::Main::run();
|
||||||
|
|
||||||
|
if (checkstatus) {
|
||||||
if ( !exit_status )
|
if ( !exit_status )
|
||||||
operationdetail.get_last_child().set_status( STATUS_SUCCES );
|
operationdetail.get_last_child().set_status( STATUS_SUCCES );
|
||||||
else
|
else
|
||||||
operationdetail.get_last_child().set_status( STATUS_ERROR );
|
operationdetail.get_last_child().set_status( STATUS_ERROR );
|
||||||
}
|
}
|
||||||
|
close( out );
|
||||||
if ( ! output .empty() )
|
close( err );
|
||||||
operationdetail .get_last_child() .add_child( OperationDetail( output, STATUS_NONE, FONT_ITALIC ) ) ;
|
|
||||||
|
|
||||||
if ( ! error .empty() )
|
|
||||||
operationdetail .get_last_child() .add_child( OperationDetail( error, STATUS_NONE, FONT_ITALIC ) ) ;
|
|
||||||
|
|
||||||
return exit_status;
|
return exit_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileSystem::execute_command_eof()
|
||||||
|
{
|
||||||
|
if (--pipecount)
|
||||||
|
return; // wait for second pipe to eof
|
||||||
|
if ( !running ) // already got exit status
|
||||||
|
Gtk::Main::quit();
|
||||||
|
}
|
||||||
|
|
||||||
//Create uniquely named temporary directory and add results to operation detail
|
//Create uniquely named temporary directory and add results to operation detail
|
||||||
Glib::ustring FileSystem::mk_temp_dir( const Glib::ustring & infix, OperationDetail & operationdetail )
|
Glib::ustring FileSystem::mk_temp_dir( const Glib::ustring & infix, OperationDetail & operationdetail )
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <mntent.h>
|
#include <mntent.h>
|
||||||
#include <gtkmm/messagedialog.h>
|
#include <gtkmm/messagedialog.h>
|
||||||
|
#include <gtkmm/main.h>
|
||||||
|
|
||||||
std::vector<Glib::ustring> libparted_messages ; //see ped_exception_handler()
|
std::vector<Glib::ustring> libparted_messages ; //see ped_exception_handler()
|
||||||
|
|
||||||
|
@ -138,6 +139,22 @@ void GParted_Core::set_user_devices( const std::vector<Glib::ustring> & user_dev
|
||||||
|
|
||||||
void GParted_Core::set_devices( std::vector<Device> & devices )
|
void GParted_Core::set_devices( std::vector<Device> & devices )
|
||||||
{
|
{
|
||||||
|
Glib::Thread::create( sigc::bind(
|
||||||
|
sigc::mem_fun( *this, &GParted_Core::set_devices_thread ),
|
||||||
|
&devices),
|
||||||
|
false );
|
||||||
|
Gtk::Main::run();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool _mainquit( void *dummy )
|
||||||
|
{
|
||||||
|
Gtk::Main::quit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
|
||||||
|
{
|
||||||
|
std::vector<Device> &devices = *pdevices;
|
||||||
devices .clear() ;
|
devices .clear() ;
|
||||||
Device temp_device ;
|
Device temp_device ;
|
||||||
Proc_Partitions_Info pp_info( true ) ; //Refresh cache of proc partition information
|
Proc_Partitions_Info pp_info( true ) ; //Refresh cache of proc partition information
|
||||||
|
@ -325,6 +342,7 @@ void GParted_Core::set_devices( std::vector<Device> & devices )
|
||||||
//NOTE that we cannot clear mountinfo since it might be needed in get_all_mountpoints()
|
//NOTE that we cannot clear mountinfo since it might be needed in get_all_mountpoints()
|
||||||
set_thread_status_message("") ;
|
set_thread_status_message("") ;
|
||||||
fstab_info .clear() ;
|
fstab_info .clear() ;
|
||||||
|
g_idle_add( (GSourceFunc)_mainquit, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
// runs gpart on the specified parameter
|
// runs gpart on the specified parameter
|
||||||
|
@ -3548,13 +3566,13 @@ public:
|
||||||
struct ped_exception_ctx {
|
struct ped_exception_ctx {
|
||||||
PedExceptionOption ret;
|
PedExceptionOption ret;
|
||||||
PedException *e;
|
PedException *e;
|
||||||
Glib::Threads::Mutex mutex;
|
Glib::Mutex mutex;
|
||||||
Glib::Threads::Cond cond;
|
Glib::Cond cond;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool _ped_exception_handler( struct ped_exception_ctx *ctx )
|
static bool _ped_exception_handler( struct ped_exception_ctx *ctx )
|
||||||
{
|
{
|
||||||
std::cout << ctx->e->message << std::endl;
|
std::cerr << ctx->e->message << std::endl;
|
||||||
|
|
||||||
libparted_messages.push_back( ctx->e->message );
|
libparted_messages.push_back( ctx->e->message );
|
||||||
char optcount = 0;
|
char optcount = 0;
|
||||||
|
|
|
@ -65,7 +65,8 @@ gpartedbin_SOURCES = \
|
||||||
reiser4.cc \
|
reiser4.cc \
|
||||||
reiserfs.cc \
|
reiserfs.cc \
|
||||||
ufs.cc \
|
ufs.cc \
|
||||||
xfs.cc
|
xfs.cc \
|
||||||
|
PipeCapture.cc
|
||||||
|
|
||||||
gpartedbin_LDFLAGS = -lparted
|
gpartedbin_LDFLAGS = -lparted
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ OperationDetail & OperationDetail::get_last_child()
|
||||||
if ( sub_details .size() == 0 )
|
if ( sub_details .size() == 0 )
|
||||||
add_child( OperationDetail( "---", STATUS_ERROR ) ) ;
|
add_child( OperationDetail( "---", STATUS_ERROR ) ) ;
|
||||||
|
|
||||||
return sub_details .back() ;
|
return sub_details[sub_details.size() - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void OperationDetail::on_update( const OperationDetail & operationdetail )
|
void OperationDetail::on_update( const OperationDetail & operationdetail )
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
#include "../include/PipeCapture.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace GParted {
|
||||||
|
|
||||||
|
PipeCapture::PipeCapture( int fd, Glib::ustring &string ) : buff( string ), backcount( 0 ), linelength( 0 )
|
||||||
|
{
|
||||||
|
// tie fd to string
|
||||||
|
// make channel
|
||||||
|
channel = Glib::IOChannel::create_from_fd( fd );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipeCapture::connect_signal( int fd )
|
||||||
|
{
|
||||||
|
// connect handler to signal input/output
|
||||||
|
connection = Glib::signal_io().connect(
|
||||||
|
sigc::mem_fun( *this, &PipeCapture::OnReadable ),
|
||||||
|
fd,
|
||||||
|
Glib::IO_IN | Glib::IO_HUP | Glib::IO_ERR );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PipeCapture::OnReadable( Glib::IOCondition condition )
|
||||||
|
{
|
||||||
|
// read from pipe and store in buff
|
||||||
|
Glib::ustring str;
|
||||||
|
Glib::IOStatus status = channel->read( str, 512 );
|
||||||
|
if (status == Glib::IO_STATUS_NORMAL)
|
||||||
|
{
|
||||||
|
for( Glib::ustring::iterator s = str.begin();
|
||||||
|
s != str.end(); s++ )
|
||||||
|
{
|
||||||
|
if( *s == '\b' )
|
||||||
|
backcount++;
|
||||||
|
else if( *s == '\r' )
|
||||||
|
backcount = linelength;
|
||||||
|
else if( *s == '\n' ) {
|
||||||
|
linelength = 0;
|
||||||
|
buff += '\n';
|
||||||
|
backcount = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (backcount) {
|
||||||
|
buff.erase( buff.length() - backcount, backcount );
|
||||||
|
linelength -= backcount;
|
||||||
|
backcount = 0;
|
||||||
|
}
|
||||||
|
buff += *s;
|
||||||
|
++linelength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (status != Glib::IO_STATUS_EOF)
|
||||||
|
std::cerr << "Pipe IOChannel read failed" << std::endl;
|
||||||
|
// signal completion
|
||||||
|
connection.disconnect();
|
||||||
|
eof();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipeCapture::~PipeCapture()
|
||||||
|
{
|
||||||
|
connection.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace GParted
|
183
src/Utils.cc
183
src/Utils.cc
|
@ -17,6 +17,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../include/Utils.h"
|
#include "../include/Utils.h"
|
||||||
|
#include "../include/GParted_Core.h"
|
||||||
|
#include "../include/PipeCapture.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -26,7 +28,8 @@
|
||||||
#include <uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
|
#include <gtkmm/main.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
namespace GParted
|
namespace GParted
|
||||||
{
|
{
|
||||||
|
@ -380,62 +383,113 @@ int Utils::execute_command( const Glib::ustring & command )
|
||||||
return execute_command( command, dummy, dummy ) ;
|
return execute_command( command, dummy, dummy ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class utils_execute_command_status
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool running;
|
||||||
|
int pipecount;
|
||||||
|
int exit_status;
|
||||||
|
bool foreground;
|
||||||
|
Glib::Mutex mutex;
|
||||||
|
Glib::Cond cond;
|
||||||
|
void store_exit_status( GPid pid, int status );
|
||||||
|
void execute_command_eof();
|
||||||
|
};
|
||||||
|
|
||||||
|
void utils_execute_command_status::store_exit_status( GPid pid, int status )
|
||||||
|
{
|
||||||
|
exit_status = status;
|
||||||
|
running = false;
|
||||||
|
if (pipecount == 0) // pipes finished first
|
||||||
|
{
|
||||||
|
if (foreground)
|
||||||
|
Gtk::Main::quit();
|
||||||
|
else {
|
||||||
|
mutex.lock();
|
||||||
|
cond.signal();
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Glib::spawn_close_pid( pid );
|
||||||
|
}
|
||||||
|
|
||||||
|
void utils_execute_command_status::execute_command_eof()
|
||||||
|
{
|
||||||
|
if (--pipecount)
|
||||||
|
return; // wait for second pipe to eof
|
||||||
|
if ( !running ) // already got exit status
|
||||||
|
{
|
||||||
|
if (foreground)
|
||||||
|
Gtk::Main::quit();
|
||||||
|
else {
|
||||||
|
mutex.lock();
|
||||||
|
cond.signal();
|
||||||
|
mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_locale()
|
||||||
|
{
|
||||||
|
setenv( "LC_ALL", "C", 1 );
|
||||||
|
}
|
||||||
|
|
||||||
int Utils::execute_command( const Glib::ustring & command,
|
int Utils::execute_command( const Glib::ustring & command,
|
||||||
Glib::ustring & output,
|
Glib::ustring & output,
|
||||||
Glib::ustring & error,
|
Glib::ustring & error,
|
||||||
bool use_C_locale )
|
bool use_C_locale )
|
||||||
{
|
{
|
||||||
int exit_status = -1 ;
|
Glib::Pid pid;
|
||||||
std::string std_out, std_error ;
|
// set up pipes for capture
|
||||||
|
int out, err;
|
||||||
try
|
utils_execute_command_status status;
|
||||||
{
|
// spawn external process
|
||||||
std::vector<std::string>argv;
|
status.running = true;
|
||||||
argv .push_back( "sh" ) ;
|
status.pipecount = 2;
|
||||||
argv .push_back( "-c" ) ;
|
status.foreground = (Glib::Thread::self() == GParted_Core::mainthread);
|
||||||
argv .push_back( command ) ;
|
try {
|
||||||
|
Glib::spawn_async_with_pipes(
|
||||||
if ( use_C_locale )
|
std::string(),
|
||||||
{
|
Glib::shell_parse_argv( command ),
|
||||||
//Spawn command using the C language environment
|
Glib::SPAWN_DO_NOT_REAP_CHILD | Glib::SPAWN_SEARCH_PATH,
|
||||||
std::vector<std::string> envp ;
|
use_C_locale ? sigc::ptr_fun( set_locale ) : sigc::slot< void >(),
|
||||||
envp .push_back( "LC_ALL=C" ) ;
|
&pid,
|
||||||
envp .push_back( "PATH=" + Glib::getenv( "PATH" ) ) ;
|
0,
|
||||||
|
&out,
|
||||||
Glib::spawn_sync( "."
|
&err );
|
||||||
, argv
|
} catch (Glib::SpawnError &e) {
|
||||||
, envp
|
std::cerr << e.what() << std::endl;
|
||||||
, Glib::SPAWN_SEARCH_PATH
|
return 1;
|
||||||
, sigc::slot<void>()
|
|
||||||
, &std_out
|
|
||||||
, &std_error
|
|
||||||
, &exit_status
|
|
||||||
) ;
|
|
||||||
}
|
}
|
||||||
else
|
fcntl( out, F_SETFL, O_NONBLOCK );
|
||||||
{
|
fcntl( err, F_SETFL, O_NONBLOCK );
|
||||||
//Spawn command inheriting the parent's environment
|
Glib::signal_child_watch().connect( sigc::mem_fun(
|
||||||
Glib::spawn_sync( "."
|
status, &utils_execute_command_status::store_exit_status ),
|
||||||
, argv
|
pid );
|
||||||
, Glib::SPAWN_SEARCH_PATH
|
output.clear();
|
||||||
, sigc::slot<void>()
|
error.clear();
|
||||||
, &std_out
|
//Lock mutex so we have time to setup pipecapture for output and error streams
|
||||||
, &std_error
|
// before connecting the input/output signal handler
|
||||||
, &exit_status
|
if( !status.foreground )
|
||||||
) ;
|
status.mutex.lock();
|
||||||
}
|
PipeCapture outputcapture( out, output );
|
||||||
}
|
PipeCapture errorcapture( err, error );
|
||||||
catch ( Glib::Exception & e )
|
outputcapture.eof.connect( sigc::mem_fun(
|
||||||
{
|
status, &utils_execute_command_status::execute_command_eof ));
|
||||||
error = e .what() ;
|
errorcapture.eof.connect( sigc::mem_fun(
|
||||||
|
status, &utils_execute_command_status::execute_command_eof ));
|
||||||
|
outputcapture.connect_signal( out );
|
||||||
|
errorcapture.connect_signal( err );
|
||||||
|
|
||||||
return -1 ;
|
if( status.foreground)
|
||||||
|
Gtk::Main::run();
|
||||||
|
else {
|
||||||
|
status.cond.wait( status.mutex );
|
||||||
|
status.mutex.unlock();
|
||||||
}
|
}
|
||||||
|
close( out );
|
||||||
output = Utils::cleanup_cursor( std_out ) ;
|
close( err );
|
||||||
error = std_error ;
|
return status.exit_status;
|
||||||
|
|
||||||
return exit_status ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Glib::ustring Utils::regexp_label( const Glib::ustring & text
|
Glib::ustring Utils::regexp_label( const Glib::ustring & text
|
||||||
|
@ -468,37 +522,6 @@ Glib::ustring Utils::trim( const Glib::ustring & src, const Glib::ustring & c /*
|
||||||
return src.substr(p1, (p2-p1)+1);
|
return src.substr(p1, (p2-p1)+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Glib::ustring Utils::cleanup_cursor( const Glib::ustring & text )
|
|
||||||
{
|
|
||||||
std::istringstream in(text);
|
|
||||||
std::ostringstream out;
|
|
||||||
char ch;
|
|
||||||
std::streampos startofline = out.tellp();
|
|
||||||
|
|
||||||
while (in.get(ch))
|
|
||||||
{
|
|
||||||
switch(ch)
|
|
||||||
{
|
|
||||||
case '\r':
|
|
||||||
if ('\n' != in.peek()) // for windows CRLF
|
|
||||||
out.seekp(startofline);
|
|
||||||
else
|
|
||||||
out.put(ch);
|
|
||||||
break;
|
|
||||||
case '\b':
|
|
||||||
if (out.tellp() > startofline)
|
|
||||||
out.seekp(out.tellp() - std::streamoff(1));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
out.put(ch);
|
|
||||||
}
|
|
||||||
if (ch == '\n')
|
|
||||||
startofline = out.tellp();
|
|
||||||
}
|
|
||||||
|
|
||||||
return out.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
Glib::ustring Utils::get_lang()
|
Glib::ustring Utils::get_lang()
|
||||||
{
|
{
|
||||||
//Extract base language from string that may look like "en_CA.UTF-8"
|
//Extract base language from string that may look like "en_CA.UTF-8"
|
||||||
|
|
|
@ -621,8 +621,6 @@ bool Win_GParted::pulsebar_pulse()
|
||||||
|
|
||||||
void Win_GParted::show_pulsebar( const Glib::ustring & status_message )
|
void Win_GParted::show_pulsebar( const Glib::ustring & status_message )
|
||||||
{
|
{
|
||||||
sigc::connection pulsetimer;
|
|
||||||
|
|
||||||
pulsebar .show();
|
pulsebar .show();
|
||||||
statusbar .push( status_message) ;
|
statusbar .push( status_message) ;
|
||||||
|
|
||||||
|
@ -636,7 +634,10 @@ void Win_GParted::show_pulsebar( const Glib::ustring & status_message )
|
||||||
|
|
||||||
// connect pulse update timer
|
// connect pulse update timer
|
||||||
pulsetimer = Glib::signal_timeout().connect( sigc::mem_fun(*this, &Win_GParted::pulsebar_pulse), 100 );
|
pulsetimer = Glib::signal_timeout().connect( sigc::mem_fun(*this, &Win_GParted::pulsebar_pulse), 100 );
|
||||||
Gtk::Main::run();
|
}
|
||||||
|
|
||||||
|
void Win_GParted::hide_pulsebar()
|
||||||
|
{
|
||||||
pulsetimer.disconnect();
|
pulsetimer.disconnect();
|
||||||
pulsebar .hide();
|
pulsebar .hide();
|
||||||
statusbar .pop() ;
|
statusbar .pop() ;
|
||||||
|
@ -1199,17 +1200,11 @@ void Win_GParted::on_show()
|
||||||
menu_gparted_refresh_devices() ;
|
menu_gparted_refresh_devices() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win_GParted::thread_refresh_devices()
|
|
||||||
{
|
|
||||||
gparted_core .set_devices( devices ) ;
|
|
||||||
Gtk::Main::quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win_GParted::menu_gparted_refresh_devices()
|
void Win_GParted::menu_gparted_refresh_devices()
|
||||||
{
|
{
|
||||||
Glib::Thread::create( sigc::mem_fun( *this, &Win_GParted::thread_refresh_devices ), false );
|
|
||||||
|
|
||||||
show_pulsebar( _("Scanning all devices...") ) ;
|
show_pulsebar( _("Scanning all devices...") ) ;
|
||||||
|
gparted_core.set_devices( devices );
|
||||||
|
hide_pulsebar();
|
||||||
|
|
||||||
//check if current_device is still available (think about hotpluggable stuff like usbdevices)
|
//check if current_device is still available (think about hotpluggable stuff like usbdevices)
|
||||||
if ( current_device >= devices .size() )
|
if ( current_device >= devices .size() )
|
||||||
|
@ -1981,7 +1976,7 @@ void Win_GParted::activate_format( GParted::FILESYSTEM new_fs )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win_GParted::thread_unmount_partition( bool * succes, Glib::ustring * error )
|
void Win_GParted::unmount_partition( bool * succes, Glib::ustring * error )
|
||||||
{
|
{
|
||||||
std::vector<Glib::ustring> errors, failed_mountpoints, mountpoints = gparted_core .get_all_mountpoints() ;
|
std::vector<Glib::ustring> errors, failed_mountpoints, mountpoints = gparted_core .get_all_mountpoints() ;
|
||||||
Glib::ustring dummy ;
|
Glib::ustring dummy ;
|
||||||
|
@ -2013,63 +2008,15 @@ void Win_GParted::thread_unmount_partition( bool * succes, Glib::ustring * error
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*error = "<i>" + Glib::build_path( "\n", errors ) + "</i>" ;
|
*error = "<i>" + Glib::build_path( "\n", errors ) + "</i>" ;
|
||||||
|
|
||||||
Gtk::Main::quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win_GParted::thread_mount_partition( Glib::ustring mountpoint, bool * succes, Glib::ustring * error )
|
|
||||||
{
|
|
||||||
Glib::ustring dummy ;
|
|
||||||
std::vector<Glib::ustring> errors ;
|
|
||||||
|
|
||||||
*succes = ! Utils::execute_command( "mount -v " + selected_partition .get_path() + " \"" + mountpoint + "\"",
|
|
||||||
dummy,
|
|
||||||
*error ) ;
|
|
||||||
Gtk::Main::quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win_GParted::thread_toggle_swap( bool * succes, Glib::ustring * error )
|
|
||||||
{
|
|
||||||
Glib::ustring dummy ;
|
|
||||||
|
|
||||||
if ( selected_partition .busy )
|
|
||||||
*succes = ! Utils::execute_command( "swapoff -v " + selected_partition .get_path() + " && sync",
|
|
||||||
dummy,
|
|
||||||
*error ) ;
|
|
||||||
else
|
|
||||||
*succes = ! Utils::execute_command( "swapon -v " + selected_partition .get_path() + " && sync",
|
|
||||||
dummy,
|
|
||||||
*error ) ;
|
|
||||||
Gtk::Main::quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win_GParted::thread_toggle_lvm2_pv( bool * success, Glib::ustring * error )
|
|
||||||
{
|
|
||||||
Glib::ustring dummy ;
|
|
||||||
|
|
||||||
if ( selected_partition .busy )
|
|
||||||
//VGNAME from mount point
|
|
||||||
*success = ! Utils::execute_command( "lvm vgchange -a n " + selected_partition .get_mountpoint(),
|
|
||||||
dummy,
|
|
||||||
*error ) ;
|
|
||||||
else
|
|
||||||
*success = ! Utils::execute_command( "lvm vgchange -a y " + selected_partition .get_mountpoint(),
|
|
||||||
dummy,
|
|
||||||
*error ) ;
|
|
||||||
Gtk::Main::quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Runs gpart in a thread
|
|
||||||
void Win_GParted::thread_guess_partition_table()
|
|
||||||
{
|
|
||||||
this->gpart_output="";
|
|
||||||
this->gparted_core.guess_partition_table(devices[ current_device ], this->gpart_output);
|
|
||||||
Gtk::Main::quit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Win_GParted::toggle_busy_state()
|
void Win_GParted::toggle_busy_state()
|
||||||
{
|
{
|
||||||
int operation_count = partition_in_operation_queue_count( selected_partition ) ;
|
int operation_count = partition_in_operation_queue_count( selected_partition ) ;
|
||||||
|
bool success = false ;
|
||||||
|
Glib::ustring error ;
|
||||||
|
Glib::ustring output;
|
||||||
|
|
||||||
if ( operation_count > 0 )
|
if ( operation_count > 0 )
|
||||||
{
|
{
|
||||||
//Note that this situation will only occur when trying to swapon a partition
|
//Note that this situation will only occur when trying to swapon a partition
|
||||||
|
@ -2112,20 +2059,22 @@ void Win_GParted::toggle_busy_state()
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool succes = false ;
|
|
||||||
Glib::ustring error ;
|
|
||||||
|
|
||||||
if ( selected_partition .filesystem == GParted::FS_LINUX_SWAP )
|
if ( selected_partition .filesystem == GParted::FS_LINUX_SWAP )
|
||||||
{
|
{
|
||||||
Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
|
|
||||||
sigc::mem_fun( *this, &Win_GParted::thread_toggle_swap ), &succes, &error ), false );
|
|
||||||
|
|
||||||
show_pulsebar(
|
show_pulsebar(
|
||||||
String::ucompose(
|
String::ucompose(
|
||||||
selected_partition .busy ? _("Deactivating swap on %1") : _("Activating swap on %1"),
|
selected_partition .busy ? _("Deactivating swap on %1") : _("Activating swap on %1"),
|
||||||
selected_partition .get_path() ) ) ;
|
selected_partition .get_path() ) ) ;
|
||||||
|
if ( selected_partition .busy )
|
||||||
if ( ! succes )
|
success = ! Utils::execute_command( "swapoff -v " + selected_partition .get_path(),
|
||||||
|
output,
|
||||||
|
error );
|
||||||
|
else
|
||||||
|
success = ! Utils::execute_command( "swapon -v " + selected_partition .get_path(),
|
||||||
|
output,
|
||||||
|
error );
|
||||||
|
hide_pulsebar();
|
||||||
|
if ( ! success )
|
||||||
{
|
{
|
||||||
Gtk::MessageDialog dialog(
|
Gtk::MessageDialog dialog(
|
||||||
*this,
|
*this,
|
||||||
|
@ -2142,17 +2091,24 @@ void Win_GParted::toggle_busy_state()
|
||||||
}
|
}
|
||||||
else if ( selected_partition .filesystem == GParted::FS_LVM2_PV )
|
else if ( selected_partition .filesystem == GParted::FS_LVM2_PV )
|
||||||
{
|
{
|
||||||
Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
|
|
||||||
sigc::mem_fun( *this, &Win_GParted::thread_toggle_lvm2_pv ), &succes, &error ), false );
|
|
||||||
|
|
||||||
show_pulsebar(
|
show_pulsebar(
|
||||||
String::ucompose(
|
String::ucompose(
|
||||||
selected_partition .busy ? _("Deactivating Volume Group %1")
|
selected_partition .busy ? _("Deactivating Volume Group %1")
|
||||||
: _("Activating Volume Group %1"),
|
: _("Activating Volume Group %1"),
|
||||||
//VGNAME from mount point
|
//VGNAME from mount point
|
||||||
selected_partition .get_mountpoint() ) ) ;
|
selected_partition .get_mountpoint() ) ) ;
|
||||||
|
if ( selected_partition .busy )
|
||||||
|
//VGNAME from mount point
|
||||||
|
success = ! Utils::execute_command( "lvm vgchange -a n " + selected_partition .get_mountpoint(),
|
||||||
|
output,
|
||||||
|
error );
|
||||||
|
else
|
||||||
|
success = ! Utils::execute_command( "lvm vgchange -a y " + selected_partition .get_mountpoint(),
|
||||||
|
output,
|
||||||
|
error );
|
||||||
|
hide_pulsebar();
|
||||||
|
|
||||||
if ( ! succes )
|
if ( ! success )
|
||||||
{
|
{
|
||||||
Gtk::MessageDialog dialog(
|
Gtk::MessageDialog dialog(
|
||||||
*this,
|
*this,
|
||||||
|
@ -2170,12 +2126,10 @@ void Win_GParted::toggle_busy_state()
|
||||||
}
|
}
|
||||||
else if ( selected_partition .busy )
|
else if ( selected_partition .busy )
|
||||||
{
|
{
|
||||||
Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
|
|
||||||
sigc::mem_fun( *this, &Win_GParted::thread_unmount_partition ), &succes, &error ), false );
|
|
||||||
|
|
||||||
show_pulsebar( String::ucompose( _("Unmounting %1"), selected_partition .get_path() ) ) ;
|
show_pulsebar( String::ucompose( _("Unmounting %1"), selected_partition .get_path() ) ) ;
|
||||||
|
unmount_partition( &success, &error );
|
||||||
if ( ! succes )
|
hide_pulsebar();
|
||||||
|
if ( ! success )
|
||||||
{
|
{
|
||||||
Gtk::MessageDialog dialog( *this,
|
Gtk::MessageDialog dialog( *this,
|
||||||
String::ucompose( _("Could not unmount %1"), selected_partition .get_path() ),
|
String::ucompose( _("Could not unmount %1"), selected_partition .get_path() ),
|
||||||
|
@ -2222,21 +2176,19 @@ void Win_GParted::activate_mount_partition( unsigned int index )
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool succes = false ;
|
bool success = false ;
|
||||||
Glib::ustring error ;
|
Glib::ustring error ;
|
||||||
|
Glib::ustring stdout;
|
||||||
Glib::Thread::create( sigc::bind<Glib::ustring, bool *, Glib::ustring *>(
|
|
||||||
sigc::mem_fun( *this, &Win_GParted::thread_mount_partition ),
|
|
||||||
selected_partition .get_mountpoints()[ index ],
|
|
||||||
&succes,
|
|
||||||
&error ),
|
|
||||||
false );
|
|
||||||
|
|
||||||
show_pulsebar( String::ucompose( _("mounting %1 on %2"),
|
show_pulsebar( String::ucompose( _("mounting %1 on %2"),
|
||||||
selected_partition .get_path(),
|
selected_partition .get_path(),
|
||||||
selected_partition .get_mountpoints()[ index ] ) ) ;
|
selected_partition .get_mountpoints()[ index ] ) ) ;
|
||||||
|
success = !Utils::execute_command( "mount -v " + selected_partition .get_path() + " \"" +
|
||||||
if ( ! succes )
|
selected_partition.get_mountpoints()[ index ] + "\"",
|
||||||
|
stdout,
|
||||||
|
error ) ;
|
||||||
|
hide_pulsebar();
|
||||||
|
if ( ! success )
|
||||||
{
|
{
|
||||||
Gtk::MessageDialog dialog( *this,
|
Gtk::MessageDialog dialog( *this,
|
||||||
String::ucompose( _("Could not mount %1 on %2"),
|
String::ucompose( _("Could not mount %1 on %2"),
|
||||||
|
@ -2375,11 +2327,11 @@ void Win_GParted::activate_attempt_rescue_data()
|
||||||
|
|
||||||
messageDialog.hide();
|
messageDialog.hide();
|
||||||
|
|
||||||
Glib::Thread::create( sigc::mem_fun( *this, &Win_GParted::thread_guess_partition_table ), false );
|
|
||||||
|
|
||||||
/*TO TRANSLATORS: looks like Searching for file systems on /deb/sdb */
|
/*TO TRANSLATORS: looks like Searching for file systems on /deb/sdb */
|
||||||
show_pulsebar(String::ucompose( _("Searching for file systems on %1"), devices[ current_device ] .get_path()));
|
show_pulsebar(String::ucompose( _("Searching for file systems on %1"), devices[ current_device ] .get_path()));
|
||||||
|
gpart_output="";
|
||||||
|
gparted_core.guess_partition_table(devices[ current_device ], gpart_output);
|
||||||
|
hide_pulsebar();
|
||||||
Dialog_Rescue_Data dialog;
|
Dialog_Rescue_Data dialog;
|
||||||
dialog .set_transient_for( *this );
|
dialog .set_transient_for( *this );
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,8 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
|
||||||
if ( mount_point .empty() )
|
if ( mount_point .empty() )
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "mount -v -t btrfs " + partition_new .get_path() + " " + mount_point, operationdetail ) ;
|
success &= ! execute_command( "mount -v -t btrfs " + partition_new .get_path() + " " + mount_point,
|
||||||
|
operationdetail, true ) ;
|
||||||
|
|
||||||
if ( success )
|
if ( success )
|
||||||
{
|
{
|
||||||
|
@ -210,7 +211,7 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
|
||||||
cmd = "btrfs filesystem resize " + size + " " + mount_point ;
|
cmd = "btrfs filesystem resize " + size + " " + mount_point ;
|
||||||
else
|
else
|
||||||
cmd = "btrfsctl -r " + size + " " + mount_point ;
|
cmd = "btrfsctl -r " + size + " " + mount_point ;
|
||||||
exit_status = execute_command_timed( cmd, operationdetail, false ) ;
|
exit_status = execute_command( cmd, operationdetail, false ) ;
|
||||||
bool resize_succeeded = ( exit_status == 0 ) ;
|
bool resize_succeeded = ( exit_status == 0 ) ;
|
||||||
if ( resize_to_same_size_fails )
|
if ( resize_to_same_size_fails )
|
||||||
{
|
{
|
||||||
|
@ -235,7 +236,7 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
|
||||||
operationdetail .get_last_child() .set_status( resize_succeeded ? STATUS_SUCCES : STATUS_ERROR ) ;
|
operationdetail .get_last_child() .set_status( resize_succeeded ? STATUS_SUCCES : STATUS_ERROR ) ;
|
||||||
success &= resize_succeeded ;
|
success &= resize_succeeded ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "umount -v " + mount_point, operationdetail ) ;
|
success &= ! execute_command( "umount -v " + mount_point, operationdetail, true ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rm_temp_dir( mount_point, operationdetail ) ;
|
rm_temp_dir( mount_point, operationdetail ) ;
|
||||||
|
|
12
src/jfs.cc
12
src/jfs.cc
|
@ -68,7 +68,7 @@ FS jfs::get_filesystem_support()
|
||||||
|
|
||||||
void jfs::set_used_sectors( Partition & partition )
|
void jfs::set_used_sectors( Partition & partition )
|
||||||
{
|
{
|
||||||
if ( ! Utils::execute_command( "echo dm | jfs_debugfs " + partition .get_path(), output, error, true ) )
|
if ( ! Utils::execute_command( "sh -c 'echo dm | jfs_debugfs " + partition.get_path() + "'", output, error, true ) )
|
||||||
{
|
{
|
||||||
//blocksize
|
//blocksize
|
||||||
index = output .find( "Block Size:" ) ;
|
index = output .find( "Block Size:" ) ;
|
||||||
|
@ -160,15 +160,15 @@ bool jfs::resize( const Partition & partition_new, OperationDetail & operationde
|
||||||
if ( mount_point .empty() )
|
if ( mount_point .empty() )
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "mount -v -t jfs " + partition_new .get_path() + " " + mount_point,
|
success &= ! execute_command( "mount -v -t jfs " + partition_new .get_path() + " " + mount_point,
|
||||||
operationdetail ) ;
|
operationdetail, true ) ;
|
||||||
|
|
||||||
if ( success )
|
if ( success )
|
||||||
{
|
{
|
||||||
success &= ! execute_command_timed( "mount -v -t jfs -o remount,resize " + partition_new .get_path() + " " + mount_point,
|
success &= ! execute_command( "mount -v -t jfs -o remount,resize " + partition_new .get_path() + " " + mount_point,
|
||||||
operationdetail ) ;
|
operationdetail, true ) ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "umount -v " + mount_point, operationdetail ) ;
|
success &= ! execute_command( "umount -v " + mount_point, operationdetail, true ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rm_temp_dir( mount_point, operationdetail ) ;
|
rm_temp_dir( mount_point, operationdetail ) ;
|
||||||
|
|
|
@ -162,7 +162,7 @@ bool lvm2_pv::remove( const Partition & partition, OperationDetail & operationde
|
||||||
cmd = "lvm pvremove " + partition .get_path() ;
|
cmd = "lvm pvremove " + partition .get_path() ;
|
||||||
else
|
else
|
||||||
//Must force the removal of a PV which is a member of a VG
|
//Must force the removal of a PV which is a member of a VG
|
||||||
cmd = "echo y | lvm pvremove --force --force " + partition .get_path() ;
|
cmd = "lvm pvremove --force --force --yes " + partition .get_path() ;
|
||||||
return ! execute_command( cmd, operationdetail ) ;
|
return ! execute_command( cmd, operationdetail ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,8 +163,8 @@ bool nilfs2::resize( const Partition & partition_new, OperationDetail & operatio
|
||||||
if ( mount_point .empty() )
|
if ( mount_point .empty() )
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "mount -v -t nilfs2 " + partition_new .get_path() + " " + mount_point,
|
success &= ! execute_command( "mount -v -t nilfs2 " + partition_new .get_path() + " " + mount_point,
|
||||||
operationdetail ) ;
|
operationdetail, true ) ;
|
||||||
|
|
||||||
if ( success )
|
if ( success )
|
||||||
{
|
{
|
||||||
|
@ -175,9 +175,9 @@ bool nilfs2::resize( const Partition & partition_new, OperationDetail & operatio
|
||||||
partition_new .get_sector_length(), partition_new .sector_size, UNIT_KIB ) ) ) + "K" ;
|
partition_new .get_sector_length(), partition_new .sector_size, UNIT_KIB ) ) ) + "K" ;
|
||||||
cmd += " " + size ;
|
cmd += " " + size ;
|
||||||
}
|
}
|
||||||
success &= ! execute_command_timed( cmd, operationdetail ) ;
|
success &= ! execute_command( cmd, operationdetail, true ) ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "umount -v " + mount_point, operationdetail ) ;
|
success &= ! execute_command( "umount -v " + mount_point, operationdetail, true ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rm_temp_dir( mount_point, operationdetail ) ;
|
rm_temp_dir( mount_point, operationdetail ) ;
|
||||||
|
|
|
@ -154,16 +154,15 @@ bool reiserfs::create( const Partition & new_partition, OperationDetail & operat
|
||||||
|
|
||||||
bool reiserfs::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
|
bool reiserfs::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
|
||||||
{
|
{
|
||||||
Glib::ustring str_temp = "echo y | resize_reiserfs " + partition_new .get_path() ;
|
Glib::ustring size = "" ;
|
||||||
|
|
||||||
if ( ! fill_partition )
|
if ( ! fill_partition )
|
||||||
{
|
{
|
||||||
str_temp += " -s " ;
|
size = " -s " + Utils::num_to_str( Utils::round( Utils::sector_to_unit(
|
||||||
str_temp += Utils::num_to_str( Utils::round( Utils::sector_to_unit(
|
|
||||||
partition_new .get_sector_length(), partition_new .sector_size, UNIT_BYTE ) ) -1 ) ;
|
partition_new .get_sector_length(), partition_new .sector_size, UNIT_BYTE ) ) -1 ) ;
|
||||||
}
|
}
|
||||||
|
Glib::ustring cmd = "sh -c 'echo y | resize_reiserfs" + size + " " + partition_new .get_path() + "'" ;
|
||||||
|
|
||||||
exit_status = execute_command( str_temp, operationdetail ) ;
|
exit_status = execute_command( cmd, operationdetail ) ;
|
||||||
|
|
||||||
return ( exit_status == 0 || exit_status == 256 ) ;
|
return ( exit_status == 0 || exit_status == 256 ) ;
|
||||||
}
|
}
|
||||||
|
|
28
src/xfs.cc
28
src/xfs.cc
|
@ -175,14 +175,14 @@ bool xfs::resize( const Partition & partition_new, OperationDetail & operationde
|
||||||
if ( mount_point .empty() )
|
if ( mount_point .empty() )
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "mount -v -t xfs " + partition_new .get_path() + " " + mount_point,
|
success &= ! execute_command( "mount -v -t xfs " + partition_new .get_path() + " " + mount_point,
|
||||||
operationdetail ) ;
|
operationdetail, true ) ;
|
||||||
|
|
||||||
if ( success )
|
if ( success )
|
||||||
{
|
{
|
||||||
success &= ! execute_command_timed( "xfs_growfs " + mount_point, operationdetail ) ;
|
success &= ! execute_command( "xfs_growfs " + mount_point, operationdetail, true ) ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "umount -v " + mount_point, operationdetail ) ;
|
success &= ! execute_command( "umount -v " + mount_point, operationdetail, true ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rm_temp_dir( mount_point, operationdetail ) ;
|
rm_temp_dir( mount_point, operationdetail ) ;
|
||||||
|
@ -204,7 +204,7 @@ bool xfs::copy( const Glib::ustring & src_part_path,
|
||||||
{
|
{
|
||||||
bool success = true ;
|
bool success = true ;
|
||||||
|
|
||||||
success &= ! execute_command_timed( "mkfs.xfs -f " + dest_part_path, operationdetail ) ;
|
success &= ! execute_command( "mkfs.xfs -f " + dest_part_path, operationdetail, true ) ;
|
||||||
if ( ! success )
|
if ( ! success )
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
|
@ -219,24 +219,24 @@ bool xfs::copy( const Glib::ustring & src_part_path,
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
success &= ! execute_command_timed( "mount -v -t xfs -o noatime,ro " + src_part_path +
|
success &= ! execute_command( "mount -v -t xfs -o noatime,ro " + src_part_path +
|
||||||
" " + src_mount_point, operationdetail ) ;
|
" " + src_mount_point, operationdetail, true ) ;
|
||||||
|
|
||||||
if ( success )
|
if ( success )
|
||||||
{
|
{
|
||||||
success &= ! execute_command_timed( "mount -v -t xfs " + dest_part_path +
|
success &= ! execute_command( "mount -v -t xfs " + dest_part_path +
|
||||||
" " + dest_mount_point, operationdetail ) ;
|
" " + dest_mount_point, operationdetail, true ) ;
|
||||||
|
|
||||||
if ( success )
|
if ( success )
|
||||||
{
|
{
|
||||||
success &= ! execute_command_timed( "xfsdump -J - " + src_mount_point +
|
success &= ! execute_command( "sh -c 'xfsdump -J - " + src_mount_point +
|
||||||
" | xfsrestore -J - " + dest_mount_point,
|
" | xfsrestore -J - " + dest_mount_point + "'",
|
||||||
operationdetail ) ;
|
operationdetail, true );
|
||||||
|
|
||||||
success &= ! execute_command_timed( "umount -v " + dest_part_path, operationdetail ) ;
|
success &= ! execute_command( "umount -v " + dest_part_path, operationdetail, true ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
success &= ! execute_command_timed( "umount -v " + src_part_path, operationdetail ) ;
|
success &= ! execute_command( "umount -v " + src_part_path, operationdetail, true ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
rm_temp_dir( dest_mount_point, operationdetail ) ;
|
rm_temp_dir( dest_mount_point, operationdetail ) ;
|
||||||
|
|
Loading…
Reference in New Issue