gparted/src/nilfs2.cc

220 lines
6.8 KiB
C++
Raw Normal View History

/* Copyright (C) 2011 Mike Fleetwood
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "nilfs2.h"
#include "FileSystem.h"
#include "Partition.h"
#include <glibmm/miscutils.h>
#include <glibmm/shell.h>
namespace GParted
{
FS nilfs2::get_filesystem_support()
{
FS fs( FS_NILFS2 );
fs .busy = FS::GPARTED ;
if ( ! Glib::find_program_in_path( "mkfs.nilfs2" ) .empty() )
{
fs.create = FS::EXTERNAL;
fs.create_with_label = FS::EXTERNAL;
}
if ( ! Glib::find_program_in_path( "nilfs-tune" ) .empty() )
{
fs.read = FS::EXTERNAL;
fs.read_label = FS::EXTERNAL;
fs.write_label = FS::EXTERNAL;
fs.read_uuid = FS::EXTERNAL;
fs.write_uuid = FS::EXTERNAL;
}
//Nilfs2 resizing is an online only operation and needs:
// mount, umount, nilfs-resize and linux >= 3.0 with nilfs2 support.
if ( ! Glib::find_program_in_path( "mount" ) .empty() &&
! Glib::find_program_in_path( "umount" ) .empty() &&
! Glib::find_program_in_path( "nilfs-resize" ) .empty() &&
Utils::kernel_supports_fs( "nilfs2" ) &&
Utils::kernel_version_at_least( 3, 0, 0 ) )
{
fs.grow = FS::EXTERNAL;
if ( fs .read ) //needed to determine a minimum file system size.
fs.shrink = FS::EXTERNAL;
}
fs.copy = FS::GPARTED;
fs.move = FS::GPARTED;
fs .online_read = FS::GPARTED ;
#ifdef ENABLE_ONLINE_RESIZE
if ( Utils::kernel_version_at_least( 3, 6, 0 ) )
{
fs .online_grow = fs .grow ;
fs .online_shrink = fs .shrink ;
}
#endif
//Minimum FS size is 128M+4K using mkfs.nilfs2 defaults
fs_limits.min_size = 128 * MEBIBYTE + 4 * KIBIBYTE;
return fs ;
}
void nilfs2::set_used_sectors( Partition & partition )
{
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
if ( ! Utils::execute_command( "nilfs-tune -l " + Glib::shell_quote( partition.get_path() ),
output, error, true ) )
{
//File system size in bytes
Glib::ustring::size_type index = output .find( "Device size:" ) ;
if ( index == Glib::ustring::npos
|| sscanf( output.substr( index ).c_str(), "Device size: %lld", &T ) != 1
)
T = -1 ;
//Free space in blocks
index = output .find( "Free blocks count:" ) ;
if ( index == Glib::ustring::npos
|| sscanf( output.substr( index ).c_str(), "Free blocks count: %lld", &N ) != 1
)
N = -1 ;
index = output .find( "Block size:" ) ;
if ( index == Glib::ustring::npos
|| sscanf( output.substr( index ).c_str(), "Block size: %lld", &S ) != 1
)
S = -1 ;
if ( T > -1 && N > -1 && S > -1 )
{
T = Utils::round( T / double(partition .sector_size) ) ;
N = Utils::round( N * ( S / double(partition .sector_size) ) ) ;
partition .set_sector_usage( T, N ) ;
partition.fs_block_size = S;
}
}
else
{
if ( ! output .empty() )
Display messages for encrypted file systems (#760080) At the moment any messages for an encrypted file system aren't shown, only messages from the outer PartitionLUKS object are shown. Also in Win_GParted::activate_paste() the selected Partition object, possibly a derived PartitionLUKS, is cloned and the messages cleared. Therefore a set of accessor methods must be provided to query and modify partition messages. Messages will be stored in the Partition object to which they are added and retrieved from all. So in the case of a derived PartitionLUKS they will be retrieved from the messages vector of the PartitionLUKS object itself and the messages vector for the encrypted file system it contains. To replace code like this in GParted_Core: partition_temp->messages = messages; We might naturally provide a set_messages() method which assigns the messages vector and is used like this: partition_temp->set_messages( messages ); However on a PartitionLUKS object what should set_messages() do? By the name it will replace any existing messages in the PartitionLUKS object itself, but what should happen to the messages for the contained encrypted Partition object? Should they be cleared or left alone? Rather than implement set_messages() with unclear semantics implement append_messages(), which in the PartitionLUKS object case will clearly leave any messages for the contained encrypted Partition object alone. Append_messages() is then used to add messages as the Partition or PartitionLUKS objects when populating the data in GParted_Core. Bug 760080 - Implement read-only LUKS support
2015-12-31 09:32:08 -07:00
partition.push_back_message( output );
if ( ! error .empty() )
Display messages for encrypted file systems (#760080) At the moment any messages for an encrypted file system aren't shown, only messages from the outer PartitionLUKS object are shown. Also in Win_GParted::activate_paste() the selected Partition object, possibly a derived PartitionLUKS, is cloned and the messages cleared. Therefore a set of accessor methods must be provided to query and modify partition messages. Messages will be stored in the Partition object to which they are added and retrieved from all. So in the case of a derived PartitionLUKS they will be retrieved from the messages vector of the PartitionLUKS object itself and the messages vector for the encrypted file system it contains. To replace code like this in GParted_Core: partition_temp->messages = messages; We might naturally provide a set_messages() method which assigns the messages vector and is used like this: partition_temp->set_messages( messages ); However on a PartitionLUKS object what should set_messages() do? By the name it will replace any existing messages in the PartitionLUKS object itself, but what should happen to the messages for the contained encrypted Partition object? Should they be cleared or left alone? Rather than implement set_messages() with unclear semantics implement append_messages(), which in the PartitionLUKS object case will clearly leave any messages for the contained encrypted Partition object alone. Append_messages() is then used to add messages as the Partition or PartitionLUKS objects when populating the data in GParted_Core. Bug 760080 - Implement read-only LUKS support
2015-12-31 09:32:08 -07:00
partition.push_back_message( error );
}
}
void nilfs2::read_label( Partition & partition )
{
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
if ( ! Utils::execute_command( "nilfs-tune -l " + Glib::shell_quote( partition.get_path() ),
output, error, true ) )
{
Glib::ustring label = Utils::regexp_label( output, "^Filesystem volume name:[\t ]*(.*)$" ) ;
if ( label != "(none)" )
partition.set_filesystem_label( label );
Make GParted recognise reading blank file system labels (#685656) GParted doesn't notice when a file system label is changed to blank. GParted first calls the file system specific read_label() method. When the label is blank read_label() correctly sets partition.label to the zero length string. Second GParted_Core::set_device_partitions() treats the zero length string to mean that the label is unset and calls FS_Info::get_label() to retrieve it from the cache of blkid output. Blkid also doesn't notice when the file system label has been changed to blank so reports the previous label. Hence GParted displays the previous file system label. Fix by making label a private member variable of the class Partition and providing access methods set_label(), get_label() and label_known() which track whether the label has been set or not. This only fixes the fault for file systems which use file system specific commands to read the label and when these tools are installed. Otherwise GParted uses, or has to fall back on using, the buggy blkid command to read the file system label. NOTE: Many of the file system specific read_label() methods use a tool which outputs more than just the label and use Utils::regexp_label() to match leading text and the label itself. If the surrounding text changes or disappears altogether to indicated a blank label, regexp_label() doesn't match anything and returns the zero length string. This is exactly what is required and is passed to set_label() to set the label to blank. Bug 685656 - GParted doesn't notice when file system label is changed to blank
2012-10-08 07:23:17 -06:00
else
partition.set_filesystem_label( "" );
}
else
{
if ( ! output .empty() )
Display messages for encrypted file systems (#760080) At the moment any messages for an encrypted file system aren't shown, only messages from the outer PartitionLUKS object are shown. Also in Win_GParted::activate_paste() the selected Partition object, possibly a derived PartitionLUKS, is cloned and the messages cleared. Therefore a set of accessor methods must be provided to query and modify partition messages. Messages will be stored in the Partition object to which they are added and retrieved from all. So in the case of a derived PartitionLUKS they will be retrieved from the messages vector of the PartitionLUKS object itself and the messages vector for the encrypted file system it contains. To replace code like this in GParted_Core: partition_temp->messages = messages; We might naturally provide a set_messages() method which assigns the messages vector and is used like this: partition_temp->set_messages( messages ); However on a PartitionLUKS object what should set_messages() do? By the name it will replace any existing messages in the PartitionLUKS object itself, but what should happen to the messages for the contained encrypted Partition object? Should they be cleared or left alone? Rather than implement set_messages() with unclear semantics implement append_messages(), which in the PartitionLUKS object case will clearly leave any messages for the contained encrypted Partition object alone. Append_messages() is then used to add messages as the Partition or PartitionLUKS objects when populating the data in GParted_Core. Bug 760080 - Implement read-only LUKS support
2015-12-31 09:32:08 -07:00
partition.push_back_message( output );
if ( ! error .empty() )
Display messages for encrypted file systems (#760080) At the moment any messages for an encrypted file system aren't shown, only messages from the outer PartitionLUKS object are shown. Also in Win_GParted::activate_paste() the selected Partition object, possibly a derived PartitionLUKS, is cloned and the messages cleared. Therefore a set of accessor methods must be provided to query and modify partition messages. Messages will be stored in the Partition object to which they are added and retrieved from all. So in the case of a derived PartitionLUKS they will be retrieved from the messages vector of the PartitionLUKS object itself and the messages vector for the encrypted file system it contains. To replace code like this in GParted_Core: partition_temp->messages = messages; We might naturally provide a set_messages() method which assigns the messages vector and is used like this: partition_temp->set_messages( messages ); However on a PartitionLUKS object what should set_messages() do? By the name it will replace any existing messages in the PartitionLUKS object itself, but what should happen to the messages for the contained encrypted Partition object? Should they be cleared or left alone? Rather than implement set_messages() with unclear semantics implement append_messages(), which in the PartitionLUKS object case will clearly leave any messages for the contained encrypted Partition object alone. Append_messages() is then used to add messages as the Partition or PartitionLUKS objects when populating the data in GParted_Core. Bug 760080 - Implement read-only LUKS support
2015-12-31 09:32:08 -07:00
partition.push_back_message( error );
}
}
bool nilfs2::write_label( const Partition & partition, OperationDetail & operationdetail )
{
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
return ! execute_command( "nilfs-tune -L " + Glib::shell_quote( partition.get_filesystem_label() ) +
" " + Glib::shell_quote( partition.get_path() ),
Time and check nearly all file system action commands (#754684) There has been an undocumented rule that external commands displayed in the operation details, as part of file system manipulations, only get a time and check mark displayed when multiple commands are needed, and not otherwise. (GParted checks whether all commands are successful or not regardless of whether a check mark is displayed in the operation details or not). EXCEPTION 1: btrfs resize Since the following commit [1] from 2013-02-22, GParted stopped displaying the timing for the btrfs resize command in the operation details. It being part of a multi-command sequence to perform the step. This is because FileSystem::execute_command() since the commit can only check the exit status for zero / non-zero while timing and checking the command status but btrfs resize needs to consider some non-zero statuses as successful. [1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe Reduce threading (#685740) EXCEPTION 2: ext2/3/4 move and copy using e2image When use of e2image was added [2] the single command steps were timed and check. [2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985 Use e2image to move/copy ext[234] file systems (#721516) EXCEPTION 3: fat16/32 write label and UUID Uses Utils::execute_command() rather than FileSystem::execute_command() so can be separately changed. See the following commit for resolution of the final commands not yet timed and check mark displayed. CHANGE: Lets make a simpler rule of always displaying the time and a check mark for all external commands displayed in the operation details. However this makes several of the other single command actions need special exit status handling because zero success, non-zero failure is not correct for every case. Specifically affects resizing of reiserfs and check repair of ext2/3/4, fat16/32, jfs and reiserfs. After this change all external commands run as file system actions must follow one of these two patterns of using the EXEC_CHECK_STATUS flag or separately calling FileSystem::set_status() to register success or failure of the command: exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...); or: exit_status = execute_command(cmd, od, ...); bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...); set_status(od, success ); Bug 754684 - Updates to FileSystem:: and Utils::execute_command() functions
2015-09-05 02:31:16 -06:00
operationdetail, EXEC_CHECK_STATUS );
}
void nilfs2::read_uuid( Partition & partition )
{
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
if ( ! Utils::execute_command( "nilfs-tune -l " + Glib::shell_quote( partition.get_path() ),
output, error, true ) )
{
partition .uuid = Utils::regexp_label( output, "^Filesystem UUID:[[:blank:]]*(" RFC4122_NONE_NIL_UUID_REGEXP ")" ) ;
}
else
{
if ( ! output .empty() )
Display messages for encrypted file systems (#760080) At the moment any messages for an encrypted file system aren't shown, only messages from the outer PartitionLUKS object are shown. Also in Win_GParted::activate_paste() the selected Partition object, possibly a derived PartitionLUKS, is cloned and the messages cleared. Therefore a set of accessor methods must be provided to query and modify partition messages. Messages will be stored in the Partition object to which they are added and retrieved from all. So in the case of a derived PartitionLUKS they will be retrieved from the messages vector of the PartitionLUKS object itself and the messages vector for the encrypted file system it contains. To replace code like this in GParted_Core: partition_temp->messages = messages; We might naturally provide a set_messages() method which assigns the messages vector and is used like this: partition_temp->set_messages( messages ); However on a PartitionLUKS object what should set_messages() do? By the name it will replace any existing messages in the PartitionLUKS object itself, but what should happen to the messages for the contained encrypted Partition object? Should they be cleared or left alone? Rather than implement set_messages() with unclear semantics implement append_messages(), which in the PartitionLUKS object case will clearly leave any messages for the contained encrypted Partition object alone. Append_messages() is then used to add messages as the Partition or PartitionLUKS objects when populating the data in GParted_Core. Bug 760080 - Implement read-only LUKS support
2015-12-31 09:32:08 -07:00
partition.push_back_message( output );
if ( ! error .empty() )
Display messages for encrypted file systems (#760080) At the moment any messages for an encrypted file system aren't shown, only messages from the outer PartitionLUKS object are shown. Also in Win_GParted::activate_paste() the selected Partition object, possibly a derived PartitionLUKS, is cloned and the messages cleared. Therefore a set of accessor methods must be provided to query and modify partition messages. Messages will be stored in the Partition object to which they are added and retrieved from all. So in the case of a derived PartitionLUKS they will be retrieved from the messages vector of the PartitionLUKS object itself and the messages vector for the encrypted file system it contains. To replace code like this in GParted_Core: partition_temp->messages = messages; We might naturally provide a set_messages() method which assigns the messages vector and is used like this: partition_temp->set_messages( messages ); However on a PartitionLUKS object what should set_messages() do? By the name it will replace any existing messages in the PartitionLUKS object itself, but what should happen to the messages for the contained encrypted Partition object? Should they be cleared or left alone? Rather than implement set_messages() with unclear semantics implement append_messages(), which in the PartitionLUKS object case will clearly leave any messages for the contained encrypted Partition object alone. Append_messages() is then used to add messages as the Partition or PartitionLUKS objects when populating the data in GParted_Core. Bug 760080 - Implement read-only LUKS support
2015-12-31 09:32:08 -07:00
partition.push_back_message( error );
}
}
bool nilfs2::write_uuid( const Partition & partition, OperationDetail & operationdetail )
{
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
return ! execute_command( "nilfs-tune -U " + Glib::shell_quote( Utils::generate_uuid() ) +
" " + Glib::shell_quote( partition .get_path() ),
Time and check nearly all file system action commands (#754684) There has been an undocumented rule that external commands displayed in the operation details, as part of file system manipulations, only get a time and check mark displayed when multiple commands are needed, and not otherwise. (GParted checks whether all commands are successful or not regardless of whether a check mark is displayed in the operation details or not). EXCEPTION 1: btrfs resize Since the following commit [1] from 2013-02-22, GParted stopped displaying the timing for the btrfs resize command in the operation details. It being part of a multi-command sequence to perform the step. This is because FileSystem::execute_command() since the commit can only check the exit status for zero / non-zero while timing and checking the command status but btrfs resize needs to consider some non-zero statuses as successful. [1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe Reduce threading (#685740) EXCEPTION 2: ext2/3/4 move and copy using e2image When use of e2image was added [2] the single command steps were timed and check. [2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985 Use e2image to move/copy ext[234] file systems (#721516) EXCEPTION 3: fat16/32 write label and UUID Uses Utils::execute_command() rather than FileSystem::execute_command() so can be separately changed. See the following commit for resolution of the final commands not yet timed and check mark displayed. CHANGE: Lets make a simpler rule of always displaying the time and a check mark for all external commands displayed in the operation details. However this makes several of the other single command actions need special exit status handling because zero success, non-zero failure is not correct for every case. Specifically affects resizing of reiserfs and check repair of ext2/3/4, fat16/32, jfs and reiserfs. After this change all external commands run as file system actions must follow one of these two patterns of using the EXEC_CHECK_STATUS flag or separately calling FileSystem::set_status() to register success or failure of the command: exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...); or: exit_status = execute_command(cmd, od, ...); bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...); set_status(od, success ); Bug 754684 - Updates to FileSystem:: and Utils::execute_command() functions
2015-09-05 02:31:16 -06:00
operationdetail, EXEC_CHECK_STATUS );
}
bool nilfs2::create( const Partition & new_partition, OperationDetail & operationdetail )
{
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
return ! execute_command( "mkfs.nilfs2 -L " + Glib::shell_quote( new_partition.get_filesystem_label() ) +
" " + Glib::shell_quote( new_partition.get_path() ),
Time and check nearly all file system action commands (#754684) There has been an undocumented rule that external commands displayed in the operation details, as part of file system manipulations, only get a time and check mark displayed when multiple commands are needed, and not otherwise. (GParted checks whether all commands are successful or not regardless of whether a check mark is displayed in the operation details or not). EXCEPTION 1: btrfs resize Since the following commit [1] from 2013-02-22, GParted stopped displaying the timing for the btrfs resize command in the operation details. It being part of a multi-command sequence to perform the step. This is because FileSystem::execute_command() since the commit can only check the exit status for zero / non-zero while timing and checking the command status but btrfs resize needs to consider some non-zero statuses as successful. [1] 52a2a9b00a32996921ace055e71d0e09fb33c5fe Reduce threading (#685740) EXCEPTION 2: ext2/3/4 move and copy using e2image When use of e2image was added [2] the single command steps were timed and check. [2] 86111fe12a26d23d9fc2a9e2d19281290ecaf985 Use e2image to move/copy ext[234] file systems (#721516) EXCEPTION 3: fat16/32 write label and UUID Uses Utils::execute_command() rather than FileSystem::execute_command() so can be separately changed. See the following commit for resolution of the final commands not yet timed and check mark displayed. CHANGE: Lets make a simpler rule of always displaying the time and a check mark for all external commands displayed in the operation details. However this makes several of the other single command actions need special exit status handling because zero success, non-zero failure is not correct for every case. Specifically affects resizing of reiserfs and check repair of ext2/3/4, fat16/32, jfs and reiserfs. After this change all external commands run as file system actions must follow one of these two patterns of using the EXEC_CHECK_STATUS flag or separately calling FileSystem::set_status() to register success or failure of the command: exit_status = execute_command(cmd, od, EXEC_CHECK_STATUS...); or: exit_status = execute_command(cmd, od, ...); bool success = (exit_status == 0 || exit_status == OTHER_SUCCESS_VALUE...); set_status(od, success ); Bug 754684 - Updates to FileSystem:: and Utils::execute_command() functions
2015-09-05 02:31:16 -06:00
operationdetail, EXEC_CHECK_STATUS );
}
bool nilfs2::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
{
bool success = true ;
Glib::ustring mount_point ;
if ( ! partition_new .busy )
{
mount_point = mk_temp_dir( "", operationdetail ) ;
if ( mount_point .empty() )
return false ;
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
success &= ! execute_command( "mount -v -t nilfs2 " + Glib::shell_quote( partition_new.get_path() ) +
" " + Glib::shell_quote( mount_point ),
operationdetail, EXEC_CHECK_STATUS );
}
if ( success )
{
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
Glib::ustring cmd = "nilfs-resize -v -y " + Glib::shell_quote( partition_new.get_path() );
if ( ! fill_partition )
{
Glib::ustring size = Utils::num_to_str( floor( Utils::sector_to_unit(
partition_new .get_sector_length(), partition_new .sector_size, UNIT_KIB ) ) ) + "K" ;
cmd += " " + size ;
}
success &= ! execute_command( cmd, operationdetail, EXEC_CHECK_STATUS );
if ( ! partition_new. busy )
Correctly quote and escape arguments passed to external commands (#787203) Trying to set a file system label to (including the double quotes): " --help " fails. For example labelling an ext4 file system would try to run this command: # e2label /dev/sdb1 "" --help "" Usage: e2label device [newlabel] # echo $? 1 Alternatively trying to create a file system with a label of just a double quote also fails. The Applying Pending Operations dialog waits forever and won't cancel or force cancel. Have to use the window manager close window button to close the dialog. Also GParted reports this error to the console: (gpartedbin:9648): glibmm-CRITICAL **: unhandled exception (type Glib::Error) in signal handler: domain: g-shell-error-quark code : 0 what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2') Command strings are parsed and split into argv array by function Glib::shell_parse_argv() which calls internal glib function tokenize_command_line() for shell tokenization. It expects the command string to be properly quoted and escaped and after tokenization, calls g_shell_unquote() on every parsed argument. So to prevent constructing incorrect commands, every non-static string needs to be properly quoted. GParted only puts labels and mount points into double quotes, but has not escaped special characters in those values itself. This patch fixes all these problems by using Glib::shell_quote() on all variable values. Labels, mount points, paths and all others too. Probably a better solution would be to use a new function which takes argv array instead of one string with all the, correctly quoted and escaped, arguments concatenated together. Bug 787203 - Correctly quote and escape arguments of external programs passed to execute_command()
2017-09-03 01:52:54 -06:00
success &= ! execute_command( "umount -v " + Glib::shell_quote( mount_point ),
operationdetail, EXEC_CHECK_STATUS );
}
if ( ! partition_new .busy )
rm_temp_dir( mount_point, operationdetail ) ;
return success ;
}
} //GParted