Commit Graph

525 Commits

Author SHA1 Message Date
Mike Fleetwood 71715a1c29 Add detection of ZFS (#752862)
Requires blkid from util-linux >= 2.15, released May 2009, for
detection of ZFS.

Bug 752862 - ZFS is not recognised
2015-08-08 09:55:42 -06:00
Curtis Gedak 1561d1ae7e Add libparted ped_file_system_resize thread to avoid blocking GUI (#737022)
Since GParted commit 52a2a9b "Reduce threading (#685740)", released in
GParted 0.15.0, application of operations occurs in the main thread
running the UI, therefore long running libparted actions such as
resizing a FAT16 or FAT32 file system hang the UI for as long as it take
to complete the operation.
https://git.gnome.org/browse/gparted/commit/?id=52a2a9b00a32996921ace055e71d0e09fb33c5fe

Though this problem exists for all libparted actions, it is particularly
noticeable when performing a large resize of fat16/fat32/hfs/hfs+ file
systems.

To address this significant cause of an unresponsive GUI, this
enhancement adds threading to the libparted ped_file_system_resize
function call.

Bug 737022 - UI hangs while running libparted operations such as
             FAT16/FAT32 resizing
2015-07-19 21:57:17 +01:00
Mike Fleetwood 54d0e3d056 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-07-01 10:22:57 -06:00
Mike Fleetwood 4b72ecd44e Display device serial numbers (#751251)
Run "hdparm -I /dev/DISK" to get the hard drive serial number of
every device which has one and display it in the Device Information.
The displayed value can either be the actual serial number, "none" or
blank.  "none" means the device doesn't have a hard drive serial number,
such as for Linux software RAID arrays, BIOS fake RAID arrays or USB
flash drives.  Blank means something went wrong getting the serial
number.  Either it couldn't be found in the hdparm output or the hdparm
command wasn't installed.

Example real hard drive:
    # hdparm -I /dev/sda
    ...
    ATA device, with non-removable media
            Model Number:       SAMSUNG HM500JI
            Serial Number:      S1WFJDSZ123732
    ...

Example Linux software RAID array:
    # hdparm -I /dev/md127

    /dev/md127:
     HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device

On my desktop with 4 internal hard drives 2 Linux software RAID arrays
on those hard drives, 2 USB flash drives and 1 USB hard drive attached,
running hdparm 9 times added 0.07 seconds to the device refresh time.

Bug 751251 - Show serial number in device information
2015-07-01 10:22:47 -06:00
Mike Fleetwood 8308ee6051 Support changing the UUID of a btrfs file system (#751337)
Btrfs-progs 4.1, released June 2015, includes support for changing the
UUID of a btrfs file system using the btrfstune command.  Check for
availability by looking for the -u option in the btrfstune help output.
Use btrfstune like this:

    # umount /dev/sdb1
    # btrfstune -f -u /dev/sdb1
    Current fsid: e7ad5dba-d721-4f99-990b-1ba2901c8ad2
    New fsid: 231563d9-e173-410d-b1da-d34c4319a423
    Set superblock flag CHANGING_FSID
    Change fsid in extents
    Change fsid on devices
    Clear superblock flag CHANGING_FSID
    Fsid change finished
    # echo $?
    0

Bug 751337 - btrfstune in btrfs-progs 4.1 supports changing the file
             system UUID
2015-06-28 10:57:58 -06:00
Mike Fleetwood 9be8d37600 Delay loading LVM2_PV_info cache until actually needed (#750582)
The lvm query commands were always run and the cache loaded even if
GParted, actually blkid, didn't identify any LVM2 PVs.  (GParted uses
libparted and blkid to identify partition content and the lvm commands
to provide the needed configuration details).

Now implement complete lazy initialization of the cache.  Never force
loading of the cache.  The cache is only loaded when the first value is
accessed from it.  When there are no LVM2 PVs, the cache is never
queried, so never loaded.  All the needed infrastructure for delayed
loading was previously added by this commit from 2011-12-11:
    ff8ad04120
    Lazy initialize the cache from querying LVM2 PVs (#160787)
Every public member function which access values from the cache already
calls initialize_if_required().  Just need to replace force loading of
the cache with a function which just clears the cache.

On my desktop, only when there are no LVM2 PVs, not loading the cache
and therefore not executing these external commands in
load_lvm2_pv_info_cache() saves 1.0 seconds of the 3.7 seconds it takes
to perform the a refresh in GParted:
    lvm vgscan
    lvm pvs ... -o pv_name,...
    lvm pvs ... -o vg_name,...

Bug 750582 - Refactor the LVM2_PV_Info module object interface and
             internal cache representation
2015-06-13 10:56:31 -06:00
Mike Fleetwood e6f7ea01f9 Parse LVM2_PV_Info cache into fields while loading (#750582)
GParted used to cache the results of the "lvm pvs" commands used to query
the state of the Logical Volume Manager as a series of lines of text.
Then every time a particular value was queried GParted would split all
the lines of text into fields until the required value was found.

Stop this repeat splitting of cached lines of text.  Instead parse the
lines of text into separate fields and store in structures of values of
the correct type in the cache.

Bug 750582 - Refactor the LVM2_PV_Info module object interface and
             internal cache representation
2015-06-13 10:56:15 -06:00
Mike Fleetwood 2c5e7b0d90 Stop needing any LVM2_PV_Info objects (#750582)
The LVM2_PV_Info cache had a pretend multi-object interface, yet all the
data is static.  An LVM2_PV_Info object doesn't contain any member
variables, yet was needed just to call the member functions.

Make all the member functions static removing the need to use any
LVM2_PV_Info objects.

Bug 750582 - Refactor the LVM2_PV_Info module object interface and
             internal cache representation
2015-06-13 10:56:12 -06:00
Mike Fleetwood 81f0b934bc Stop borrowing the constructor to load the LVM2_PV_Info cache (#750582)
An LVM2_PV_Info object contains no member variables as all the data is
static (exists once in the program and accessed by all objects).  The
constructor did nothing, except when passed true to load the cache.

Provide a separate load_cache() member function and remove the
constructors and destructor which do nothing.  The C++ compiler will
provide a default constructor and destructor, which don't do anything as
there are no member variables to initialise and finalise.

This makes the interface a little easier to understand.  Mostly a step
along the way of refactoring how the LVM2_PV_Info cache module works.

Bug 750582 - Refactor the LVM2_PV_Info module object interface and
             internal cache representation
2015-06-13 10:55:48 -06:00
Mike Fleetwood 7a4a375ed6 Remove Set_Data() from the copy, resize/move and new dialog class APIs
The copy, resize/move and new dialog classes (Dialog_Partition_Copy,
Dialog_Partition_Resize_Move and Dialog_Partition_New respectively) had
to be used like this:

    construct dialog object passing some parameters
    call Set_Data() to pass more parameters
    run() dialog
    call Get_New_Partition()

There is nothing in the classes which forces Set_Data() to be called,
but it must be called for the dialogs to work and prevent GParted from
crashing.

Make these class APIs safer by making it impossible to program
incorrectly in this regard.  Move all the additional parameters from
each Set_Data() method to each constructor.  The constructors just call
the now private set_data() methods.
2015-06-10 10:44:33 -06:00
Mike Fleetwood 32a5ace156 Rename Dialog_Base_Partition member to new_partition
The member variable was named selected_partition.  It is assigned from
Win_GParted::selected_partition_ptr (which is a pointer to a const
partition object so is never updated).  This gives connotations that it
won't be modified.

However it is updated freely as the new resultant partition object is
prepared before being returned from the dialog, most notable in the
Get_New_Partition() methods.

Therefore rename from selected_partition to new_partition.
2015-06-10 10:44:33 -06:00
Mike Fleetwood 8b96f8409f Stop copying selected_partition back on itself in the copy dialog (#750168)
The code goes like this:

    Dialog_Partition_Copy::Get_New_Partition()
        call Dialog_Base_Partition::Get_New_Partition()
            Update this->selected_partition with results from running
            the dialog.
            return this->selected_partition by value.
        Save value back to this->selected_partition.
        Update this->selected_partition some more.
        return this->selected_partition by value.

So there is an unnecessary copy of the partition object returned from
the base class Get_New_Partition() function back to the same variable in
the derived copy class Get_New_Partition() function.

Need to keep the base class Get_New_Partition() function as derived
class Dialog_Partition_Resize_Move uses that implementation as it
doesn't override it, and it's part of the interface.

Avoid this unnecessary copy by moving base class Get_New_Partition()
code into a new private function, called prepare_new_partition(), which
doesn't return anything.  Then have Get_New_Partition() in both classes
just return the required partition object.  Like this:

    Dialog_Base_Partition::Get_New_Partition()
        call prepare_new_partition()
        return this->selected_partition by value.

    Dialog_Partition_Copy::Get_New_Partition()
        call Dialog_Base_Partition::prepare_new_partition()
        Update this->selected_partition some more.
        return this->selected_partition by value.

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:44:33 -06:00
Mike Fleetwood 90e3ed68fc Shallow copy Device object into Operation object (#750168)
When Operation objects are created they take a copy of the Device object
to which the operation is to be applied.  The Device object includes a
vector of all the contained Partition objects currently on the device,
so these get copied too.

These additional deep copied Partition objects in the Operation object
are never accessed.  Therefore don't copy the contained Partition
objects when copying the Device object into the Operation object.

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:44:33 -06:00
Mike Fleetwood ece945685c Stop copying selected partition object in Manage Flags dialog (#750168)
When opening the Manage Flags dialog, creation of the dialog object was
creating a copy of the selected partition object.  If this was an
extended partition it also included recursively constructing the
contained logical partitions too.

Instead, replace the partition object in the DialogManageFlags class
with a reference to it.

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:44:33 -06:00
Mike Fleetwood efaea94301 Stop copying selected partition object in Information dialog (#750168)
When opening the Partition Information dialog, creation of the dialog
object was creating a copy of the partition object to be displayed.  If
this was an extended partition it also included recursively constructing
the contained logical partitions too.

Instead, replace the partition object in the Dialog_Partition_Info class
with a reference to it.

NOTE:
In C++ a reference is really just a pointer under the hood.  As such,
dereferences of a pointer to an object in the context of needing a
reference to the object doesn't copy the object.  It merely initialises
the reference from the pointer.

Specifically, with this prototype:
    Dialog_Partition_Info( const Partition & partition );
and the dialog object being constructed in Win_GParted::activate_info():
    Dialog_Partition_Info dialog( *selected_partition_ptr );
the partition object is not copy constructed.  A reference (pointer) to
it is merely passed to the dialog constructor.

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:43:43 -06:00
Mike Fleetwood 6ae327c8f9 Assert selected_partition_ptr is valid before use (#750168)
Further ensure that a bug doesn't get introduced with the use of
selected_partition_ptr, by asserting that it points to a current
partition object in the vector of display partitions.

After deliberately breaking the code so that selected_partition_ptr
points to some other partition object, trying to display the Information
dialog causes this crash:

======================
libparted : 2.4
======================
**
ERROR:Win_GParted.cc:989:void GParted::Win_GParted::set_valid_operations(): assertion failed: (valid_display_partition_ptr( selected_partition_ptr ))
Aborted (core dumped)

At this point in the code:

    973  void Win_GParted::set_valid_operations()
    974  {
    ...
    986          // No partition selected ...
    987          if ( ! selected_partition_ptr )
    988                  return ;
>>  989          g_assert( valid_display_partition_ptr( selected_partition_ptr ) );  // Bug: Not pointing at a valid display partition object

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:43:40 -06:00
Mike Fleetwood da39e3cad3 Change selected partition into a pointer (#750168)
Now that TreeView_Details and DrawingAreaVisualDisk classes store and
pass pointers to partition objects in the Gtk signal callbacks, change
the selected partition into a pointer too.

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:43:14 -06:00
Mike Fleetwood cc1448abd2 Store pointers to partition objects in DrawingAreaVisualDisk (#750168)
This stops copying of each displayed partition object into the
DrawingAreaVisualDisk class.

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:43:14 -06:00
Mike Fleetwood acd5d7e580 Store pointers to partition objects in TreeView_Details (#750168)
This stops copying of each displayed partition object into the
TreeView_Details class.

It also stops copy constructing lots of partition objects when just
clicking on a partition in the disk graphic.  The disk graphic needs to
inform the main GUI and then the partition list which partition has been
selected.  The call sequence goes like:

    DrawingAreaVisualDisk::on_button_press_event(event)
      Win_GParted::on_partition_selected(partition_ptr, src_is_treeview)
        TreeView_Detail::set_selected(partition_ptr)
          TreeView_Detail::set_selected(rows, partition_ptr,
                                        inside_extended)

Relevant source and highlighted comparison line:

   140  bool TreeView_Detail::set_selected( Gtk::TreeModel::Children rows,
   141                                      const Partition * partition_ptr, bool inside_extended )
   142  {
   143          for ( unsigned int t = 0 ; t < rows .size() ; t++ )
   144          {
>> 145                  if ( static_cast<Partition>( rows[t][treeview_detail_columns.partition] ) == *partition_ptr )
   146                  {
   147                          if ( inside_extended )
   148                                  expand_all() ;
   149
   150                          set_cursor( static_cast<Gtk::TreePath>( rows[ t ] ) ) ;
   151                          return true ;
   152                  }
   153
   154                  if ( set_selected( rows[t].children(), partition_ptr, true ) )
   155                          return true ;
   156          }
   157
   158          return false ;
   159  }

Then in this function the partition selected in the disk graphic
(partition_ptr parameter) is compared in turn with each partition object
stored in the Gtk::TreeView model to find the matching one to mark it as
selected.  This mere act of accessing the partition object stored in a
row of the Gtk::TreeView model causes it to be copy constructed.  So
clicking on the 5th partition in the disk graphic will copy construct
the first 5 partition objects just to do a compare to find the matching
one.

This is because it is not possible to get a reference from a
Gtk:TreeViewProxy in gtkmm.  Merely accessing a value in a Gtk::TreeView
model takes a copy of that value.

    Subject: get a reference from a Gtk::TreeValueProxy
    http://comments.gmane.org/gmane.comp.gnome.gtkmm/2217
    http://marc.info/?t=104400417500001&r=1&w=4

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:43:14 -06:00
Mike Fleetwood c430acf52a Pass by pointer in the signal_partition_selected callbacks (#750168)
Change from passing a reference to the selected partition, to passing a
pointer to the selected partition in the signal_partition_selected
callbacks between the disk graphic, partition list and core GUI modules.

This is an enabler for the following patches.

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:43:14 -06:00
Mike Fleetwood 545b75d957 Move vector of partition objects to a Win_GParted class member (#750168)
Win_GParted::Refresh_Visual() used a local variable containing a copy of
the vector of partitions in the current device to be displayed.  After
visually applying pending operations it loaded copies of each partition
object into the GUI widgets to display the disk graphic and partition
list, DrawingAreaVisualDisk and TreeView_Details classes respectively.
When a partition is selected in the UI, again a partition object is
copied.  Also several of the partition dialogs, including the
information dialog, take a copy of the partition object.  All these are
copies of the same set of partition objects, those currently being
displayed in the UI.

Move the vector of displayed partitions from a local variable in
Refresh_Visual() to a Win_GParted member variable.  This will allow for
the above cases to be changed to used pointers and references to the
same set of partition objects.

The valid lifetime of pointers to elements in this partition object
vector is from one refresh to the next, when the vector is cleared and
repopulated with a new set of partition objects.  This is exactly what
is needed as the GUI widgets are reloaded on each refresh, the selected
partition is reset and none of the partition dialog objects exist.
Dialog objects being created and destroyed on each use.

On the other hand some copies of partition objects currently being
displayed, still need to be made because they have lifetimes which need
to last longer than the next call to Refresh_Visual().  Specifically the
source of the copy partition and the partition objects copied into the
in the list of pending operations.

Bug 750168 - Reduce the amount of copying of partition objects
2015-06-10 10:42:36 -06:00
Mike Fleetwood 8bbb77f1f8 Remove cylinder size adjustments in the copy dialog (#749867)
BUF in the copy dialog class, Dialog_Partition_Copy, is use to adjust
limits in 2 cases:

1) Minimum size when copying an XFS file system

Minimum size was set to the used space + 2 * cylinder size (typically
plus ~16 MiB).  This commit from 2004-12-20 added it:
    a54b52ea33
    xfs copy now uses xfsdump and xfsrestore. icw some hacks in the other 2

Issues:
* This is increasing the minimum XFS file system size when copying it,
  which doesn't happen in the resize case for other file systems.
* It allows an XFS file system to be created which is smaller than the
  minimum size allowed by GParted.  Copying an empty XFS file system can
  create a new file system as small as 26 MiB.  This is smaller than the
  minimum GParted allows of 32 MiB because that is the minimum
  xfs_repair can handle.

Remove this addition when copying an XFS file system and enforce minimum
file system size.

2) Maximum size when copying a file system into empty space larger than
   it's maximum size

Maximum size was set to maximum file system size - cylinder size
(typically minus ~8 MiB).  Only applied to FAT16 which has a maximum
file system size set in and can be grown.  Added by this commit from
2004-12-15:
    10e8f3338d
    :get_fs now returns a const reference. in copy and resizedialog
    ...
    * in copy and resizedialog filesystems with MAX set now have a max size of MAX - one cylinder .

Issue:
* This is applying a lower maximum resize when copying the file system
  compared to that when creating the file system.
  NOTE:
  GParted currently allows all file systems to be resize to any size,
  regardless of the maximum file system size.  This is probably an
  oversight, but it does allow libparted to convert FAT16 to FAT32 file
  system when resizing.

Remove this lower maximum file system size when copying and resizing,
compared to creating.

Bug 749867 - Some limits are adjusted by arcane cylinder size amount
             when copying and resizing in a single operation
2015-05-28 12:53:41 -06:00
Mike Fleetwood b9262922a7 Remove last trace of cylinder size adjustments in the resize dialog (#749867)
This commit from 2010-05-20 removed use of cylinder size increase in the
minimum, and cylinder size decrease in the maximum file system sizes
from the resize/move dialog.
    e62a23b5b5
    Add partition alignment option to align to MiB (#617409)

This cylinder size limit adjustments were being performed using the
Dialog_Base_Partition::BUF member variable.  Now in the
Dialog_Partition_Resize_Move class it is never accessed, and only
unnecessarily set.  Move BUF from the common base class into the
Dialog_Partition_Copy class where it is still used.

Bug 749867 - Some limits are adjusted by arcane cylinder size amount
             when copying and resizing in a single operation
2015-05-28 12:44:51 -06:00
Mike Fleetwood f6e4390aaf Add const qualifier to get_custom_text() member functions
The function never modifies any member variables so make it a const
member function.

(FileSystem::get_custom_text() is a virtual function so can't be made
static).
2015-05-19 10:34:59 -06:00
Mike Fleetwood d0580d5955 Rename two GParted_Core methods to detect_filesystem*()
Rename a couple of GParted_Core methods for consistency and to better
distinguish get_filesystem() from get_filesystems() which do completely
unrelated things.

  get_filesystem()                 -> detect_filesystem()
  recognise_filesystem_signature() -> detect_filesystem_internal()

Also make detect_filesystem() a static member method as it doesn't use
any member variables.  Requirement cascades to get_partition_path().
2015-05-07 08:01:43 -06:00
Mike Fleetwood 42cd956a54 Make GParted_Core methods flush_device(), get_device(), etc static
GParted_Core methods:
    flush_device()
    get_device()
    get_disk()
    get_device_and_disk()
    destroy_device_and_disk()
    commit()
    commit_to_os()
    settle_device()

This group of methods only call libparted API functions and run external
executables.  None of them access any GParted_Core member variables.
Make them all static member functions.
2015-05-07 08:01:43 -06:00
Mike Fleetwood df000a94a6 Tidy-up GParted_Core::init/fini_filesystems() function declarations
These member functions are only used within the GParted_Core class and
only operate on the static member variable FILESYSTEM_MAP.

Make both functions private and also make init_filesystems() static.
2015-05-07 08:01:43 -06:00
Mike Fleetwood 40820bada7 Fix memory leak of FileSystem objects in init_filesystems() (#749036)
The FileSystem objects stored in the FILESYSTEM_MAP are allocated once
using new in init_filesystems() but never deleted.

Valgrind output fragment:

    # valgrind --leak-check=full ./gparted
    ==29314== 353 (72 direct, 281 indirect) bytes in 1 blocks are definitely lost in loss record 6,287 of 6,905
    ==29314==    at 0x4A075FC: operator new(unsigned long) (vg_replace_malloc.c:298)
>>  ==29314==    by 0x46EDA5: GParted::GParted_Core::init_filesystems() (GParted_Core.cc:106)
    ==29314==    by 0x46EC5F: GParted::GParted_Core::GParted_Core() (GParted_Core.cc:96)
    ==29314==    by 0x4A74F4: GParted::Win_GParted::Win_GParted(std::vector<Glib::ustring, std::allocator<Glib::ustring> > const&) (Win_GParted.cc:51)
    ==29314==    by 0x4D600A: main (main.cc:56)
    ...
    ==29314== 161 (72 direct, 89 indirect) bytes in 1 blocks are definitely lost in loss record 6,119 of 6,905
    ==29314==    at 0x4A075FC: operator new(unsigned long) (vg_replace_malloc.c:298)
>>  ==29314==    by 0x46F50C: GParted::GParted_Core::init_filesystems() (GParted_Core.cc:124)
    ==29314==    by 0x46EC5F: GParted::GParted_Core::GParted_Core() (GParted_Core.cc:96)
    ==29314==    by 0x4A74F4: GParted::Win_GParted::Win_GParted(std::vector<Glib::ustring, std::allocator<Glib::ustring> > const&) (Win_GParted.cc:51)
    ==29314==    by 0x4D600A: main (main.cc:56)

GParted_Core.cc source:

   102  void GParted_Core::init_filesystems()
   103  {
   104          FILESYSTEM_MAP[ FS_UNKNOWN ]         = NULL ;
   105          FILESYSTEM_MAP[ FS_CLEARED ]         = NULL ;
>> 106          FILESYSTEM_MAP[ FS_BTRFS ]           = new btrfs() ;
   ...
>> 124          FILESYSTEM_MAP[ FS_XFS ]             = new xfs() ;
   125          FILESYSTEM_MAP[ FS_BITLOCKER ]       = NULL ;

Fix by deleting all FILESYSTEM_MAP pointers.  Note that delete on a NULL
pointer is defined by C++ as a safe do nothing operation.

    C++ FAQ / Do I need to check for null before delete p?
    https://isocpp.org/wiki/faq/freestore-mgmt#delete-handles-null

Fixing this reduces the valgrind reported definitely lost memory blocks
count from 25 down to 6.  19 FileSystem objects deleted and 19 memory
blocks no longer lost.

Bug 749036 - FileSystem objects are memory leaked in init_filesystems()
2015-05-07 08:01:43 -06:00
Mike Fleetwood 5fd7c92671 Add partition name to Create New Partition dialog (#746214)
Add a partition name entry box to the Create New Partition dialog.  The
entry box is greyed out (not sensitive) for partition table types which
don't support partition naming.  Currently only supported for GPTs.  See
Utils::get_max_partition_name_length() for details.

There was a slightly wider gap between the file system combobox row and
the label entry row when there were only three widgets on the right hand
side of the dialog.  This has been removed now that there are four
widgets so that they are all evenly spaced and they line up with the
four widgets on the left hand side.

So far the partition name can be entered and previewed, but isn't yet
applied to the disk.

Bug 746214 - Partition naming enhancements
2015-03-25 10:02:43 -06:00
Mike Fleetwood 6a9a06af0e Pass Device object when setting up Dialog_Partition_New (#746214)
Adding a partition name entry to the Create New Partition dialog will
need access to these two Device methods: partition_naming_supported()
and get_max_partition_length().  The Set_Data() function already takes
two parameters, only_unformatted and disktype, taken from Device member
variables.

Rather than add two more parameters to the Set_Data() function pass the
Device object instead, replacing the current only_unformatted and
disktype parameters.

Bug 746214 - Partition name enhancements
2015-03-25 10:02:43 -06:00
Mike Fleetwood fc599270c2 Rename member object to filesystem_label_entry (#746214)
Rename Gtk::Entry object entry -> filesystem_label_entry in the
Dialog_Partition_New class.  This is in preparation for the introduction
of the partition name entry box in the Create New Partition dialog.

Bug 746214 - Partition name enhancements
2015-03-25 10:02:43 -06:00
Mike Fleetwood 9b2c95bcd1 Make support of naming for other partition table types possible (#746214)
Previously partition naming had only been implemented for gpt.  Make the
code ready to support naming of the other partition table types for
which libparted supports naming.  Specifically: amiga, dvh, mac and
pc98 in addition to gpt.  Document issues found with some of these
partition table types, which can relatively easily been worked around.

Leave support of naming for partition table types other than gpt
disabled, mostly just to reduce ongoing testing effort, at least until
there is any user demand for it.

Bug 746214 - Partition naming enhancements
2015-03-25 10:02:42 -06:00
Mike Fleetwood 4d83d3723d Remove unused device parameter from a few GParted_Core methods
resize_move() and move() stopped using the device parameter in this
commit from 2006-07-23:
    d663c3c277
    removed cylindersize buffering during resize from the filesystems. It is

create() stopped using the device parameter in this commit from 2006-03-19:
    ad9f2126e7
    fixed issues with copying (see also #335004) cleanups + added FIXME added

For reference most other operation methods had the device parameter
removed in this earlier commit from 2005-12-07:
    642f0a145b
    from now on each partition has a reference to it's device. make use of new
2015-03-09 11:04:13 -06:00
Mike Fleetwood 9c1a833a0d Fix failure to recognise whole disk file systems in certain cases (#743181)
When the following conditions were met GParted would fail to recognise a
newly created whole disk device file system, and instead show an unknown
file system filling the disk:

1) Disk was previously partitioned and contained at least one partition.

2) Using libparted version 2.0 to 3.0 inclusive.

Initial status:
    # blkid | fgrep sdc
    # fgrep sdc /proc/partitions
       8       32  976762584 sdc
       8       33  104857600 sdc1
    # parted /dev/sdc
    GNU Parted 2.4
    Using /dev/sdc
    Welcome to GNU Parted! Type 'help' to view a list of commands.
    (parted) print
    Model: ATA ST1000LM024 HN-M (scsi)
    Disk /dev/sdc: 1000GB
    Sector size (logical/physical): 512B/4096B
    Partition Table: msdos

    Number  Start   End    Size   Type     File system  Flags
     1      1049kB  107GB  107GB  primary

When creating the loop partition table libparted would not inform the
kernel to delete the old partitions.  /proc/partitions still contained
the details of the old partitions.
    (parted) mktable loop
    Warning: The existing disk label on /dev/sdc will be destroyed and
    all data on this disk will be lost. Do you want to continue?
    Yes/No? Yes
    (parted) print
    Model: ATA ST1000LM024 HN-M (scsi)
    Disk /dev/sdc: 1000GB
    Sector size (logical/physical): 512B/4096B
    Partition Table: loop

    Number  Start  End  Size  File system  Flags

    (parted) quit
    # fgrep sdc /proc/partitions
       8       32  976762584 sdc
       8       33  104857600 sdc1

Creation of the whole disk device file system goes unnoticed by blkid
because the kernel and therefore blkid's cache have stale partition
information.
    # mkfs.xfs -f /dev/sdc
    # blkid | fgrep sdc

NOTE:
On a Linux Software RAID array, as opposed to a hard disk, blkid does
notice creation of the whole disk device file system.  However the
kernel still has old partition details.

This was fixed in libparted 3.1 by commit:

    http://git.savannah.gnu.org/cgit/parted.git/commit/?id=f5c909c0cd50ed52a48dae6d35907dc08b137e88
    libparted: remove has_partitions check to allow loopback partitions

Fix by deleting old partitions before creating the loop table when
compiled with a broken version of libparted.  The GParted UI provides
no feedback while a new partition table is created, and with some
versions of GTK the UI become unresponsive too, so it is important to be
as fast as possible.  Evaluated three different methods, deleting 15 and
22 MSDOS partitions on a physical 5400 RPM hard drive using libparted
2.4:

M1) Delete and commit one partition at a time.
    Takes up to 24 seconds to delete 15 partitions.  With 22 partitions
    libparted always reports finding some of the partitions busy and
    unable to inform the kernel about the modifications.
    Too slow and doesn't work.

M2) Delete all partitions in one go and commit once.
    Takes up to 1.4 seconds to delete either 15 or 22 partitions.  Never
    removes partitions 17 and higher from the kernel.
    Doesn't work.

M3) Write GPT table (letting libparted delete any old partitions).
    Takes up to 0.8 seconds to delete either 15 or 22 partitions.
    Fast and works.

Use method 3 - write a GPT table thus using libparted code to inform the
kernel of the old partition deletions.

Bug 743181 - Add unpartitioned drive read-write support
2015-03-09 11:04:13 -06:00
Mike Fleetwood 4087cb2e2b Workaround older blkid not distinguishing between FAT16 and FAT32 (#743181)
Older versions of blkid don't correctly distinguish between FAT16 and
FAT32 file systems when overwriting one with the other.  This effects
GParted too with these file systems on whole disk devices where only
blkid is used to recognise the contents.  See previous fix for why only
blkid is used in this case:
    Avoid whole disk FAT being detected as MSDOS partition table
    (#743181)

Example:

    # blkid -v
    blkid from util-linux 2.20.1 (liblkid 2.20.0, 19-Oct-2011)
    # mkdosfs -F16 -I /dev/md1
    # blkid | fgrep md1
    /dev/md1: SEC_TYPE="msdos" UUID="7C23-95D9" TYPE="vfat"
    # mkdosfs -F32 -I /dev/md1
    # blkid | fgrep md1
    /dev/md1: SEC_TYPE="msdos" UUID="7F93-98F4" TYPE="vfat"

So blkid recognised the UUID changed but didn't remove the SEC_TYPE for
the FAT32 file system.  See FS_Info::get_fs_type() as it uses this to
distinguish between FAT16 and FAT32.  This is a caching update bug in
blkid, because telling blkid not to use the cache gets the right
results:

    # blkid -c /dev/null | fgrep md1
    /dev/md1: UUID="7F93-98F4" TYPE="vfat"

With testing determined that blkid from util-linux 2.23 and later are
not affected and earlier versions are affected.  Mostly recently known
affected distribution is Ubuntu 14.04 LTS with util-linux 2.20.1.

The straight forward fix would be to instruct blkid to not use its cache
with 'blkid -c /dev/null'.  But using blkid's cache is needed to prevent
blkid hanging for minutes when trying to access a non-existent floppy
drive when the BIOS is set incorrectly.  See commit:

    18f863151c
    Fix long scan problem when BIOS floppy setting incorrect

Instead, when using an older affected version of blkid and when blkid
cache reports a vfat file system, run blkid again bypassing the cache.
The device is known to exist and contain a vfat file system, just not
whether it is a FAT16 or FAT32 file system, so can't be a non-existent
floppy device and won't hang.

Bug 743181 - Add unpartitioned drive read-write support
2015-03-09 11:04:13 -06:00
Mike Fleetwood e7ed209020 Erase file system signatures before creating a partition table (#743181)
When writing "loop" partition table over the top of some whole disk
device file system types GParted continued to show those whole disk
device file systems rather than the virtual unknown partition from the
"loop" partition table.

This affected btrfs, jfs, reiser4 and reiserfs.  It occurred because of
several factors:
1) Libparted only zeroed the first and last 9.5 KiB (assuming 512 byte
   sectors) of the device before writing a new partition table.  See
   ped_disk_clobber().
2) These file systems have their super blocks and therefore signatures
   after the first 9.5 KiB.
3) Whole disk device file system detection is performed using blkid
   before checking for a libparted "loop" partition table.  See
   GParted_Core::set_devices_thread().

Ref:
libparted 3.2: disk.c:ped_disk_clobber()
http://git.savannah.gnu.org/cgit/parted.git/tree/libparted/disk.c?id=v3.2#n302

Fix by always erasing any possible file system signatures on the device
before creating a new "loop" partition table.

NOTE:
This is typically taking up to 0.5 seconds in my testing on a 5400 RPM
hard drive, during which time the GParted UI is hung and the create
partition table dialog shows the apply button pressed but no other
progress indication.

Bug 743181 - Add unpartitioned drive read-write support
2015-03-09 11:04:13 -06:00
Mike Fleetwood 51ac4d5648 Split get_device_and_disk() into two (#743181)
get_device_and_disk() basically calls libparted to get a PedDevice
object representing a disk device and a PedDisk object representing a
partition table.  Re-implement get_device_and_disk() using two separate
functions, get_device() and get_disk(), to get one of these objects
each.

No functionality changes with this commit.  It enables future commits to
incrementally add support for whole disk devices into GParted without
needing libparted to recognise the contents and create a virtual "loop"
partition table.

Bug 743181 - Add unpartitioned drive read-write support
2015-03-09 11:04:13 -06:00
Mike Fleetwood 5098744f9a Add whole_device flag to the partition object (#743181)
Need to be able to take different actions in the GParted_Core partition
manipulation methods and in Win_GParted UI methods to deal with
libparted supported partitions or whole disk devices without a partition
table.  Add boolean whole_device to the partition object and set
appropriately to allow for this.

Bug 743181 - Add unpartitioned drive read-write support
2015-03-09 11:04:13 -06:00
Mike Fleetwood 0bdc1fef14 Add lookup for Linux kernel names of mountable file systems (#742741)
Function Utils::get_filesystem_kernel_name() returns the name of the
file system as needed for use in the mount command:
    mount -t TYPE DEVICE DIR

Needed because the kernel / mount name is 'hfsplus' where as libparted /
GParted, as reported by Utils::get_filesystem_string(), calls it 'hfs+'.
So far just added debugging when mounting a file system to test the
function works.

    # ./gartedbin
    ======================
    libparted : 2.1
    ======================
    DEBUG: (hfsplus) # mount -v /dev/sdb5 "/mnt/5"
    DEBUG: (nilfs2) # mount -v /dev/sdb1 "/mnt/1"

Bug 742741 - Nilfs2 file system is unusable on RHEL/CentOS 6
2015-03-09 10:50:40 -06:00
Mike Fleetwood cbf8bd741d 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
2015-03-09 10:17:22 -06:00
Mike Fleetwood ed827cf59a Create helper function set_partition_label_and_uuid() (#741430)
Move code which queries the file system label and UUID of a partition
into a separate helper function.

Bug 741430 - GParted cannot recognise LVM signature on unpartitioned
             drive
2015-03-09 10:17:22 -06:00
Mike Fleetwood cb645b16cf Refactor GParted internal file system signature detection (#741430)
Refactor GParted internal file system signature detection to remove code
duplication.  There were 5 separate copies of code to: allocate a
buffer, open, read and close the device, free the buffer and compare the
signature.

Bug 741430 - GParted cannot recognise LVM signature on unpartitioned
             drive
2015-03-09 10:17:22 -06:00
Michael Zimmermann 1f5841b4ad Add support for GPT partition names (#741424)
Embedded devices (Android) use GPT partition names to identify
partitions, instead of file system labels.  Add support for viewing and
changing them.

As partition names are used to provide unique identification they are
never copied when copying the contents of one partition to another.

Note that GNU/Linux uses file system labels, UUIDs or device names for
identification during the boot process and afterwards so while partition
names can be used, they are optional and purely for user information.

Bug 741424 - Add support for GPT partition names
2015-02-01 10:08:23 -07:00
Mike Fleetwood e1dc89cd11 Rename class to Dialog_FileSystem_Label (#741424)
class Dialog_Partition_Label   -> Dialog_FileSystem_Label
file Dialog_Partition_Label.h  -> Dialog_FileSystem_Label.h
file Dialog_Partition_Label.cc -> Dialog_FileSystem_Label.cc

Bug 741424 - Add support for GPT partition names
2015-02-01 10:08:23 -07:00
Mike Fleetwood 04450c577c Rename class to OperationLabelFileSystem (#741424)
class OperationLabelPartition   -> OperationLabelFileSystem
file OperationLabelPartition.h  -> OperationLabelFileSystem.h
file OperationLabelPartition.cc -> OperationLabelFileSystem.cc

Bug 741424 - Add support for GPT partition names
2015-02-01 10:08:23 -07:00
Mike Fleetwood 3630b9c83b Rename methods in GParted_Core and Win_GParted classes (#741424)
class GParted_Core:
    label_partition() -> label_filesystem()

class Win_GParted:
    allow_label_partition()    -> allow_label_filesystem()
    activate_label_partition() -> activate_label_filesystem()

Bug 741424 - Add support for GPT partition names
2015-02-01 10:08:23 -07:00
Mike Fleetwood 63aeb150ac Rename member variables and methods in Partition class (#741424)
class Partition:
    have_label    -> have_filesystem_label
    label         -> filesystem_label
    label_known() -> filesystem_label_known()
    get_label()   -> get_filesystem_label()
    set_label()   -> set_filesystem_label()

Bug 741424 - Add support for GPT partition names
2015-02-01 10:08:23 -07:00
Mike Fleetwood d480800600 Rename enum to OPERATION_LABEL_FILESYSTEM (#741424)
This and the following few commits rename variables, methods, classes,
etc from *label_partition* to *label_filesystem* so that the code also
reflects that it is the label of the file system that is being modified
and to separate it from the name partition operation about to be added.

enum OPERATION_LABEL_PARTITION -> OPERATION_LABEL_FILESYSTEM

Bug 741424 - Add support for GPT partition names
2015-02-01 10:08:23 -07:00
Mike Fleetwood 3373ef07fa Recognise ReFS file system (#738471)
Only recognises ReFS file system.  No other actions are supported.
Requires blkid from util-linux >= 2.24.

Bug #738471 - ReFS file system is not recognised
2014-10-30 09:55:01 -06:00
Mike Fleetwood 8b4b73a8f3 Add supported_filesystem() predicate method (#738471)
Helper to check whether a recognised file system type is supported by
GParted or not.  Supported means there is an implementation class and
will appear in the File System Support dialog.

Make supported_filesystem() a static member function so that it can be
called without a class object so that GParted_Core::GParted_Core()
initialiser isn't called multiple times.  This requires FILESYSTEM_MAP
to become a static member variable too.

Bug #738471 - ReFS file system is not recognised
2014-10-30 09:55:01 -06:00
Mike Fleetwood 58618572b5 Comment and re-order FILESYSTEM enumeration type 2014-10-30 09:55:01 -06:00
Mike Fleetwood e3a1b93a6d Pass by value to get_filesystem_object()
get_filesystem_object() takes a constant reference to a FILESYSTEM, but
FILESYSTEM is just an enumeration.  So that's a pointer to a constant
int.  Just pass by value instead.
2014-10-30 09:55:01 -06:00
Mike Fleetwood f672f68863 Check for e4fsprogs commands for ext4 support on RHEL/CentOS 5.x (#738706)
RHEL / CentOS 5.6 and later officially support ext4 file system [1].
From RHEL / CentOS 5.3 ext4 file system was included as a technology
preview.  Ext4 file system tools are in a separate package e4fsprogs,
using uniquely named commands.  The standard e2fsprogs commands only
support ext2 and ext3 file systems.

    # mkfs.ext4 /dev/sdb3
    # tune2fs -l /dev/sdb3
    tune2fs 1.39 (29-May-2006)
    tune2fs: Filesystem has unsupported feature(s) while trying to open /dev/sdb3
    Couldn't find valid filesystem superblock.
    # echo $?
    1
    # tune4fs -l /dev/sdb3
    tune4fs 1.41.12 (17-May-2010)
    Filesystem volume name:   <none>
    Last mounted on:          <not available>
    Filesystem UUID:          ba4a9d58-7728-4b47-8a90-80e772615637
    Filesystem magic number:  0xEF53
    Filesystem revision #:    1 (dynamic)
    Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
    ...

For ext4 only, search for the e4fsprogs specific commands first and the
standard e2fsprogs commands second.

[1] RHEL 5.6 Release Notes, 5. Filesystems and Storage
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/5/html/5.6_Release_Notes/ar01s05.html

Bug #738706 - GParted doesn't support ext4 on RHEL/CentOS 5.x
2014-10-27 09:32:36 -06:00
Mike Fleetwood 52ee26f971 Prevent flashing redraw of the devices combobox (#696149)
The device combobox was getting drawn blank, then getting drawn again
with the selected device.  This was happening because at the start of
Win_GParted::refresh_combo_devices() the GTK model behind the combobox,
liststore_devices, was cleared, changing the active item, causing the
combobox to get redrawn empty.  After the GTK model had been repopulated
the active item was reset causing the comboxbox to get redrawn again,
now showing the selected device.  Call flow:

    Win_GParted::refresh_combo_devices()
        liststore_devices->clear()
            //Gtk::Combobox emits signal_change.  Registered callbacks
            //called.
                Win_GParted::combo_devices_changed()
                    Win_GParted::Refresh_Visual()
                        ...
        ...
        combo_devices.set_active(current_device);
            //Gtk::Combobox emits signal_change.  Registered callbacks
            //called.
                Win_GParted::combo_devices_changed()
                    Win_GParted::Refresh_Visual()
                        ...

This has always been the case, since the device combobox was first added
to GParted before version 0.1 by commit:

    3a4b43e0ad
    replaced deprecated OptionMenu with ComboBox ...

Fix by temporarily blocking the devices comboxbox from emitting
signal_changed while the GTK model behind the combobox is recreated.

However, since automatic selection of the largest free space was added
[1] in GParted 0.15.0, a more noticeable flashing redraw issue was
caused in which the partition graphic and partition list were both drawn
blank then redrawn fully populated.  Some distributions were not
affected by this at all, some only experienced a single flash and others
suffered from two or more flashing redraws.  Some affected
distributions: CentOS 5.10, 6.5, 7.0, Debian 6, Fedora 14, 19, 20,
Ubuntu 13.10, Xubuntu 14.04 LTS.  Did not occur on Kubuntu 12.04 LTS.

[1] 5b53c12f6e
    Select largest unallocated partition by default (#667365)

Bug #696149 - Double refresh of display introduced with default
              unallocated space
2014-10-07 10:38:27 -06:00
Mike Fleetwood c1db9811e1 Use Autoconf check specifically for libparted-fs-resize (#734718)
Remove HAVE_LIBPARTED_3_1_0_PLUS definition and replace Autoconf
    check for libparted >= 3.1

Currently uses custom check which compiles an executable to check for
libparted version >= 3.1 to determine the availability of the library
parted-fs-resize and the need to include the header <parted/filesys.h>.

Change to use a direct Autoconf check to determine the availability of
the ped_file_system_resize() function in the parted-fs-resize library.
Remove inclusion of the header <parted/filesys.h> as it has always been
included via <parted/parted.h>, at least as far back as parted 1.8.0,
and even in parted 3.0 when ped_file_system_resize() and libparted file
system resize capability didn't exist.

Bug #734718 - Update Autoconf version specific libparted checks and
              defines to feature specific ones
2014-08-18 15:48:34 -06:00
Mike Fleetwood 3bea067596 Flush devices when scanning to prevent reading stale signatures (#723842)
While one partition is busy, reformat another partition from the command
line.  Afterwards parted/libparted still detects the original file
system and GParted shows errors from the file system specific tools
reporting the new file system doesn't exist.  Only limitation is that
the new new file system must be recognised by libparted (or by GParted's
fallback file system signature detection).

Case #1, File system reformatting:

    # parted /dev/sdb print
    Model: ATA SAMSUNG SSD UM41 (scsi)
    Disk /dev/sdb: 8012MB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos

    Number  Start   End     Size    Type     File system  Flags
     1      1049kB  2149MB  2147MB  primary  ext2
     2      2149MB  4296MB  2147MB  primary  ext2
    # mount | fgrep sdb
    /dev/sdb1 on /mnt/1 type ext2 (rw)

    # mkfs.xfs -f /dev/sdb2
    # blkid /dev/sdb2
    /dev/sdb2: UUID="c31823a2-b81b-46fa-8246-0a59695e4834" TYPE="xfs"
    # parted /dev/sdb print
    Model: ATA SAMSUNG SSD UM41 (scsi)
    Disk /dev/sdb: 8012MB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos

    Number  Start   End     Size    Type     File system  Flags
     1      1049kB  2149MB  2147MB  primary  ext2
     2      2149MB  4296MB  2147MB  primary  ext2
    # e2label /dev/sdb2
    e2label: Bad magic number in super-block while trying to open /dev/sdb2
    Couldn't find valid filesystem superblock.
    # dumpe2fs /dev/sdb2
    dumpe2fs 1.41.12 (17-May-2010)
    dumpe2fs: Bad magic number in super-block while trying to open /dev/sdb2
    Couldn't find valid filesystem superblock.

Case #2, Removing device from multi-device btrfs:

    # btrfs filesystem show /dev/sdb1
    Label: none  uuid: a05db434-efd5-4e8c-902f-05f89a88b610
            Total devices 2 FS bytes used 156.00KB
            devid    2 size 2.00GB used 512.00MB path /dev/sdb2
            devid    1 size 2.00GB used 240.75MB path /dev/sdb1

    # mount /dev/sdb1 /mnt/1
    # btrfs device delete /dev/sdb2
    # btrfs filesystem show /dev/sdb1
    Label: none  uuid: a05db434-efd5-4e8c-902f-05f89a88b610
            Total devices 1 FS bytes used 92.00KB
            devid    1 size 2.00GB used 714.25MB path /dev/sdb1
    # btrfs filesystem show /dev/sdb2

and GParted reports this error for partition /dev/sdb2:
    Unable to read the contents of this file system!
    Because of this some operations may be unavailable.
    The cause might be a missing software package.
    The following list of software packages is required for btrfs
    file system support:  btrfs-tools.

This is another case of libparted reading from the whole disk device
(/dev/sdb) yet the file system tools use the partition specific block
device (/dev/sdb2), and the Linux buffer cache not providing cache
coherency.  Previous scenario was fixed with:

    797f0b8eeb
    Flush device after wiping a file system (#688882)

This affects libparted 2.0 to 3.1 inclusive and is fixed by:

    http://git.savannah.gnu.org/cgit/parted.git/commit/?id=fb99ba5ebd0dc34204fc9f1014131d5d494805bc
    Revert "linux-commit: do not unnecessarily open partition device nodes"

Fix by calling ped_device_sync() to guarantee cache coherency for each
device during scanning.

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood 20f52e2866 Display btrfs members in the Partition Information dialog (#723842)
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood 4b63e46a4e Fallback to reading mount command output instead of /etc/mtab (#723842)
With linux 3.5 and later, the device used to mount a btrfs file system
is updated in /proc/mounts when the previous mounting device is removed
from the file system.  Most recent distributions make /etc/mtab a
symbolic link to /proc/mounts.  However some still have /etc/mtab as a
plain file only updated by mount and umount, thus showing the old device
name which is no longer part of the file system.

On Ubuntu 13.10, which has /etc/mtab as a plain file managed by mount
and umount:

    # mkfs.btrfs /dev/sdb1
    # mount /dev/sdb1 /mnt/1
    # btrfs device add /dev/sdb2 /mnt/1
    # btrfs device delete /dev/sdb1 /mnt/1
    # sync
    # btrfs filesystem show /dev/sdb1
    # btrfs filesystem show /dev/sdb2
    Label: none  uuid: e47775a6-e5ad-4fb4-9ea4-1570aa5b4009
            Total devices 2 FS bytes used 28.00KB
            devid    2 size 2.00GB used 272.00MB path /dev/sdb2

    # fgrep btrfs /proc/mounts
    /dev/sdb2 /mnt/1 btrfs rw,relatime,space_cache 0 0
    # ls -l /etc/mtab
    -rw-r--r-- 1 root root 842 Apr 15 19:41 /etc/mtab
    # fgrep btrfs /etc/mtab
    /dev/sdb1 /mnt/1 btrfs rw 0 0

This causes GParted to report /dev/sdb1 as busy and mounted at /mnt/1
when it is no longer mounted.  This effects recent releases of Ubuntu,
13.04, 13.10 and 14.04.

Either /etc/mtab is a symlink and is identical to /proc/mounts or
/etc/mtab is a plain file with wrong information.  Fix by not reading
mounted file systems from /etc/mtab.

However old distributions only contain 'rootfs' and '/dev/root' device
names for the / (root) file system with '/dev/root' being a block device
rather than a symlink to the true device.  For example from CentOS 5.x:

    # fgrep ' / ' /proc/mounts
    rootfs / rootfs rw 0 0
    /dev/root / ext3 rw,data=ordered 0 0
    # ls -l /dev/root
    brw------- 1 root root 8, 3 Jun  4  2013 /dev/root

This prevents identification, and therefore busy detection, of the
device containing the / (root) file system.  Used to read /etc/mtab to
get the root file system device name.

    # fgrep ' / ' /etc/mtab
    /dev/sda3 / ext3 rw 0 0
    # ls -l /dev/sda3
    brw-r----- 1 root disk 8, 3 Jun  4  2013 /dev/sda3

As per commit:

    409096f739
    improved scanning for root mountpoint (/) ...

but, as discussed above, this contains an out of date device name after
the mounting device has been dynamically removed from a multi-device
btrfs, thus identifying the wrong device as busy.  Instead fall back to
reading mounted file systems from the output of the mount command, but
only when required.

    # mount | fgrep ' / '
    /dev/sda3 on / type ext3 (rw)

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood 287526681d Add devid to the cache of btrfs device information (#723842)
Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood a086e115e5 Display mount points for multi-device btrfs file systems (#723842)
Linux can only show a single device name in /proc/mounts and /etc/mtab
for each mounted btrfs, even if it is a multi-device file system.  So
GParted only shows a mount point for one of the devices in the btrfs, no
matter how many devices are part of the file system.

    # mkfs.btrfs /dev/sdb1 /dev/sdb2
    # btrfs filesystem show /dev/sdb1
    Label: none  uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
            Total devices 2 FS bytes used 156.00KB
            devid    2 size 2.00GB used 512.00MB path /dev/sdb2
            devid    1 size 2.00GB used 240.75MB path /dev/sdb1
    # mount /dev/sdb1 /mnt/1
    # grep btrfs /proc/mounts
    /dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0

GParted only shows the mount point for /dev/sdb1 as /mnt/1, but nothing
for /dev/sdb2.

Make GParted report the same mount point for all devices included in a
multi-device btrfs file system.

Add btrfs specific get_mount_device() method to report the mounting
device, if any, for the btrfs file system in the occupying the device in
question.  Uses the existing cache of btrfs file system device
membership.  Also extract common code from GParted_Core::
set_mountpoints() into set_mountpoints_helper().

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood 76e64f2905 Detect busy status of multi-device btrfs file systems (#723842)
Busy detection of file systems works by checking if the device is
mounted (appears in the mount_info map).  For a multi-device btrfs file
system this will only report one of the devices as busy, not all of
them.

    # btrfs filesystem show /dev/sdb1
    Label: none  uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
            Total devices 2 FS bytes used 156.00KB
            devid    2 size 2.00GB used 512.00MB path /dev/sdb2
            devid    1 size 2.00GB used 240.75MB path /dev/sdb1
    # mount /dev/sdb1 /mnt/1
    # grep btrfs /proc/mounts
    /dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0

GParted will only report /dev/sdb1 as busy, but not /dev/sdb2.

Add btrfs specific is_busy() method which reports the device as busy if
any of the devices in the btrfs file system are mounted.  This uses a
cache which maps device membership in all btrfs file systems.  The cache
is cleared on GParted refresh and incrementally populated as each btrfs
partition is checked for busy status.

WARNING:
Removal of the mounting device from a btrfs file system makes it
impossible to determine whether the file system is mounted or not for
linux <= 3.4.  This is because /proc/mounts continues to show the old
device which is no longer a member of the file system.

    # btrfs device delete /dev/sdb1 /mnt/1
    # sync
    # grep btrfs /proc/mounts
    /dev/sdb1 /mnt/1 btrfs rw,seclabel,relatime,ssd,space_cache 0 0
    # btrfs filesystem show /dev/sdb1
    # btrfs filesystem show /dev/sdb2
    Label: none  uuid: 36eb51a2-2927-4c92-820f-b2f0b5cdae50
            Total devices 1 FS bytes used 28.00KB
            devid    2 size 2.00GB used 1.02GB path /dev/sdb2

Fixed in linux 3.5 by commit:
    Btrfs: implement ->show_devname
    https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=9c5085c147989d48dfe74194b48affc23f376650

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood a0c0533e3e Add is_dev_mounted() to expose core partition is mounted test (#723842)
Add static member function GParted_Core::is_dev_mounted() so that other
modules can determine if a particular partition contains a mounted file
system or not.

Make it a static member function so that it can be called without
needing the gparted_core object.  Extend to make the group of
manipulated variables (mount_info, fstab_info) and manipulating
functions (init_maps(), read_mountpoints_from_file(),
read_mountpoints_from_file_swaps(), get_all_mountpoints()) static too.

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood b1dc9e69e3 Make partition busy detection method selectable per file system (#723842)
GParted's primary inbuilt busy detection method is "is the partition
mounted?".  A custom method is used for LVM2 PV because its not a
mounted file system.

Make busy detection selectable per file system type.

    .fs.busy = FS::NONE  (default)
        No busy detection.

    .fs.busy = FS::GPARTED
        Use internal GParted method which checks if the partition is
        mounted.

    .fs.busy = FS:EXTERNAL
        Call the file system type's member function is_busy().

LVM2 PV busy detection changes from a special case to just electing to
call the lvm2_pv::is_busy() method.  Linux Software RAID remains a
special case because it's only recognised, but not otherwise supported.

Bug #723842 - GParted resizes the wrong filesystem (does not pass the
              devid to btrfs filesystem resize)
2014-07-28 10:03:16 -06:00
Mike Fleetwood 0fcfd18061 Prevent cross thread write after free in _OnReadable() (#731752)
Fragment of debugging and valgrind output:
D: tid=2193 main()
...
D: tid=2202 GParted_Core::set_devices_thread()
...
D: tid=2202 Utils::execute_command(command="dumpe2fs -h /dev/sda1", output, error, use_C_locale=1)
D: tid=2202 this=0x13fef4a0 PipeCapture::PipeCapture()
D: tid=2202 this=0x13fef4f0 PipeCapture::PipeCapture()
D: tid=2202 this=0x13fef4a0 PipeCapture::connect_signal()
D:  sourceid=77
D: tid=2202 this=0x13fef4f0 PipeCapture::connect_signal()
D:  sourceid=78
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D:  signal_update.emit()
D:  return true
D: tid=2193 data=0x13fef4f0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4f0 PipeCapture::OnReadable()
D:  signal_update.emit()
D:  return true
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D:  signal_update.emit()
D:  return true
D: tid=2193 data=0x13fef4f0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4f0 PipeCapture::OnReadable()
D:  signal_eof.emit()
D:  return false
D:  (!rc)  &(pc->sourceid)=0x13fef518
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D:  signal_update.emit()
D:  return true
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D:  signal_update.emit()
D:  return true
D: tid=2193 data=0x13fef4a0 PipeCapture::_OnReadable()
D: tid=2193 this=0x13fef4a0 PipeCapture::OnReadable()
D:  signal_eof.emit()
D: tid=2202 this=0x13fef4f0 PipeCapture::~PipeCapture()
D:  sourceid=0
D: tid=2202 this=0x13fef4a0 PipeCapture::~PipeCapture()
D:  sourceid=77
D:  return false
D:  (!rc)  &(pc->sourceid)=0x13fef4c8
==2193== Thread 1:
==2193== Invalid write of size 4
==2193==    at 0x490580: GParted::PipeCapture::_OnReadable(_GIOChannel*, GIOCondition, void*) (PipeCapture.cc:56)
==2193==    by 0x38662492A5: g_main_context_dispatch (gmain.c:3066)
==2193==    by 0x3866249627: g_main_context_iterate.isra.24 (gmain.c:3713)
==2193==    by 0x3866249A39: g_main_loop_run (gmain.c:3907)
==2193==    by 0x3D7FD45C26: gtk_main (gtkmain.c:1257)
==2193==    by 0x469743: GParted::GParted_Core::set_devices(std::vector<GParted::Device, std::allocator<GParted::Device> >&) (GParted_Core.cc:155)
==2193==    by 0x4A78F1: GParted::Win_GParted::menu_gparted_refresh_devices() (Win_GParted.cc:1259)
==2193==    by 0x4A7886: GParted::Win_GParted::on_show() (Win_GParted.cc:1253)
==2193==    by 0x3D82B2009C: Gtk::Widget_Class::show_callback(_GtkWidget*) (widget.cc:3855)
==2193==    by 0x3867210297: g_closure_invoke (gclosure.c:777)
==2193==    by 0x3867221B86: signal_emit_unlocked_R (gsignal.c:3516)
==2193==    by 0x386722A0F1: g_signal_emit_valist (gsignal.c:3330)
==2193==  Address 0x13fef4c8 is not stack'd, malloc'd or (recently) free'd
==2193==

PipeCapture.cc (with debugging):
    46  gboolean PipeCapture::_OnReadable( GIOChannel *source,
    47                                     GIOCondition condition,
    48                                     gpointer data )
    49  {
    50          std::cout << "D: tid=" << (long int)syscall(SYS_gettid) << " data=" << data << " PipeCapture::_OnReadable()" << std::endl;
    51          PipeCapture *pc = static_cast<PipeCapture *>(data);
    52          gboolean rc = pc->OnReadable( Glib::IOCondition(condition) );
    53          if (!rc)
    54          {
    55                  std::cout << "D:  (!rc)  &(pc->sourceid)=" << &(pc->sourceid) << std::endl;
    56                  pc->sourceid = 0;
    57          }
    58          return rc;
    59  }

The use after free across threads only happens when an external program
is being executed from a thread other than the main() thread.  This is
because by default glib registered callbacks are run by the glib main
loop, which is only called from the main() thread with Gtk::Main::run().

Event sequence:
tid=2193                      tid=2202

main()
...
  GParted_Core::set_devices()
    Glib::Thread::create(... set_devices_thread ...)
    Gtk::Main::run()          GParted_Core::set_devices_thread()
                              ...
                                Utils::execute_command("dumpe2fs ... /dev/sda1" ...)
                                  Glib::spawn_async_with_pipes()
                                  PipeCapture outputcapture(out, output)
                                  outputcapture.connect_signal()
      //Glib main loop runs callback
      PipeCapture::_OnReadable()
        pc->OnReadable()
          //output read
          signal_update.emit()
          return true
      ...
      //Glib main loop runs callback
      PipeCapture::_OnReadable()
        pc->OnReadable()
          //eof reached
[1]       signal_eof.emit()
                                  return status.exit_status
[2]                               PipeCapture::~PipeCapture()
[3]       return false
[4]     pc->sourceid = 0

What is happening is that the PipeCapture destructor [2] is running in
the set_devices_thread() thread and freeing the object's memory as soon
as signal_eof.emit() [1] has been called.  Then signal_eof.emit()
returns back to OnReadable() which then returns false [3] back to the
_OnReadable() callback function which then assigns 0 to sourceid member
variable [4] in the already freed object, detected by valgrind as:
    Invalid write of size 4
       at ... GParted::PipeCapture::_OnReadable(...) (PipeCapture.cc:56)

This is happening because PipeCapture member variable sourceid is being
saved, in a different thread, just so the _OnReadable() callback can be
removed.  However a glib IOChannel callback, type GIOFunc(), returning
false will be automatically removed.

    GLib Reference Manual 2.26 / IO Channels
    https://developer.gnome.org/glib/2.26/glib-IO-Channels.html#GIOFunc

    GIOFunc()

    Returns : the function should return FALSE if the event source
              should be removed

Therefore fix by just not saving the event sourceid at all, and not
calling g_source_remove() to manually remove the callback, but instead
letting glib automatically remove the callback when it returns false.

Bug #731752 - Write after free cross thread race in
              PipeCapture::_OnReadable()
2014-07-06 10:22:40 -06:00
Phillip Susi 947cd02857 Change OperationDetail to not store complex objects in STL containers (#729139)
OperationDetail was storing its children in a std::vector.  This means they
can be moved around in memory arbitrarily, going through indeterminate
lifetimes.  This is generally a bad thing for any non trivial object and
in the case of OperationDetail, it created havoc with the way it maintains
pointers between parent/child objects for signal connections.  It will now
keep only pointers to children in a std::vector instead, so their lifetime
can be controlled, fixing various crashes.

Bug 729139 - Refactor OperationDetail to address random behavior
2014-05-18 10:07:45 -06:00
Curtis Gedak 6efa623401 Add optional yalign argument to Utils::mk_label() method
As part of the work on bug 652044 - uses deprecated APIs, selectable
vertical alignment was defaulted to ALIGN_CENTER for all labels.  The
relevant commits can be viewed in comment 26 of said bug report.
https://bugzilla.gnome.org/show_bug.cgi?id=652044#c26

For multi-line labels a vertical ALIGN_CENTER value is not
consistently aesthetically pleasing.  This becomes obvious when a
single-line heading label is paired with a multi-line value label.
To improve the aesthetics, a vertical alignment of ALIGN_TOP is
preferred.

Hence re-add the ability to optionally specify a vertical alignment for
labels.  If a yalign value is not specified a default vertical alignment
of ALIGN_CENTER is used.
2014-04-28 08:42:40 +01:00
Curtis Gedak e075ab006e Remove unused text_color argument from Utils::mk_label() method
None of the current GParted code uses the text_color argument for
Utils::mk_label().  Remove unused argument to simplify code.
2014-04-28 08:42:40 +01:00
Curtis Gedak ccaeb8dc51 Make the partition information dialog resizable (#690542)
Make the dialog resizable, add a vertical scrollbar to the information
and messages section, and set the initial height to ensure the dialog
fits entirely on an 800x600 screen.

A default height is required because some window managers, such as
fluxbox used in GParted Live, only permit resizing the height by using
the bottom corners of the dialog.  If the dialog is too large for the
screen then the user would not be able to resize it.

Note that two default initial heights are used in an effort to minimize
the amount of extra whitespace.

Bug 690542 - Partition Information Dialog Warning not readable
2014-04-28 08:42:40 +01:00
Mike Fleetwood 5f6656f267 Initialise file system objects only once
The code used to unnecessarily destroy and re-create the file system
objects on every scan for file system support tools.

Instead only create the file system objects once and just call each
object's get_filesystem_support() method on each rescan.
2014-04-23 10:25:56 -06:00
Mike Fleetwood 131098a797 Remove set_proper_filesystem() method
Prior to commit:

    1f3b11748e
    Remove GParted_Core::p_filesystem (#683149)

set_proper_filesystems() used to set GParted_Core::p_filesystem member
variable to one of the FileSystem objects, but that was just treating it
like a local variable.  After the commit local variables named
p_filesystem were used where required and set_proper_filesystem() became
a function which did nothing other than call get_filesystem_object().

Now remove set_proper_filesystem() altogether and use
get_filesystem_object() in its place.
2014-04-23 10:25:27 -06:00
Mike Fleetwood 67115eeff2 Remove unused member variable GParted_Core::buf 2014-04-23 09:54:20 -06:00
Phillip Susi 86111fe12a Use e2image to move/copy ext[234] file systems (#721516)
Use e2image features added in e2fsprogs 1.42.9 to move/copy
an ext[234] file system more efficiently by skipping unused blocks.
Fall back to the internal copy algorithm if e2image is not found
or does not support move/copy.

Bug #721516 - Use e2image to move/copy ext[234] filesystems
2014-03-05 22:12:10 +00:00
Mike Fleetwood 9728479771 Recognise BitLocker encrypted partitions (#723232)
Only recognises partitions containing BitLocker Disk Encryption content.
No other actions are supported.

Bug #723232 - BitLocker Disk Encryption not recognised
2014-01-31 09:55:05 -07:00
Mike Fleetwood a70bfd32fe Restore compilation order of source files
Restore the order of the source files so that they are once again
compiled in order A-Z, a-z.  Order is obtained with:

    fgrep .cc src/Makefile.am | LANG=C sort
    fgrep .h include/Makefile.am | LANG=C sort
2014-01-27 10:54:48 -07:00
Mike Fleetwood 6f9b99f138 Make the File System Support dialog resizable (#342682)
Make the dialog resizable, add a vertical scrollbar and set the minimum
(and therefore initial) height to 500 pixels.  This is so that the
dialog entirely fits on an 800x600 screen, thus allowing the rescan
button to be pressed.

100 pixel difference is to account for the size of the top and bottom
GNOME 2 panels and two sets of title bars.  Two sets of title bars
because the window manager tries to place the top of dialog title bars
in line with the bottom of the main window title bar.

Bug #342682 - too much information in 'features' dialog
2014-01-27 10:54:48 -07:00
Mike Fleetwood 59f684d8cd Always show the File System Support dialog legend (#342682)
Make the legend always shown, ready for when the dialog is resizable.

Change the widget containing the legend from an expander to a frame
widget.  Set the frame to be borderless using a bold label as
recommended in the GNOME Human Interface Guidelines 2.2.1 / Controls /
Frames and Separators.

    https://developer.gnome.org/hig-book/2.32/controls-frames.html.en

Bug #342682 - too much information in 'features' dialog
2014-01-27 10:54:48 -07:00
Daniel Mustieles 3861b9257b Replace obsolete FSF postal address in copyright notices (#721565)
This is part of parent bug:
    Bug #721455 - Obsolete info in license text on multiple modules

and GNOME Goal:
    https://wiki.gnome.org/Initiatives/GnomeGoals/Proposals

    * verify all source files to make sure they have a license and a
      copyright, and that both are up-to-date

Bug #721565 -  License text contains obsolete FSF postal address
2014-01-26 10:53:23 +00:00
Mike Fleetwood 7b43d52720 Display partition table types in order (#711098)
In the Create Partition Table dialog display the entries in the combobox
in order.

Previously the default of MSDOS or GPT was moved to the first item in
the combobox.  Now the partition table types remain in order with just
either MSDOS or GPT being selected as as the default as required.

The partition table types are displayed in the order supplied by
libparted, which is alphabetic except with "loop" last.

Bug #711098 - Default partition table can not handle > 2 TiB disks
2014-01-06 10:45:00 +00:00
Phillip Susi 07bd72ba80 Default to GPT on disks >= 2 TiB (#711098)
MSDOS partition table is limited to addressing 2^32 sectors, limiting
disks using 512 byte sectors to 2 TiB in size.  Fdisk reports the
following warning on disks 2 TiB and larger.

    # truncate -s 2T /var/tmp/loop-2T
    # losetup /dev/loop0 /var/tmp/loop-2T
    # fdisk /dev/loop0

    WARNING: The size of this disk is 2.2 TB (2199023255552 bytes).
    DOS partition table format can not be used on drives for volumes
    larger than (2199023255040 bytes) for 512-byte sectors. Use parted(1) and GUID
    partition table format (GPT).

(Fdisk arguably reports this warning one sector too early.  Anyway for
safety and consistency GParted will use this limit too).  Continue to
use MSDOS as the default partition table type for disks smaller than 2
TiB and use GPT as the default for disks 2 TiB and larger.  This
maximises compatibility.

Also remove the advanced expander and always show the partition table
list box.

Bug #711098 - Default partition table can not handle > 2 TiB disks
2014-01-06 10:44:59 +00:00
Phillip Susi de2844d02d Add online resize support (#694622)
Many file systems are capable of growing while mounted, and a few can
even shrink.  This support must be explicitly enabled at configure time
with the --enable-online-resize flag and depends on a patched libparted.
Also requires kernel >= 3.6 for partition resizing, even if the
partition is in use (BLKPG_RESIZE_PARTITION).

Thanks to Mike Fleetwood for double check mark idea instead of a second
column to show the online grow/shrink.

Bug #694622 - Add support for online resize
2013-11-24 10:10:37 +00:00
Mike Fleetwood 7ae05b7241 Remove unused function declarations for *_mtoolsrc_file()
Remove left behind function declarations create_mtoolsrc_file() and
delete_mtoolsrc_file() after commit:

    2706f0174a
    Remove mtoolsrc file
2013-10-19 10:21:09 -06:00
Mike Fleetwood d2e1130ad2 Detect busy status of Linux Software RAID members (#709640)
Read the contents of /proc/mdstat file to determine if a device is a
member of of an active RAID array.

    $ cat /proc/mdstat
    Personalities : [raid1]
    md1 : active raid1 sda1[2] sdb1[3]
          524224 blocks super 1.0 [2/2] [UU]

    md2 : active raid1 sdb2[2] sda2[3](F)
          5238720 blocks super 1.1 [2/1] [U_]

    md3 : active raid1 sdb3[1]
          10477440 blocks super 1.1 [2/1] [_U]
          bitmap: 1/1 pages [4KB], 65536KB chunk

    md4 : inactive sda4[0](S)
          1048564 blocks super 1.2

    unused devices: <none>

There are 5 example Linux Software RAID arrays, md1 to md5.  All are
RAID1 mirrors with 2 members, in various states.

    Array  Members     Status
    md1    sda1, sdb2  Fully operational.
    md2    sda2, sdb2  Member sda2 marked as faulty.  (Device sda2 is
                       still in use).
    md3    sda3, sdb3  Member sda3 has been removed.  (Device sda3 is
                       not in use).
    md4    sda4, sdb4  Incremental start of member sda4 only.  (Neither
                       member devices is in use).
    md5    sda5, sdb5  Array stopped.  (Neither member device is in
                       use).

Also disable "Unmount" in the partition menu for active RAID array
members.

Bug #709640 - Linux Swap Suspend and Software RAID partitions not
              recognised
2013-10-19 10:21:03 -06:00
Mike Fleetwood fac3f5b865 Recognise Linux Swap Suspend and Software RAID partitions (#709640)
Recognise in kernel, Linux Swap Suspend partitions.  (When hibernated
the kernel write the RAM out to swap space and changes the magic string
from swap space to suspend).  Recognition required either
libparted >= 1.8.8.1 or blkid from util-linux >= 2.15 or before that
blkid from e2fsprogs >= 1.39.

Recognise Linux Software RAID partitions.  Recognition requires blkid
from util-linux >= 2.15.

Example:

    # blkid /dev/sda10 /dev/sda11
    /dev/sda10: ... TYPE="swsuspend"
    /dev/sda11: ... TYPE="linux_raid_member"

    # parted /dev/sda print
    Model: ATA SAMSUNG HM500JI (scsi)
    Disk /dev/sda: 500GB
    Sector size (logical/physical): 512B/512B
    Partition Table: msdos

    Number  Start   End     Size    Type      File system     Flags
    ...
    10      361GB   362GB   1074MB  logical   swsusp
    11      362GB   363GB   1074MB  logical                   raid

Bug #709640 - Linux Swap Suspend and Software RAID partitions not
              recognised
2013-10-19 10:05:54 -06:00
Mike Fleetwood be2689ad25 Stop using deprecated widget alignment enumerators (#652044)
Step 3 of 3:

Now that all label widgets are created with ALIGN_LEFT and ALIGN_CENTER
alignment remove the x_align and y_align parameters from mk_label() and
always use this alignment.  Also specify this alignment via floats
rather than enumerators, one of which was deprecated.

Bug #652044 - uses deprecated APIs
2013-10-18 10:17:22 -06:00
Mike Fleetwood 1b54123580 Enhance line discipline in PipeCapture::OnReadable() (#709276)
Add concept of cursor position within the current line, separate from
the end of the buffer.  This is so that programs which output a text
progress bar using backspace, such as resize2fs -p, are displayed
correctly.

Bug #709276 - Percentage indicator for subcommand
2013-10-03 10:23:46 -06:00
Mike Fleetwood 293c8929a7 Actually display error message from statvfs() failure
Pass error_message parameter by reference to
get_mounted_filesystem_usage() so that the caller can access the
modified error message when required.
2013-09-24 09:49:10 -06:00
Mike Fleetwood 387b391d6d Add reporting of linux-swap usage (#708107)
For active swap space read the usage from /proc/swaps.  (Linux kernel
uses units of 1 KiB).  By definition inactive swap space is 100% free.

    $ cat /proc/swaps
    Filename                                Type            Size    Used    Priority
    /dev/sda2                               partition       5242876 430552  -1

Always set fs.read = FS::EXTERNAL even if /proc/swaps doesn't exist so
that an attempt is made to open the file generating a specific error, in
addition to the generic error.

    open("/proc/swaps", O_RDONLY): No such file or directory

    Unable to read the contents of this file system!
    Because of this some operations may be unavailable.

    The cause might be a missing software package.
    The following list of software packages is required for linux-
    swap file system support: util-linux.

Closes Bug #708107 - Usage of swap space is not reported
2013-09-24 09:49:10 -06:00
Mike Fleetwood 78c558c350 Also accept btrfs tools using IEC prefix multipliers (#706914)
Currently the btrfs command outputs figures to 2 decimal places followed
by an SI multiplier, e.g. 1.00GB.

This patch to btrfs-progs has been included in the integration
repository and will likely be included in the official btrfs-progs
repository at some point.  It changes btrfs-progs to use IEC
multipliers, e.g. 1.00GiB.  In fact multipliers already aren't used for
figures less than 1024.
    [PATCH] btrfs-progs: use IEC units for size
    http://permalink.gmane.org/gmane.comp.file-systems.btrfs/26888
    https://patchwork.kernel.org/patch/2825841/

Make GParted capable of also accepting IEC prefix multipliers, just "B"
for bytes and no multiplier, as well as an optional space between the
number and multiplier.  Therefore accept values like these:
    1.00GB         1.00 GB
    1.00GiB        1.00 GiB
    1073741824B    1073741824 B
    1073741824

Closes Bug #706914 - Prepare for btrfs tools using IEC prefix
                     multipliers
2013-08-29 10:20:52 -06:00
Mike Fleetwood 246e05559d Clear btrfs file system super block mirror copies too (#705426)
With recent btrfs-progs, GParted failed to format a btrfs file system
over the top of an existing one.  Make btrfs failed with this error:

    # mkfs.btrfs /dev/sdb1
    ...
    /dev/sdb1 appears to contain an existing filesystem (btrfs).
    Use the -f option to force overwrite.

With this commit to btrfs-progs on 2013-02-19, mkfs.btrfs checks for
existing file system signatures, including all mirror copies of btrfs
super blocks, before writing to the partition.

    http://git.kernel.org/cgit/linux/kernel/git/mason/btrfs-progs.git/commit/?id=2a2d8e1962e8b6cda7b0a7584f6d2fb95d442cb6
    btrfs-progs: require mkfs -f force option to overwrite filesystem or partition table

Make GParted clear all the mirror copies of the btrfs file system super
blocks as erase_filesystem_signatures() is intended to prevent detection
of old signatures.  This also avoids having to determine if the -f
option to mkfs.btrfs is available before trying to use it.

Closes Bug #705426 - Formatting Existing BTRFS Partition as BTRFS Fails
                     Because mkfs.btrfs Is Not Run with "-f"
2013-08-26 10:16:01 -06:00
Mike Fleetwood 1ae03dee95 Recognise new dosfstools program names (#704629)
Dosfstools >= 3.0.18, released June 2013, renamed the programs thus:

    dosfslabel becomes fatlabel,
    dosfsck becomes fsck.fat,
    and mkdosfs becomes mkfs.fat.

Dosfstools creates symbolic links for the old names for backward
compatibility, but unfortunately the Debian dosfstools-3.0.22-1
(experimental) package doesn't include those symbolic links.  This
causes create, check and read unmounted FAT16/32 file systems to not be
supported.

Make GParted look for the new names first and the old names second.

Closes Bug #704629 - Program name changes in dosfstools 3.0.18+ break
                     FAT16/32 support
2013-07-27 11:32:20 -06:00
Sinlu Bes 20006e1f8e Add create_with_label flag to struct FS (#701569)
It was difficult to retrieve whether a filesystem's label can be set on reformat.

The read_label flag can't be used as it decides whether to use the logic in the filesystem class
rather than the fallback in GParted::set_device_partitions, to determine the label of a partition.

The create_with_label flag is NONE for file systems that we cannot format with a
label (or that we cannot format at all).
The value is usually EXTERNAL for file systems that we can format with a label.
2013-06-09 09:50:54 -06:00
Mike Fleetwood aed1fb58cf Remove unused read-only functionality from internal block copy
The read-only functionality is unused and the readonly parameter is
always false in copy_filesystem() and copy_blocks() methods.  This has
been the case since the copy simulation was dropped by commit:

    b9b4b2e55d
    Remove simulation pass ( read test ) on move
2013-06-05 10:57:39 -06:00
Mike Fleetwood 2b51d87147 Make include guards unique (#539297)
Include guards need to be unique within GParted code and all included
library header files.
    http://en.wikipedia.org/wiki/Include_guard#Difficulties

Use this model for all include guards:
    #ifndef GPARTED_FILE_NAME_H
    #define GPARTED_FILE_NAME_H
    ...
    #endif /* GPARTED_FILE_NAME_H */

Closes Bug #539297 - Make include guards unique
2013-06-05 10:57:39 -06:00
Mike Fleetwood 4cc426c6cf Only allow Undo and Apply after merging operations (#699452)
It was possible to make GParted crash by adding a label, check or new
UUID operation and then applying the operation before the view of
pending operations had finished fully opening.  The operation would be
successfully applied but GParted would crash afterwards.

The fault was that Add_Operation() still enabled the Undo and Apply
buttons and processed the GTK event loop before merging the list of
pending operations.  Faulty code flow went like this:

    activate_*()
        Add_Operation()
            Add operation to the operations[] vector
            Enable Undo and Apply buttons
            Refresh_Visual()
                Process GTK event loop
                    Process Apply button callback applying operations,
                    refreshing display and clearing operations[] vector
        Merge operations in the operations[] vector
        << Core dump here >>
            Merge_Operations()
                Refresh_Visual()

This faulty code flow came about when merging of operations was added
and it didn't appreciate that the operations[] vector could have been
processed and cleared by Add_Operations() before the merge step.
Relevant commit:

    b10349ae37
    Merge overlapping operations (#438573)

Fragment of code in the label operation case:

  2454  void Win_GParted::activate_label_partition()
  2455  {
  ...
  2472          Add_Operation( operation ) ;
  2473
  2474          // Verify if the two operations can be merged
  2475          for ( unsigned int t = 0 ; t < operations .size() - 1 ; t++ )
  2476          {
  2477              if ( operations[ t ] ->type == OPERATION_LABEL_PARTITION )
  2478              {
  2479                  if ( Merge_Operations( t, operations .size() - 1 ) )
  2480                      break;
  2481              }
  2482          }

Commentary in the crashing label operation case:

  2472  The pending operation was already applied when Add_Operation()
        returned resulting in the operations[] vector being cleared
        setting its size to 0.
  2475  The return type of operations.size() is an unsigned integral, so
        the upper limit of the for loop is t < 0UL - 1.  Assuming a
        32-bit machine that's t < 4294967295.
  2477  operations[] vector is access from out of bounds offset 0
        upwards until unallocated memory is accessed resulting in a core
        dump.

Fix this by not enabling the Undo and Apply buttons and processing the
GTK event loop until after merging of operations has been performed.
Fixed code flow goes like this:

    activate_*()
        Add_Operation()
            Add operation to the operations[] vector
        Merge operations in the operations[] vector
            Merge_Operations()
        show_operationslist()
            Enable Undo and Apply buttons
            Refresh_Visual()
                Process GTK event loop
                    Process Apply button callback applying operations,
                    refreshing display and clearing operations[] vector

Not allowing the operations list to be process until after the merge
step is the be correct ordering.  This also prevents the new operation
from flashing up in the operations list and then immediately
disappearing if merged.  In the case of adding the first operation,
delaying enabling the Undo and Apply buttons is enough as the buttons
were previously disabled preventing the operation being applied before
the merge.  In the case of adding further operations, processing of the
GTK event loop must also be delayed until after the merge to prevent the
operations being applied before the merge.  Although that window of
opportunity would only be microseconds.

Bug #699452 - Crash when applying operations before pending operations
              fully displayed
2013-05-19 13:18:25 -06:00
Mike Fleetwood 7ede0ca3cc Pad fat16/32 file system labels with spaces (#700228)
Mlabel sometimes writes uninitialised memory at the end of the label.
This causes mlabel, and therefore GParted, to display extra junk at the
end of the label.  Depending on the bytes written GParted may also show
the following error on stdout:

    (gpartedbin:18116): glibmm-CRITICAL **:
    unhandled exception (type Glib::Error) in signal handler:
    domain: g_convert_error
    code  : 1
    what  : Invalid byte sequence in conversion input

This is caused by a bug in mlabel, believed fixed in mtools 4.0.14.
Effects at least Fedora 14, RHEL/CentOS 6.x and Debian 6.  (Use label
"1234567890" on Debian 6 to reproduce).  Reproduction steps:

    # mkdosfs -F16 /dev/sda7
    mkdosfs 3.0.9 (31 Jan 2010)
    # export MTOOLS_SKIP_CHECK=1
    # mlabel ::123456 -i /dev/sda7
    # mlabel -s :: -i /dev/sda7
     Volume label is 123456~1t

It is not possible to detect which characters are junk so they can't be
trimmed.  Instead just space pad labels so that at least newly written
labels aren't effected.  (Fat labels are space padded on the disk by
definition anyway).

Bug #700228 - FAT16/32 labels are sometimes shown corrupted
2013-05-17 09:23:56 -06:00
Mike Fleetwood 519af1a7c0 Combine duplicate code for fat16/32
There was virtually no difference between the separate modules for fat16
and fat32.  Remove module fat32 and patch fat16 to serve both file
system subtypes.  This is equivalent to what was previously done for
ext[234] by commit:

    38dc55d49c
    Combine duplicate code for ext[234]
2013-05-17 09:23:56 -06:00
Mike Fleetwood 0d52cd19d7 Rename signals update and eof
Rename the libsigc++ signals to signal_update and signal_eof to match
the naming used for signals in GParted.
    fgrep 'sigc::signal' include/*.h

Also explicitly use the emit() method rather than using the object
operator().  This again is to match the convention in GParted and make
it more obvious what is happening.
    fgrep '.emit(' include/*.h
2013-05-10 10:03:53 -06:00
Phillip Susi 9475731ac8 Avoid glibmm GSource bug/crash (again) (#697727)
The previous commit missed one glibmm GSource wrapper in the form of the
io watch for the PipeCapture class.  Convert this one to use glib
directly as well.

Bug #697727 - Segfault in livecd Gparted v 0.15.0-3 when copying
              partition
2013-04-29 18:42:53 +01:00
Mike Fleetwood 1386984def Add copyright notice to PipeCapture .cc and .h files 2013-04-28 13:51:06 -06:00
Phillip Susi c36934aca5 Avoid glibmm GSource bug/crash (#697727)
The glibmm GSource wrappers have a bug where they do not do
reference counting properly, and have a race condition where
the background thread can try to touch the source after the
main thread has already processed and destroyed it.  This
results in writes to freed memory and sometimes this causes
crashes or other erratic behavior.  Avoid using the glibmm
wrappers and use glib directly.  See bug #561885 for details
of the glibmm bug.

Bug #697727 - Segfault in livecd Gparted v 0.15.0-3 when copying partition
2013-04-17 11:53:55 -06:00