2009-11-05 11:08:32 -07:00
|
|
|
/* Copyright (C) 2004 Bart
|
2012-03-03 11:47:39 -07:00
|
|
|
* Copyright (C) 2008, 2009, 2010, 2011, 2012 Curtis Gedak
|
2004-11-17 06:00:25 -07:00
|
|
|
*
|
|
|
|
* 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
|
2014-01-23 03:59:48 -07:00
|
|
|
* GNU General Public License for more details.
|
2004-11-17 06:00:25 -07:00
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2014-01-23 03:59:48 -07:00
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
2004-11-17 06:00:25 -07:00
|
|
|
*/
|
2013-05-27 05:20:16 -06:00
|
|
|
|
|
|
|
#ifndef GPARTED_GPARTED_CORE_H
|
|
|
|
#define GPARTED_GPARTED_CORE_H
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2016-10-18 16:45:28 -06:00
|
|
|
#include "BlockSpecial.h"
|
2019-05-10 10:34:14 -06:00
|
|
|
#include "Device.h"
|
2016-10-18 16:45:28 -06:00
|
|
|
#include "FileSystem.h"
|
|
|
|
#include "Operation.h"
|
|
|
|
#include "Partition.h"
|
|
|
|
#include "PartitionLUKS.h"
|
|
|
|
#include "PartitionVector.h"
|
2019-07-16 06:01:07 -06:00
|
|
|
#include "SupportedFileSystems.h"
|
2018-01-15 14:25:55 -07:00
|
|
|
#include "Utils.h"
|
2004-11-17 06:00:25 -07:00
|
|
|
|
2006-01-19 12:15:15 -07:00
|
|
|
#include <parted/parted.h>
|
2004-11-17 06:00:25 -07:00
|
|
|
#include <vector>
|
|
|
|
#include <fstream>
|
2018-12-04 09:46:27 -07:00
|
|
|
#include <glibmm/thread.h>
|
2019-03-30 05:41:54 -06:00
|
|
|
#include <glibmm/ustring.h>
|
2018-12-04 09:46:27 -07:00
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
|
|
|
|
namespace GParted
|
|
|
|
{
|
|
|
|
|
|
|
|
class GParted_Core
|
|
|
|
{
|
2023-02-04 08:36:37 -07:00
|
|
|
friend class EraseFileSystemSignaturesTest; // To allow unit testing to call private
|
|
|
|
// method.
|
|
|
|
|
2004-11-17 06:00:25 -07:00
|
|
|
public:
|
2012-01-04 17:30:28 -07:00
|
|
|
static Glib::Thread *mainthread;
|
2006-02-25 09:30:43 -07:00
|
|
|
GParted_Core() ;
|
2006-03-28 12:01:20 -07:00
|
|
|
~GParted_Core() ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2019-03-30 05:41:54 -06:00
|
|
|
static Glib::ustring get_version_and_config_string();
|
Remember result of searching the PATH for the hdparm command (#751251)
Previously on every refresh for every device, GParted was searching the
PATH to discover if the hdparm command existed. Stracing GParted showed
that calling Glib::find_program_in_path("hdparm") made the following OS
calls:
access("/usr/lib64/qt-3.3/bin/hdparm", X_OK) = -1 ENOENT (No such file or directory)
access("/usr/local/sbin/hdparm", X_OK) = -1 ENOENT (No such file or directory)
access("/usr/local/bin/hdparm", X_OK) = -1 ENOENT (No such file or directory)
access("/sbin/hdparm", X_OK) = 0
getuid() = 0
stat("/sbin/hdparm", {st_mode=S_IFREG|0755, st_size=137, ...}) = 0
stat("/sbin/hdparm", {st_mode=S_IFREG|0755, st_size=137, ...}) = 0
The Linux VFS is very fast but repeatedly doing this is wasteful.
Remember the result of searching the PATH for the hdparm command at
startup and refresh this when the [Rescan For Supported Actions] button
is pressed in the File System Support dialog. This is the same as
GParted already does for file system specific commands and their
capabilities.
Bug 751251 - Show serial number in device information
2015-06-30 05:14:20 -06:00
|
|
|
static void find_supported_core();
|
2006-02-25 09:30:43 -07:00
|
|
|
void find_supported_filesystems() ;
|
2006-02-02 06:50:37 -07:00
|
|
|
void set_user_devices( const std::vector<Glib::ustring> & user_devices ) ;
|
2006-06-18 02:50:17 -06:00
|
|
|
void set_devices( std::vector<Device> & devices ) ;
|
2013-02-21 17:57:33 -07:00
|
|
|
void set_devices_thread( std::vector<Device> * pdevices );
|
2019-05-09 01:03:16 -06:00
|
|
|
|
2019-05-08 09:29:13 -06:00
|
|
|
bool valid_partition(const Device& device, Partition& partition, Glib::ustring& error);
|
2006-03-24 12:08:41 -07:00
|
|
|
bool apply_operation_to_disk( Operation * operation );
|
2015-02-14 13:49:45 -07:00
|
|
|
|
|
|
|
bool set_disklabel( const Device & device, const Glib::ustring & disklabel );
|
2015-02-21 09:43:42 -07:00
|
|
|
bool new_disklabel( const Glib::ustring & device_path, const Glib::ustring & disklabel,
|
|
|
|
bool recreate_dmraid_devs = true );
|
2006-06-17 14:52:25 -06:00
|
|
|
|
|
|
|
bool toggle_flag( const Partition & partition, const Glib::ustring & flag, bool state ) ;
|
2006-05-31 14:03:49 -06:00
|
|
|
|
|
|
|
const std::vector<FS> & get_filesystems() const ;
|
2019-07-16 06:01:07 -06:00
|
|
|
const FS& get_fs(FSType fstype) const;
|
2014-01-03 13:56:57 -07:00
|
|
|
static std::vector<Glib::ustring> get_disklabeltypes() ;
|
2006-05-31 14:03:49 -06:00
|
|
|
std::map<Glib::ustring, bool> get_available_flags( const Partition & partition ) ;
|
2008-10-30 12:50:38 -06:00
|
|
|
Glib::ustring get_thread_status_message() ;
|
|
|
|
|
2018-09-10 11:58:44 -06:00
|
|
|
static FileSystem * get_filesystem_object( FSType fstype );
|
2018-01-02 10:44:01 -07:00
|
|
|
static bool supported_filesystem( FSType fstype );
|
|
|
|
static FS_Limits get_filesystem_limits( FSType fstype, const Partition & partition );
|
2012-08-25 13:49:10 -06:00
|
|
|
static bool filesystem_resize_disallowed( const Partition & partition ) ;
|
2015-12-07 00:24:38 -07:00
|
|
|
static void insert_unallocated( const Glib::ustring & device_path,
|
|
|
|
PartitionVector & partitions,
|
|
|
|
Sector start,
|
|
|
|
Sector end,
|
|
|
|
Byte_Value sector_size,
|
|
|
|
bool inside_extended );
|
|
|
|
|
2006-05-31 14:03:49 -06:00
|
|
|
private:
|
2006-06-17 14:52:25 -06:00
|
|
|
//detectionstuff..
|
2008-10-30 12:50:38 -06:00
|
|
|
void set_thread_status_message( Glib::ustring msg ) ;
|
2021-04-10 07:19:32 -06:00
|
|
|
static Glib::ustring get_partition_path(const PedPartition *lp_partition);
|
2016-12-22 00:57:02 -07:00
|
|
|
void set_device_from_disk( Device & device, const Glib::ustring & device_path );
|
2015-06-22 07:08:02 -06:00
|
|
|
void set_device_serial_number( Device & device );
|
2012-10-30 03:30:49 -06:00
|
|
|
void set_device_partitions( Device & device, PedDevice* lp_device, PedDisk* lp_disk ) ;
|
2018-01-02 10:44:01 -07:00
|
|
|
void set_device_one_partition( Device & device, PedDevice * lp_device, FSType fstype,
|
Display whole disk file systems via partition table "none" (#741430)
For file systems which libparted recognises, when found on the whole
disk device, it reports with partition table "loop" and a partition
covering the whole disk. GParted duly displays this to the user.
For file systems which libparted doesn't recognise it reports
"unrecognised disk label". As of the latest libparted 3.2, these file
system aren't recognised and can't currently be shown when on the whole
disk device:
BitLocker, Crypt LUKS, exFAT, F2FS, LVM2 Physical Volume,
Linux Software RAID, ReFS, Reiser 4
So only when libparted doesn't recognise a file system on the whole disk
device and GParted does, either via blkid or it's internal code, display
this with partition table "none".
Bug 741430 - GParted cannot recognise LVM signature on unpartitioned
drive
2014-12-27 07:10:54 -07:00
|
|
|
std::vector<Glib::ustring> & messages );
|
2015-12-23 05:26:17 -07:00
|
|
|
void set_luks_partition( PartitionLUKS & partition );
|
2014-12-27 06:46:38 -07:00
|
|
|
void set_partition_label_and_uuid( Partition & partition );
|
2021-03-29 14:39:57 -06:00
|
|
|
static FSType detect_filesystem_in_encryption_mapping(const Glib::ustring& path,
|
|
|
|
std::vector<Glib::ustring>& messages);
|
2019-07-11 12:33:45 -06:00
|
|
|
static FSType detect_filesystem_internal(const Glib::ustring& path, Byte_Value sector_size);
|
2021-04-10 07:19:32 -06:00
|
|
|
static FSType detect_filesystem(const PedDevice *lp_device, const PedPartition *lp_partition,
|
|
|
|
std::vector<Glib::ustring> &messages);
|
2008-11-08 16:55:17 -07:00
|
|
|
void read_label( Partition & partition ) ;
|
2012-01-22 13:49:52 -07:00
|
|
|
void read_uuid( Partition & partition ) ;
|
2015-11-27 01:30:56 -07:00
|
|
|
void set_mountpoints( Partition & partition );
|
|
|
|
bool set_mountpoints_helper( Partition & partition, const Glib::ustring & path );
|
2022-01-07 01:53:52 -07:00
|
|
|
bool is_busy(const Glib::ustring& device_path, FSType fstype, const Glib::ustring& partition_path);
|
2015-11-27 06:55:20 -07:00
|
|
|
void set_used_sectors( Partition & partition, PedDisk* lp_disk );
|
2018-11-18 05:41:56 -07:00
|
|
|
void mounted_fs_set_used_sectors(Partition& partition);
|
2012-03-03 11:47:39 -07:00
|
|
|
#ifdef HAVE_LIBPARTED_FS_RESIZE
|
2012-10-30 03:30:49 -06:00
|
|
|
void LP_set_used_sectors( Partition & partition, PedDisk* lp_disk ) ;
|
2011-06-09 09:59:41 -06:00
|
|
|
#endif
|
2012-10-30 03:43:46 -06:00
|
|
|
void set_flags( Partition & partition, PedPartition* lp_partition ) ;
|
2008-10-30 12:50:38 -06:00
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
//operationstuff...
|
2015-01-18 08:46:10 -07:00
|
|
|
bool create( Partition & new_partition, OperationDetail & operationdetail );
|
2006-08-20 03:33:54 -06:00
|
|
|
bool create_partition( Partition & new_partition, OperationDetail & operationdetail, Sector min_size = 0 ) ;
|
|
|
|
bool create_filesystem( const Partition & partition, OperationDetail & operationdetail ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool format( const Partition & partition, OperationDetail & operationdetail ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2016-11-19 04:49:44 -07:00
|
|
|
bool delete_partition( const Partition & partition, OperationDetail & operationdetail );
|
2012-07-25 14:05:33 -06:00
|
|
|
|
|
|
|
bool remove_filesystem( const Partition & partition, OperationDetail & operationdetail ) ;
|
|
|
|
|
2014-12-18 15:18:33 -07:00
|
|
|
bool label_filesystem( const Partition & partition, OperationDetail & operationdetail );
|
|
|
|
|
2014-12-12 00:00:02 -07:00
|
|
|
bool name_partition( const Partition & partition, OperationDetail & operationdetail );
|
|
|
|
|
2016-11-19 04:49:44 -07:00
|
|
|
bool change_filesystem_uuid( const Partition & partition, OperationDetail & operation_detail );
|
2012-01-22 13:49:52 -07:00
|
|
|
|
2015-01-18 08:46:10 -07:00
|
|
|
bool resize_move( const Partition & partition_old,
|
|
|
|
Partition & partition_new,
|
|
|
|
OperationDetail & operationdetail );
|
|
|
|
bool move( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
|
|
|
OperationDetail & operationdetail );
|
2006-06-18 13:27:52 -06:00
|
|
|
bool move_filesystem( const Partition & partition_old,
|
2006-07-23 03:58:45 -06:00
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail ) ;
|
2012-03-03 11:47:39 -07:00
|
|
|
#ifdef HAVE_LIBPARTED_FS_RESIZE
|
2006-07-23 03:58:45 -06:00
|
|
|
bool resize_move_filesystem_using_libparted( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail ) ;
|
2015-07-14 13:40:56 -06:00
|
|
|
void thread_lp_ped_file_system_resize( PedFileSystem * fs,
|
|
|
|
PedGeometry * lp_geom,
|
|
|
|
bool * return_value );
|
2011-06-09 09:59:41 -06:00
|
|
|
#endif
|
2006-07-23 12:43:15 -06:00
|
|
|
bool resize( const Partition & partition_old,
|
2006-07-23 10:51:38 -06:00
|
|
|
const Partition & partition_new,
|
2006-08-20 03:33:54 -06:00
|
|
|
OperationDetail & operationdetail ) ;
|
2016-12-05 04:37:18 -07:00
|
|
|
bool resize_encryption( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
|
|
|
OperationDetail & operationdetail );
|
|
|
|
bool resize_plain( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
|
|
|
OperationDetail & operationdetail );
|
2006-06-18 13:38:29 -06:00
|
|
|
bool resize_move_partition( const Partition & partition_old,
|
2017-12-08 09:46:31 -07:00
|
|
|
const Partition & partition_new,
|
|
|
|
OperationDetail & operationdetail,
|
2017-12-18 09:39:37 -07:00
|
|
|
bool rollback_on_fail );
|
2017-12-08 09:32:30 -07:00
|
|
|
bool resize_move_partition_implement( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
|
|
|
Sector & new_start,
|
|
|
|
Sector & new_end );
|
2016-12-05 04:37:18 -07:00
|
|
|
bool shrink_encryption( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
|
|
|
OperationDetail & operationdetail );
|
|
|
|
bool maximize_encryption( const Partition & partition,
|
|
|
|
OperationDetail & operationdetail );
|
2016-10-26 14:24:28 -06:00
|
|
|
bool shrink_filesystem( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
|
|
|
OperationDetail & operationdetail );
|
2006-08-20 03:33:54 -06:00
|
|
|
bool maximize_filesystem( const Partition & partition, OperationDetail & operationdetail ) ;
|
2016-11-19 16:48:22 -07:00
|
|
|
bool recreate_linux_swap_filesystem( const Partition & partition,
|
|
|
|
OperationDetail & operationdetail );
|
2016-10-26 14:24:28 -06:00
|
|
|
bool resize_filesystem_implement( const Partition & partition_old,
|
|
|
|
const Partition & partition_new,
|
|
|
|
OperationDetail & operationdetail );
|
|
|
|
|
2006-06-17 14:52:25 -06:00
|
|
|
bool copy( const Partition & partition_src,
|
2016-11-04 09:07:29 -06:00
|
|
|
Partition & partition_dst,
|
|
|
|
OperationDetail & operationdetail );
|
|
|
|
bool copy_filesystem( const Partition & partition_src,
|
|
|
|
Partition & partition_dst,
|
|
|
|
OperationDetail & operationdetail );
|
2016-11-04 07:45:50 -06:00
|
|
|
bool copy_filesystem_internal( const Partition & partition_src,
|
|
|
|
const Partition & partition_dst,
|
|
|
|
OperationDetail & operationdetail,
|
|
|
|
bool cancel_safe );
|
|
|
|
bool copy_filesystem_internal( const Partition & partition_src,
|
|
|
|
const Partition & partition_dst,
|
|
|
|
OperationDetail & operationdetail,
|
|
|
|
Byte_Value & total_done,
|
|
|
|
bool cancel_safe );
|
|
|
|
bool copy_blocks( const Glib::ustring & src_device,
|
|
|
|
const Glib::ustring & dst_device,
|
|
|
|
Sector src_start,
|
|
|
|
Sector dst_start,
|
|
|
|
Byte_Value src_sector_size,
|
|
|
|
Byte_Value dst_sector_size,
|
|
|
|
Byte_Value src_length,
|
|
|
|
OperationDetail & operationdetail,
|
|
|
|
Byte_Value & total_done,
|
|
|
|
bool cancel_safe );
|
2017-11-30 01:34:30 -07:00
|
|
|
void rollback_move_filesystem( const Partition & partition_src,
|
|
|
|
const Partition & partition_dst,
|
|
|
|
OperationDetail & operationdetail,
|
|
|
|
Byte_Value total_done );
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool check_repair_filesystem( const Partition & partition, OperationDetail & operationdetail ) ;
|
2016-12-05 05:21:19 -07:00
|
|
|
bool check_repair_maximize( const Partition & partition,
|
|
|
|
OperationDetail & operationdetail );
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-08-20 03:33:54 -06:00
|
|
|
bool set_partition_type( const Partition & partition, OperationDetail & operationdetail ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
2006-09-03 08:24:05 -06:00
|
|
|
bool calibrate_partition( Partition & partition, OperationDetail & operationdetail ) ;
|
2006-07-23 03:58:45 -06:00
|
|
|
bool calculate_exact_geom( const Partition & partition_old,
|
|
|
|
Partition & partition_new,
|
2006-08-27 02:41:25 -06:00
|
|
|
OperationDetail & operationdetail ) ;
|
2017-12-28 05:08:25 -07:00
|
|
|
bool update_dmraid_entry( const Partition & partition_new, OperationDetail & operationdetail );
|
2012-12-01 05:49:29 -07:00
|
|
|
bool erase_filesystem_signatures( const Partition & partition, OperationDetail & operationdetail ) ;
|
2006-09-04 13:18:44 -06:00
|
|
|
bool update_bootsector( const Partition & partition, OperationDetail & operationdetail ) ;
|
2006-06-17 14:52:25 -06:00
|
|
|
|
|
|
|
//general..
|
2017-11-26 06:23:31 -07:00
|
|
|
void capture_libparted_messages( OperationDetail & operationdetail, bool success );
|
2017-11-25 06:56:56 -07:00
|
|
|
|
Only explicitly flush devices when using libparted < 3.2 (#259)
During device probing GParted always explicitly calls ped_device_sync()
to flush the caches for coherency between the whole disk device and the
partition devices [1]. As the GParted_Core::flush_device() comment
explains, since v3.1.61-gfb99ba5 [2], libparted flushes the devices
every time a device is opened [3], so also explicitly doing this in
GParted is unnecessary. Therefore stop explicitly flushing the devices
in GParted, except when using libparted 3.1 and older which doesn't do
it itself.
The ped_device_open() and ped_device_close() needed for the
ped_device_sync() is also a trigger of device changes and udev rule
execution performing LVM Volume Group activation, because libparted
opens the device read-write [4]. This is another reason to remove it
when possible. However even when eliminated it does not solve the issue
of LVM VG activation because other triggers remain. Do want this change
first though so that the sequence of libparted calls isn't changed
immediately after documenting them and fixing the issue and so that
there is no doubt that this change doesn't fix the issue.
Removing this extra device flush saves a little bit of time, depending
on the speed of the drive and number of partitions. Sample savings on
my desktop:
Drive type and partitions Saving (seconds)
----------------------------- ----------------
fast SSD with 3 partitions 0.05
slow SSD with 12 partitions 0.27
HDD with 1 partition 0.05
VHDD in VM with 1 partition 0.14
VHDD in VM with 10 partitions 0.58
Also the settle_device() call in flush_device() needs to be kept to wait
for device changes and udev rule execution whether it is GParted
explicitly flushing the device or just libparted automatically doing it
for cache coherency in ped_device_get(). This is because:
1. Libparted <= 3.2 opens the whole disk device read-write for
ped_device_get() [5]. (This was changed with parted
v3.2.26-g44d5ae0 [6] to open the whole disk device read-only).
2. Libparted up to and including the latest 3.6 release still opens all
partition devices read-write for ped_device_get() [7].
3. A whole disk device FAT32 file system looks enough like a partition
table that both the Linux kernel and libparted think it is
partitioned:
# mkfs.fat -F32 /dev/sdb
mkfs.fat 4.2 (2021-01-31)
# grep sdb /proc/partitions
8 16 8388608 sdb
8 17 8388607 sdb1
# parted /dev/sdb print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sdb: 8590MB
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk Flags:
Number Start End Size File system Flags
1 0s 16777215s 16777216s fat32
So the ped_device_get() call on a whole disk device FAT32 file system
still triggers device change and udev rule execution which needs to be
waited for, as this is exactly the case fixed previously by commit:
1382e0b828f630a705cecd97c346dfc6267909bf
Wait for udev change on /dev/DISK when querying whole device FS (!46)
[1] 3bea067596e3e2d6513cda2a66df1b3e4fa432fb
Flush devices when scanning to prevent reading stale signatures (#723842)
[2] Revert "linux-commit: do not unnecessarily open partition device nodes"
http://git.savannah.gnu.org/cgit/parted.git/commit/?id=fb99ba5ebd0dc34204fc9f1014131d5d494805bc
[3] parted libparted/arch/linux.c:_device_open()
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.6#n1752
1709 static int
1710 linux_open (PedDevice* dev)
1711 {
1712 return _device_open (dev, RW_MODE);
1713 }
1714
1715 static int
1716 _device_open (PedDevice* dev, int flags)
...
1752 _flush_cache (dev);
[4] parted libparted/device.c:ped_device_open() v3.6
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/device.c?h=v3.6#n226
parted libparted/arch/linux.c v3.6
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.6
ped_device_open(...)
ped_architecture->dev_ops->open(...) = linux_open(...)
_device_open(..., RW_MODE)
open(..., O_RDWR)
[5] parted libparted/device.c:ped_device_get() v3.2
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/device.c?h=v3.2#n149
parted libparted/arch/linux.c v3.2
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.2
ped_device_get(...)
ped_architecture->dev_ops->_new(...) = linux_new()
init_ide(...)
init_scsi(...)
init_generic(...)
ped_device_open(...)
ped_architecture->dev_ops->open(...) = linux_open(...)
open(..., O_RDWR)
[6] libparted: Use read only when probing devices on linux (#1245144)
http://git.savannah.gnu.org/cgit/parted.git/commit/?id=44d5ae0115c4ecfe3158748309e9912c5aede92d
[7] parted libparted/arch/linux.v v3.6
http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.6#n1660
1660 static void
1661 _flush_cache (PedDevice* dev)
...
1673 for (i = 1; i < lpn; i++) {
...
1680 if (!_partition_is_mounted_by_path(name)) {
1681 fd = open (name, WR_MODE, 0);
Closes #259 - Trying to deactivate LVM PV fails
2024-08-25 13:19:09 -06:00
|
|
|
#ifdef ENABLE_EXPLICIT_FLUSH_WORKAROUND
|
2015-04-25 06:37:59 -06:00
|
|
|
static bool flush_device( PedDevice * lp_device );
|
Only explicitly flush devices when using libparted < 3.2 (#259)
During device probing GParted always explicitly calls ped_device_sync()
to flush the caches for coherency between the whole disk device and the
partition devices [1]. As the GParted_Core::flush_device() comment
explains, since v3.1.61-gfb99ba5 [2], libparted flushes the devices
every time a device is opened [3], so also explicitly doing this in
GParted is unnecessary. Therefore stop explicitly flushing the devices
in GParted, except when using libparted 3.1 and older which doesn't do
it itself.
The ped_device_open() and ped_device_close() needed for the
ped_device_sync() is also a trigger of device changes and udev rule
execution performing LVM Volume Group activation, because libparted
opens the device read-write [4]. This is another reason to remove it
when possible. However even when eliminated it does not solve the issue
of LVM VG activation because other triggers remain. Do want this change
first though so that the sequence of libparted calls isn't changed
immediately after documenting them and fixing the issue and so that
there is no doubt that this change doesn't fix the issue.
Removing this extra device flush saves a little bit of time, depending
on the speed of the drive and number of partitions. Sample savings on
my desktop:
Drive type and partitions Saving (seconds)
----------------------------- ----------------
fast SSD with 3 partitions 0.05
slow SSD with 12 partitions 0.27
HDD with 1 partition 0.05
VHDD in VM with 1 partition 0.14
VHDD in VM with 10 partitions 0.58
Also the settle_device() call in flush_device() needs to be kept to wait
for device changes and udev rule execution whether it is GParted
explicitly flushing the device or just libparted automatically doing it
for cache coherency in ped_device_get(). This is because:
1. Libparted <= 3.2 opens the whole disk device read-write for
ped_device_get() [5]. (This was changed with parted
v3.2.26-g44d5ae0 [6] to open the whole disk device read-only).
2. Libparted up to and including the latest 3.6 release still opens all
partition devices read-write for ped_device_get() [7].
3. A whole disk device FAT32 file system looks enough like a partition
table that both the Linux kernel and libparted think it is
partitioned:
# mkfs.fat -F32 /dev/sdb
mkfs.fat 4.2 (2021-01-31)
# grep sdb /proc/partitions
8 16 8388608 sdb
8 17 8388607 sdb1
# parted /dev/sdb print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sdb: 8590MB
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk Flags:
Number Start End Size File system Flags
1 0s 16777215s 16777216s fat32
So the ped_device_get() call on a whole disk device FAT32 file system
still triggers device change and udev rule execution which needs to be
waited for, as this is exactly the case fixed previously by commit:
1382e0b828f630a705cecd97c346dfc6267909bf
Wait for udev change on /dev/DISK when querying whole device FS (!46)
[1] 3bea067596e3e2d6513cda2a66df1b3e4fa432fb
Flush devices when scanning to prevent reading stale signatures (#723842)
[2] Revert "linux-commit: do not unnecessarily open partition device nodes"
http://git.savannah.gnu.org/cgit/parted.git/commit/?id=fb99ba5ebd0dc34204fc9f1014131d5d494805bc
[3] parted libparted/arch/linux.c:_device_open()
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.6#n1752
1709 static int
1710 linux_open (PedDevice* dev)
1711 {
1712 return _device_open (dev, RW_MODE);
1713 }
1714
1715 static int
1716 _device_open (PedDevice* dev, int flags)
...
1752 _flush_cache (dev);
[4] parted libparted/device.c:ped_device_open() v3.6
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/device.c?h=v3.6#n226
parted libparted/arch/linux.c v3.6
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.6
ped_device_open(...)
ped_architecture->dev_ops->open(...) = linux_open(...)
_device_open(..., RW_MODE)
open(..., O_RDWR)
[5] parted libparted/device.c:ped_device_get() v3.2
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/device.c?h=v3.2#n149
parted libparted/arch/linux.c v3.2
https://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.2
ped_device_get(...)
ped_architecture->dev_ops->_new(...) = linux_new()
init_ide(...)
init_scsi(...)
init_generic(...)
ped_device_open(...)
ped_architecture->dev_ops->open(...) = linux_open(...)
open(..., O_RDWR)
[6] libparted: Use read only when probing devices on linux (#1245144)
http://git.savannah.gnu.org/cgit/parted.git/commit/?id=44d5ae0115c4ecfe3158748309e9912c5aede92d
[7] parted libparted/arch/linux.v v3.6
http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/arch/linux.c?h=v3.6#n1660
1660 static void
1661 _flush_cache (PedDevice* dev)
...
1673 for (i = 1; i < lpn; i++) {
...
1680 if (!_partition_is_mounted_by_path(name)) {
1681 fd = open (name, WR_MODE, 0);
Closes #259 - Trying to deactivate LVM PV fails
2024-08-25 13:19:09 -06:00
|
|
|
#endif
|
2015-04-25 06:37:59 -06:00
|
|
|
static bool get_device( const Glib::ustring & device_path, PedDevice *& lp_device, bool flush = false );
|
2021-04-10 09:39:22 -06:00
|
|
|
static bool get_disk(PedDevice *lp_device, PedDisk*& lp_disk);
|
|
|
|
static bool get_device_and_disk(const Glib::ustring& device_path,
|
|
|
|
PedDevice*& lp_device, PedDisk*& lp_disk, bool flush = false);
|
2015-04-25 06:37:59 -06:00
|
|
|
static void destroy_device_and_disk( PedDevice*& lp_device, PedDisk*& lp_disk );
|
|
|
|
static bool commit( PedDisk* lp_disk );
|
|
|
|
static bool commit_to_os( PedDisk* lp_disk, std::time_t timeout );
|
|
|
|
static void settle_device( std::time_t timeout );
|
2019-07-10 04:00:32 -06:00
|
|
|
static bool useable_device(const PedDevice* lp_device);
|
2017-09-26 01:06:29 -06:00
|
|
|
static PedPartition* get_lp_partition( const PedDisk* lp_disk, const Partition & partition );
|
2005-11-26 17:57:11 -07:00
|
|
|
|
2006-02-25 09:30:43 -07:00
|
|
|
static PedExceptionOption ped_exception_handler( PedException * e ) ;
|
|
|
|
|
2006-02-15 15:32:54 -07:00
|
|
|
std::vector<PedPartitionFlag> flags;
|
2006-02-02 06:50:37 -07:00
|
|
|
std::vector<Glib::ustring> device_paths ;
|
|
|
|
bool probe_devices ;
|
2008-10-30 12:50:38 -06:00
|
|
|
Glib::ustring thread_status_message; //Used to pass data to show_pulsebar method
|
2019-07-16 06:01:07 -06:00
|
|
|
static SupportedFileSystems* supported_filesystems;
|
2004-11-17 06:00:25 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
} //GParted
|
|
|
|
|
2013-05-27 05:20:16 -06:00
|
|
|
#endif /* GPARTED_GPARTED_CORE_H */
|