Implement new UUID operation on encrypted file systems (#774818)

When composing, describing and implementing the operation just need the
code to query and set the Partition object directly containing the file
system, instead of the enclosing encryption mapping to make it work.

The operation details for setting a new UUID on an encrypted ext4 file
system become:

    Set a new random UUID on [Encrypted] ext4 file system on /dev/sdb4
    + calibrate /dev/sdb4
    + Set UUID on /dev/mapper/sdb4_crypt to a new, random value
      + tune2fs -U random /dev/mapper/sdb4_crypt
          tune2fs 1.41.12 (17-May-2010)

Also note the now documented rule in apply_operation_to_disk() which
says each operation must leave the status of the encryption mapping and
file system as it found it.

Bug 774818 - Implement LUKS read-write actions NOT requiring a
             passphrase
This commit is contained in:
Mike Fleetwood 2016-09-06 16:03:05 +01:00 committed by Curtis Gedak
parent bd6fc67afb
commit 3ba7128d55
6 changed files with 44 additions and 17 deletions

View file

@ -134,6 +134,7 @@ public:
// Interface to return reference to the Partition object directly containing the
// file system. Will be overridden in derived PartitionLUKS.
virtual const Partition & get_filesystem_partition() const { return *this; };
virtual Partition & get_filesystem_partition() { return *this; };
virtual const Glib::ustring get_filesystem_string() const
{ return Utils::get_filesystem_string( filesystem ); };

View file

@ -53,6 +53,7 @@ public:
virtual void clear_messages();
virtual const Partition & get_filesystem_partition() const;
virtual Partition & get_filesystem_partition();
virtual const Glib::ustring get_filesystem_string() const;

View file

@ -571,6 +571,14 @@ bool GParted_Core::apply_operation_to_disk( Operation * operation )
// object(s), either partition_original, partition_new or partition_copy,
// as required. Calibrate also displays details of the partition being
// modified in the operation results to inform the user.
//
// Win_GParted::set_valid_operations() determines which operations are
// allowed on file systems depending on whether each is busy mounted or
// not. For encrypted file systems allowed operations also depends on
// whether the encryption mapping is open or not. Therefore each
// operation must leave the status of the file system and any encryption
// mapping in the same state which it found it, ready for the next
// operation.
case OPERATION_DELETE:
success = calibrate_partition( operation->get_partition_original(),
@ -662,7 +670,7 @@ bool GParted_Core::apply_operation_to_disk( Operation * operation )
case OPERATION_CHANGE_UUID:
success = calibrate_partition( operation->get_partition_new(), operation->operation_detail )
&& change_filesystem_uuid( operation->get_partition_new(),
&& change_filesystem_uuid( operation->get_partition_new().get_filesystem_partition(),
operation->operation_detail );
break;
}

View file

@ -50,18 +50,18 @@ void OperationChangeUUID::create_description()
{
g_assert( partition_new != NULL ); // Bug: Not initialised by constructor or reset later
if ( partition_new->uuid == UUID_RANDOM_NTFS_HALF )
if ( partition_new->get_filesystem_partition().uuid == UUID_RANDOM_NTFS_HALF )
{
/*TO TRANSLATORS: looks like Set half the UUID to a new random value on ntfs file system on /dev/sda1 */
description = String::ucompose( _("Set half the UUID to a new random value on %1 file system on %2"),
Utils::get_filesystem_string( partition_new->filesystem ),
partition_new->get_filesystem_string(),
partition_new->get_path() );
}
else
{
/*TO TRANSLATORS: looks like Set a new random UUID on ext4 file system on /dev/sda1 */
description = String::ucompose( _("Set a new random UUID on %1 file system on %2"),
Utils::get_filesystem_string( partition_new->filesystem ),
partition_new->get_filesystem_string(),
partition_new->get_path() );
}
}

View file

@ -200,6 +200,13 @@ const Partition & PartitionLUKS::get_filesystem_partition() const
return *this;
}
Partition & PartitionLUKS::get_filesystem_partition()
{
if ( busy )
return encrypted;
return *this;
}
const Glib::ustring PartitionLUKS::get_filesystem_string() const
{
/* TO TRANSLATORS: means that this is an encrypted file system */

View file

@ -1076,8 +1076,12 @@ void Win_GParted::set_valid_operations()
return ;
g_assert( valid_display_partition_ptr( selected_partition_ptr ) ); // Bug: Not pointing at a valid display partition object
// Reference to the Partition object directly containing the file system.
const Partition & selected_filesystem = selected_partition_ptr->get_filesystem_partition();
// Get filesystem capabilities
fs = gparted_core.get_fs( selected_partition_ptr->filesystem );
const FS & fs_cap = gparted_core.get_fs( selected_filesystem.filesystem );
//if there's something, there's some info ;)
allow_info( true ) ;
@ -1141,7 +1145,7 @@ void Win_GParted::set_valid_operations()
#endif
// Only unmount/swapoff/VG deactivate or online actions allowed if busy
if ( selected_partition_ptr->busy )
if ( selected_filesystem.busy )
return ;
// UNALLOCATED
@ -1238,7 +1242,7 @@ void Win_GParted::set_valid_operations()
allow_label_filesystem( true );
//only allow changing UUID of real partitions that support it
if ( selected_partition_ptr->status == STAT_REAL && fs.write_uuid )
if ( selected_partition_ptr->status == STAT_REAL && fs_cap.write_uuid )
allow_change_uuid( true ) ;
// Generate Mount on submenu, except for LVM2 PVs borrowing mount point to
@ -2738,7 +2742,8 @@ void Win_GParted::activate_change_uuid()
g_assert( selected_partition_ptr != NULL ); // Bug: Partition callback without a selected partition
g_assert( valid_display_partition_ptr( selected_partition_ptr ) ); // Bug: Not pointing at a valid display partition object
const FileSystem * filesystem_object = gparted_core.get_filesystem_object( selected_partition_ptr->filesystem );
const Partition & filesystem_ptn = selected_partition_ptr->get_filesystem_partition();
const FileSystem * filesystem_object = gparted_core.get_filesystem_object( filesystem_ptn.filesystem );
if ( filesystem_object->get_custom_text( CTEXT_CHANGE_UUID_WARNING ) != "" )
{
int i ;
@ -2760,21 +2765,26 @@ void Win_GParted::activate_change_uuid()
}
// Make a duplicate of the selected partition (used in UNDO)
Partition * part_temp = selected_partition_ptr->clone();
Partition * temp_ptn = selected_partition_ptr->clone();
if ( part_temp->filesystem == FS_NTFS )
//Explicitly ask for half, so that the user will be aware of it
//Also, keep this kind of policy out of the NTFS code.
part_temp->uuid = UUID_RANDOM_NTFS_HALF;
else
part_temp->uuid = UUID_RANDOM;
{
// Sub-block so that temp_filesystem_ptn reference goes out of scope
// before temp_ptn pointer is deallocated.
Partition & temp_filesystem_ptn = temp_ptn->get_filesystem_partition();
if ( temp_filesystem_ptn.filesystem == FS_NTFS )
// Explicitly ask for half, so that the user will be aware of it
// Also, keep this kind of policy out of the NTFS code.
temp_filesystem_ptn.uuid = UUID_RANDOM_NTFS_HALF;
else
temp_filesystem_ptn.uuid = UUID_RANDOM;
}
Operation * operation = new OperationChangeUUID( devices[current_device],
*selected_partition_ptr, *part_temp );
*selected_partition_ptr, *temp_ptn );
operation ->icon = render_icon( Gtk::Stock::EXECUTE, Gtk::ICON_SIZE_MENU );
delete part_temp;
part_temp = NULL;
delete temp_ptn;
temp_ptn = NULL;
Add_Operation( operation ) ;
// Try to merge this change UUID operation with all previous operations.