Commit Graph

4100 Commits

Author SHA1 Message Date
Mike Fleetwood 1e15fc9385 Add fallback of removing systemd mount unit masks directly (!116)
On RHEL / CentOS 8 GParted reports this error to the terminal when it is
closed:
    # gparted
    GParted 1.5.0-git
    configuration --enable-online-resize
    libparted 3.2
>>  --runtime cannot be used with unmask
    # $?
    0

and leaves mount units masked:
    # systemctl list-units '*.mount'
      UNIT                  LOAD   ACTIVE SUB     DESCRIPTION
      ------------------------------------------------------------------
    * -.mount               masked active mounted Root Mount
    * boot.mount            masked active mounted boot.mount
      ...

This is because of this change [1] released in systemd 239.  Systemd bug
9393 [2] was raised and the change was reverted [3] in systemd 240.
According to repology.org only RHEL / CentOS 8 (and clones) and Fedora
29 shipped with systemd 239 [4].

Fix by detecting non-zero exit status from systemctl and falling back to
directly removing the runtime mount unit mask files instead.  Then have
to use systemctl daemon-reload to inform systemd to reload it's
configuration from disk to discover the masks have been removed.

[1] systemctl: when removing enablement or mask symlinks, cover both
    /run and /etc
   4910b35078
[2] systemctl no longer allows unmask in combination with --runtime
    #9393
    https://github.com/systemd/systemd/issues/9393
[3] Revert "systemctl: when removing enablement or mask symlinks, cover
    both /run and /etc"
    1830ac51a4
[4] Versions for systemd
    https://repology.org/project/systemd/versions

Closes !116 - Systemd mount masking and udev rule location updates
2023-08-15 17:04:30 +00:00
Balázs Úr d698f6a591 Update Hungarian translation 2023-07-25 23:45:43 +00:00
Yosef Or Boczko dfa2cd6f72 Update Hebrew translation 2023-07-15 18:45:20 +00:00
Jürgen Benvenuti 371d769810 Update German translation 2023-07-14 09:22:49 +00:00
Sergej A 7cffba5f3c Update Russian translation 2023-07-11 09:23:16 +00:00
Kukuh Syafaat 82e739b458 Update Indonesian translation 2023-07-09 10:59:42 +00:00
Hugo Carvalho d5313fd4b2 Update Portuguese translation 2023-07-02 15:21:41 +00:00
Anders Jonsson 5b675a05da Update Swedish translation 2023-06-29 08:57:44 +00:00
Yuri Chornoivan 1693a622d6 Update Ukrainian translation 2023-06-25 14:21:51 +00:00
Piotr Drąg 01efda7a2a Update Polish translation 2023-06-25 13:39:57 +02:00
Ekaterine Papava b200dff4f9 Update Georgian translation 2023-06-24 17:03:35 +00:00
Marcin Zepp ac6528373f Fix crash when dealing with 0000-0000 exfat UUID (!115)
GParted crashes when blkid doesn't provide the UUID of the exfat
partition and its serial has preceding zeroes (and it isn't mounted).

blkid doesn't report UUID if the serial number is 0000-0000 (a.k.a.
0x0).

Steps to reproduce:

    # truncate -s 4M /tmp/disk.img
    # losetup -f --show /tmp/disk.img
    /dev/loop0
    # mkfs.exfat /dev/loop0
    [...]
    exFAT format complete!
    # partprobe /dev/loop0
    # blkid /dev/loop0
    /dev/loop0: UUID="F7BF-ABFF" BLOCK_SIZE="512" TYPE="exfat" PTTYPE="dos"
    # exfatlabel /dev/loop0 -i 0x0
    exfatprogs version : 1.1.3
    New volume serial : 0x0
    # blkid /dev/loop0
    /dev/loop0: BLOCK_SIZE="512" TYPE="exfat" PTTYPE="dos"
    # gparted /dev/loop0
    GParted 1.3.1
    configuration --enable-libparted-dmraid --enable-online-resize
    libparted 3.4

    ** (gpartedbin:94926): ERROR **: 10:45:01.894:
    unhandled exception (type std::exception) in signal handler:
    what: basic_string::assign: __pos (which is 18446744073709551615) > this->size() (which is 3)

    Trace/breakpoint trap (core dumped)
    # losetup -d /dev/loop0; rm /tmp/disk.img

As blkid doesn't report exfat UUID 0000-0000 FS_Info cache can't report
it so exfat::read_uuid() is called.  Then `tune.exfat -i /dev/loop0` is
executed:

	# tune.exfat -i /dev/loop0
	exfatprogs version : 1.1.3
	volume serial : 0x0

And exfat::serial_to_blkid_uuid() is called with "0x0", which causes a
crash.  Fix by safely handling volume serial numbers of any length,
specifically shorter than 8 hexadecimal digits.

Closes !115 - Fix crash when dealing with 0000-0000 exfat UUID
2023-06-24 15:48:52 +01:00
Mike Fleetwood af684ade52 Return constant reference from ProgressBar::get_text()
get_text() only performs const access on the ProgressBar object so
return the member string by constant reference.

Previously done for other string returning getters, even though the
value is assigned to a variable and doesn't save anything:
    1f6e81295b
    Return constant reference from OperationDetail::get_description() (!94)
2023-06-17 16:13:23 +00:00
Mike Fleetwood f5ba53fb3e Return const reference from OperationDetail::get_progressbar()
The only use of the reference returned from
OperationDetail::get_progressbar() is to call const methods
ProgressBar::running(), ::get_fraction() and ::get_text().  Therefore
make OperationDetail::get_progressbar() return a const reference.
2023-06-17 16:13:23 +00:00
Mike Fleetwood 3cbedad693 Generate time remaining text for fraction complete progress bars
As described in the previous commit "Clear progress bar text when
starting the bar (#230)" progress bar data is either reporting bytes
copied or fraction complete.  The bytes copied case gets in progress
text like this:
    544.00 MiB of 1.00 GiB copied (00:00:11 remaining)

But the fraction complete gets no text.

Now also generate time remaining text for progress bars only reporting
fraction complete.  As with the bytes copied text only add the time
remaining estimate after 5 seconds have passed.  Looks like:
    (00:01:59 remaining)

This is most useful for NTFS partition copy and resize operations which
can take a while depending on the amount of data involved.
2023-06-17 16:13:23 +00:00
Mike Fleetwood 1718c5d2fb Clear progress bar text when starting it (#230)
These operations use steps which generate progress bar bytes copied
information text:
* Partition move or copy using GParted's internal block copy
* EXT2/3/4 partition move or copy
* XFS partition copy
The bytes copied text looks like this (after the copy completes and the
time remaining is no longer included):
    1.00 GiB of 1.00 GiB copied

And these operations use steps which generate progress bar information
without text (because the progress bar data only represents a fraction
complete):
* EXT2/3/4 partition resize
* EXT2/3/4 partition create
* EXT2/3/4 partition format
* EXT2/3/4 partition check
* NTFS partition resize
* NTFS partition copy

In the Applying pending operations dialog, while an operation is being
applied there are 2 progress bars.  The top progress bar displays either
a pulse bar or the progress bar data for the current step.  Additionally
for the relevant steps the progress bar generates the bytes copied text.
This text, when available, is displayed in small grey characters just
above the progress bar itself.

Copy a FAT partition and apply.  Bytes copied text is displayed just
above the top progress bar.  Copy an NTFS partition and apply.  The left
behind bytes copied text from the previous operation is displayed,
instead of nothing.

Restart GParted and copy an NTFS partition and apply.  As intended, this
time there is no bytes copied text displayed just above the top progress
bar.

As there is just a single ProgressBar object, single_progressbar, fix
this by clearing the progress bar text each time it is started.

Closes #230 - Missing progress bar text reset when applying operation
2023-06-17 16:13:23 +00:00
Olga Smirnova ead39c2446 Add Interlingue translation 2023-06-06 11:37:12 +00:00
Sabri Ünal 733eba2c4f Update Turkish translation 2023-05-26 23:00:29 +00:00
Mike Fleetwood cc4687a2aa Also check links to block devices when skipping BlockSpecial unit tests (!113)
Fragment of a failed CI test job from a GiLab job runner which didn't
allow creation of block special devices looked like:

    $ tests/makedev.sh
    mknod -m 0660 /dev/sda b 8 0
    mknod: '/dev/sda': Operation not permitted
    chown: cannot access '/dev/sda': No such file or directory
    mknod -m 0660 /dev/sda1 b 8 1
    mknod: '/dev/sda1': Operation not permitted
    chown: cannot access '/dev/sda1': No such file or directory
    mkdir: created directory '/dev/disk'
    mkdir: created directory '/dev/disk/by-id/'
    '/dev/disk/by-id/gparted-sda' -> '/dev/sda'

test/makedev.sh attempted to create two block devices it wanted for
testing, but that failed with "Operation not permitted".  It then
created dangling symbolic link /dev/disk/by-id/gparted-sda -> /dev/sda;
gparted-sda pointed to a name which didn't exist.

Despite the previous commit testing and skipping every test where the
block device doesn't exist this unit test still failed:

    [ RUN      ] BlockSpecialTest.NamedBlockSpecialObjectBySymlinkMatches
    test_BlockSpecial.cc:186: Failure
    Failed
    follow_link_name(): Failed to resolve symbolic link '/dev/disk/by-id/gparted-sda'
    test_BlockSpecial.cc:271: Skip test.  Block device '' does not exist
    [  FAILED  ] BlockSpecialTest.NamedBlockSpecialObjectBySymlinkMatches (0 ms)

The unit test called get_link_name() which read the directory
/dev/disk/by-id and found symbolic link gparted-sda.  It then called
follow_link_name() passing /dev/disk/by-id/gparted-sda which used
realpath(3) to get the canonicalised absolute pathname, which includes
following links.  But as gparted-sda pointed to a non-existent file it
failed and reported message "Failed to resolve symbolic link ...".  Then
after that the unit test skips the non-existent block device, but the
test has already failed at that point.

Fix the unit test by also checking the symbolic link points to an
existing block device before calling follow_link_name() on it.  This
works because SKIP_IF_BLOCK_DEVICE_DOESNT_EXIST() uses stat(3), which
follows symbolic links, in it's verification.

Also put SKIP_IF_BLOCK_DEVICE_DOESNT_EXIST() immediately after each
initialisation of a block device name for some sort of consistency with
it's need in this fixed NamedBlockSpecialObjectBySymlinkMatches unit
test.

Closed !113 - Fix occasional GitLab CI test jobs failures on
              BlockSpecial unit tests
2023-05-20 16:18:11 +00:00
Mike Fleetwood 43e96e4c6a Skip BlockSpecial unit tests when devices don't exist, for CI test images (!113)
Since November 2022 test_BlockSpecial has been occasionally failing in
GNOME GitLab Docker CI test jobs like this:

    [ RUN      ] BlockSpecialTest.NamedBlockSpecialObjectBlockDevice
    test_BlockSpecial.cc:216: Failure
    Value of: bs.m_major > 0 || bs.m_minor > 0
      Actual: false
    Expected: true
    [  FAILED  ] BlockSpecialTest.NamedBlockSpecialObjectBlockDevice (0 ms)
    ...
    [ RUN      ] BlockSpecialTest.TwoNamedBlockSpecialObjectBlockDevices
    test_BlockSpecial.cc:244: Failure
    Value of: bs1.m_major != bs2.m_major || bs1.m_minor != bs2.m_minor
      Actual: false
    Expected: true
    [  FAILED  ] BlockSpecialTest.TwoNamedBlockSpecialObjectBlockDevices (0 ms)
    [ RUN      ] BlockSpecialTest.NamedBlockSpecialObjectBySymlinkMatches
    test_BlockSpecial.cc:170: Failure
    Failed
    follow_link_name(): Failed to resolve symbolic link '/dev/disk/by-id/gparted-sda'
    [  FAILED  ] BlockSpecialTest.NamedBlockSpecialObjectBySymlinkMatches (0 ms)
    ...
     3 FAILED TESTS
    FAIL test_BlockSpecial (exit status: 1)

As identified previously [1] the Docker CI images no longer have any
block devices in /dev.  test/makedev.sh script was added to create block
devices test_BlockSpecial needs for it's testing.  Now a subset of the
GNOME GitLab job runners additionally prevent creation of block special
device nodes.  test/makedev.sh reports this:

    $ tests/makedev.sh
    mknod -m 0660 /dev/sda b 8 0
    mknod: /dev/sda: Operation not permitted
    chown: cannot access '/dev/sda': No such file or directory
    mknod -m 0660 /dev/sda1 b 8 1
    mknod: /dev/sda1: Operation not permitted
    chown: cannot access '/dev/sda1': No such file or directory

Alternative rejected solutions:

1.  Use fakeroot [2].  Package is available for the 3 distributions used
    in CI jobs.  Does fake stat() call.  Works when run like this in the
    CI test jobs:
        fakeroot -s test/fakeroot.env tests/makedev.sh
        fakeroot -i test/fakeroot.env make check
        fakeroot -i test/fakeroot.env make distcheck
    But if you run fakeroot ... make check on our development machines
    as a non-root user it causes the test_SupportedFileSystems unit
    tests which use losetup to fail.  This is because
    test_SupportedFileSystems thinks it's root inside the fakeroot
    environment but fakeroot doesn't fake enough for losetup to work.
    This makes running tests in the GitLab CI jobs different from how we
    would have to run them on our development machines.  Prefer not to
    do that.

2.  Use GNU ld --wrap [3] to call our own __wrap_stat() allowing
    test_BlockSpecial to provide mocked results to the stat() call in
    constructor BlockSpecial::BlockSpecial().  This works with
    GNU C Library >= 2.33, released 01-Feb-2021, and musl libc,
    therefore it works on CI tested distributions Ubuntu LTS >= 22.04
    and Alpine Linux respectively.  However this fails on earlier glibc
    releases, so will fail on CentOS 7 CI image, as the compiler emits a
    call to __xstat() rather than stat().  This is something to do with
    how glibc's /usr/include/sys/stat.h supported multiple versions of
    stat().  Don't use this as it's doesn't work everywhere.

    Additional useful implementation hints.  [4][5]

Choose to fix by just skipping unit tests which need block special names
to exist in the file system, but don't exist.  This is the same
technique that test_SupportedFileSystems uses.  So tests/makedev.sh
creates block devices if it can in the GNOME GitLab CI test images [1]
and now if that fails the individual unit tests are skipped.

[1] 57983b9fc2
    Create block special devices needed by test_BlockSpecial in GitLab
    CI jobs (!59)

[2] FakeRoot
    https://wiki.debian.org/FakeRoot

[3] ld(1) - Linux manual page
    https://man7.org/linux/man-pages/man1/ld.1.html
        "--wrap=symbol
        Use a wrapper function for symbol.  Any undefined reference to
        symbol will be resolved to "__wrap_symbol".  Any undefined
        reference to "__real_symbol" will be resolved to symbol.

        This can be used to provide a wrapper for a system function.
        The wrapper function should be called "__wrap_symbol".  If it
        wishes to call the system function, it should call
        "__real_symbol".
        ...
        "

[4] gcc: error: unrecognized option --wrap
    https://stackoverflow.com/questions/33278164/gcc-error-unrecognized-option-wrap

[5] C++ ld linker --wrap option does not work for internal function calls
    https://stackoverflow.com/questions/44464961/c-ld-linker-wrap-option-does-not-work-for-internal-function-calls

Closed !113 - Fix occasional GitLab CI test jobs failures on
              BlockSpecial unit tests
2023-05-20 16:18:11 +00:00
Mike Fleetwood 011317b23f Cat /proc/partitions and list /dev in GitLab CI test jobs (!113)
Add these simple debugging aids to the GNOME GitLab CI test job.
They've been needed before [1] so add them permanently.

[1] 57983b9fc2
    Create block special devices needed by test_BlockSpecial in GitLab
    CI jobs (!59)
        "Contents of /proc/partitions inside the Docker image when this
        test CI job failed:
        ...
        And the listing of /dev/:
        "

Closed !113 - Fix occasional GitLab CI test jobs failures on
              BlockSpecial unit tests
2023-05-20 16:18:11 +00:00
Mike Fleetwood 0defcb8b79 Stick with Alpine Linux 3.17 in the GitLab CI images
Alpine Linux just released new docker image 3.18, updating latest from
3.17 [1], which causes the GNOME GitLab CI jobs to fail like this:

    $ apk add gnome-common yelp-tools automake autoconf glib-dev libtool g++ parted-dev gtkmm3-dev itstool make git polkit-dev
    ERROR: unable to select packages:
      gnome-common (no such package):
        required by: world[gnome-common]

Based on this blog [2] I printed the apk repository configuration file
in Alpine Linux 3.17 and 3.18 docker images in GitLab CI jobs and found
this contents:

Alpine Linux 3.17
    $ cat /etc/apk/repositories
    https://dl-cdn.alpinelinux.org/alpine/v3.17/main
    https://dl-cdn.alpinelinux.org/alpine/v3.17/community

Alpine Linux 3.18
    $ cat /etc/apk/repositories
    https://dl-cdn.alpinelinux.org/alpine/v3.18/main
    https://dl-cdn.alpinelinux.org/alpine/v3.18/community

So what I conclude is that the packages GParted needs aren't yet
available or being distributed for Alpine Linux 3.18.  Therefore fix
this by explicitly sticking with Alpine Linux 3.17.

[1] Alpine docker images
    https://hub.docker.com/_/alpine/
    * 3.18.0, 3.18, 3, latest
    571516c7ce/x86_64/Dockerfile
    Committed 2023-May-09

[2] ERROR: unable to select packages error on Alpine Linux
    https://www.hasanaltin.com/error-unable-to-select-packages-error-on-alpine-linux/
2023-05-20 16:18:11 +00:00
Boyuan Yang 3163dbebc4 Update Chinese (China) translation 2023-04-28 19:35:47 +00:00
Mike Fleetwood ceaf4c232e Briefly comment STAT_* enumerators 2023-04-27 15:54:01 +00:00
Mike Fleetwood eb6a77c4fd Remove superfluous STAT_FORMATTED
STAT_FORMATTED is only used inside snap_to_mebibyte() to suppress
enforcement that partition boundaries must not overlay the MBR or EBRs
when merely formatting existing partitions.  However since commit [1],
snap_to_mebibyte() is only called inside the dialogs composing Create
New, Copy / Paste into New and Resize / Move operations and never when
composing a Format operation or any other operation which doesn't change
partition boundaries.  Therefore remove STAT_FORMATTED.

[1] 7c94b7d920
    Snap partition boundaries before dialogs update FS usage (#48)
2023-04-27 15:54:01 +00:00
Mike Fleetwood c8b4df5879 Fix available space calculation in Dialog_Partition_New::set_data()
The available number of sectors 'total_length' is calculated as one
sector too few.  However this doesn't matter because when composing a
new partition in Dialog_Partition_New::Get_New_Partition() the dialog
fits the end of the partition to the end of the unallocated partition
'new_partition->sector_end' in which it is being created, not the
available space.  Missed in earlier commit:
    4f84cff781
    cleanups

Anyway correct the calculation.
2023-04-27 15:54:01 +00:00
Mike Fleetwood 3a53d17c8d Remove unnecessary portion of MiB alignment check
As a partition's position is completely defined by it's starting and
ending sector, it is aligned if both boundaries are aligned.  The size
of a partition just depends on the starting and ending sector.
Therefore it is never necessary to also check if the size of the
partition is also an exact multiple of MiB.  Remove this unnecessary
portion of the alignment check when resizing/moving a partition (or
copy/pasting into a new partition).
2023-04-27 15:54:01 +00:00
Mike Fleetwood e801689680 Remove now duplicated Win_GParted::display_partitions member (#227)
Now Win_GParted::m_display_device.partitions is an identical copy of
Win_GParted::display_partitions with the same lifetime.  That's wasteful
and pointless.  Therefore remove the later and use the former in it's
place.

Closes #227 - Unable to allocate 1 MiB between partitions when moving to
              the right
2023-04-27 15:54:01 +00:00
Mike Fleetwood e9f3977452 Use current Device object for Create and Paste dialogs too (#227)
The Create New and Paste dialogs also create partitions and have to
honour currently composed partitions while doing so.  Therefore they
must have a Device object containing the currently composed partition
layout for passing into snap_to_alignment() and below.  So copy the
current Device object when refreshing the visual at the same time
visual_partitions is generated and use in all 3 dialogs which compose
new partitions.

Note that Create New and Paste aren't subject to the same bug as Resize/
Move was because the code in snap_to_mebibyte() [1] checked the
partition object being composed has status STAT_REAL.  This is true for
partition objects created by the Resize/Move dialog, but not true for
the Create New and Paste dialogs which set status to STAT_NEW and
STAT_COPY respectively instead.

[1] Dialog_Base_Partition::snap_to_mebibyte() lines 418 to 438
    https://gitlab.gnome.org/GNOME/gparted/-/blob/GPARTED_1_5_0/src/Dialog_Base_Partition.cc#L418

Closes #227 - Unable to allocate 1 MiB between partitions when moving to
              the right
2023-04-27 15:54:01 +00:00
Mike Fleetwood 2dd0100811 Stop forcing 1 MiB gap when moving common partition boundary to the right (#227)
Start with 2 partitions next to each other, containing file systems that
GParted can move and resize.
EG:
    |[#1 ext2    ][#2 swap    ]    |

Move the start of partition #2 to the right.  Then attempt to move the
end of partition #1 to the right to meet it.
EG:
    |[#1 ext2       ][#2 swap ]    |

The Resize/Move dialog will allow the free space following to be set to
0 so partition #1 is again adjacent to partition #2, but after closing
the dialog a forced 1 MiB gap is added, shrinking the composed size of
partition #1 by that 1 MiB.

If instead the first operation to shrink and move partition #2 is
applied, then partition #1 can be successfully resize right up to
partition #2 without a 1 MiB gap.

Relevant call sequence:
    Win_GParted::activate_resize()
      Dialog_Partition_Resize_Move::Dialog_Partition_Resize_Move()
      Dialog_Base_Partition::Get_New_Partition()
        prepare_new_partition()
          snap_to_alignment()
            snap_to_mebibyte()

prepare_new_partition() created a new partition object to correctly
represent the resized/moved partition #1.  However this code in
snap_to_mebibyte() [1] determined that the new location for partition #1
overlapped with where partition #2 currently is on disk, not where
partition #2 will be after the previous operation is applied, therefore
it forced a 1 MiB decrease in partition #1's size creating the gap.
This is because snap_to_mebibyte() is working with the on disk view of
the partitions obtained from devices[current_device] passed into the
Dialog_Partition_Resize_Move() constructor.  Hence why applying the
operations one at a time doesn't suffer from the forced 1 MiB gap.

Fix this by creating a copy of the current device object, replacing the
on disk partition layout with the composed partition layout as displayed
in the UI.  Then pass this into the Dialog_Partition_Resize_Move
constructor.

[1] Dialog_Base_Partition::snap_to_mebibyte() lines 418 to 438
    https://gitlab.gnome.org/GNOME/gparted/-/blob/GPARTED_1_5_0/src/Dialog_Base_Partition.cc#L418

Closes #227 - Unable to allocate 1 MiB between partitions when moving to
              the right
2023-04-27 15:54:01 +00:00
Asier Sarasua Garmendia ab76e5cf36 Update Basque translation 2023-04-09 05:51:35 +00:00
Sabri Ünal ac1258a8d8 Update Turkish translation 2023-03-12 05:48:43 +00:00
Fabio Tomat f56b3b6b1b Update Friulian translation 2023-03-07 08:16:29 +00:00
Balázs Úr 85d97a2244 Update Hungarian translation 2023-02-28 00:55:03 +00:00
Aurimas Černius b3791b0ec7 Update Lithuanian translation 2023-02-26 20:38:59 +00:00
Fabio Tomat 611a67248a Update Friulian translation 2023-02-26 20:14:26 +00:00
Dušan Kazik bd3ef8b8ad Update Slovak translation 2023-02-24 16:45:43 +00:00
Curtis Gedak 32b0d32474 Append -git to version for continuing development 2023-02-21 10:40:48 -07:00
Curtis Gedak 489b428dfe ========== gparted-1.5.0 ========== 2023-02-21 10:14:32 -07:00
Curtis Gedak 8563d331d3 Update copyright years 2023-02-21 10:07:52 -07:00
Mike Fleetwood 0f1fde850f Resolve compiler warning from gen_password()
More recent g++ versions produce these warnings:
    test_PasswordRAMStore.cc: In member function ‘virtual void GParted::PasswordRAMStoreTest_TotalErasure_Test::TestBody()’:
    test_PasswordRAMStore.cc:61:32: warning: ‘                    ’ directive output truncated writing 20 bytes into a region of size 10 [-Wformat-truncation=]
      snprintf( buf, sizeof( buf ), "password%03u                    ", i );
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    test_PasswordRAMStore.cc:61:10: note: ‘snprintf’ output 32 bytes into a destination of size 21
      snprintf( buf, sizeof( buf ), "password%03u                    ", i );
      ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

snprintf() [1] truncates the printed string to the specified size so
didn't overflow the buffer.  However clear the warning by making the
formatted string always exactly 20 characters long, followed by the
terminating NUL character to exactly fill the buffer.

[1] print3(f) - Linux manual page
    https://man7.org/linux/man-pages/man3/snprintf.3.html
    "The functions snprintf() and vsnprintf() write at most size bytes
    (including the terminating null byte ('\0')) to str.
    "
2023-02-13 16:33:57 +00:00
Mike Fleetwood 230f44a9b4 Use Automake noinst_HEADERS to list GParted header files
Using Automake variable EXTRA_DIST [1] to list the GParted header files
seems overly general.  Instead use noinst_HEADERS [2] as it better
describes GParted header files.  Header files which need to be
distributed in the archive, but not part of an installed library so not
to be installed below /usr/include.

[1] GNU Automake manual, 14.1 Basics of Distribution
    https://www.gnu.org/software/automake/manual/html_node/Basics-of-Distribution.html
        "..., it is still common to have files to be distributed which
        are not found by the automatic rules.  You should listed these
        files in the EXTRA_DIST variable.  You can mention files in
        subdirectories in EXTRA_DIST.
        "

[2] GNU Automake manual, 9.2 Header files
    https://www.gnu.org/software/automake/manual/html_node/Headers.html
        "Usually, only header files that accompany installed libraries
        need to be installed.  Headers used by programs or convenience
        libraries are not installed.  The noinst_HEADERS variable can be
        used for such headers.  However, when the header belongs to a
        single convenience library or program, we recommend listing it
        in the program's or library's _SOURCES variable (see Defining
        program sources) instead of in noinst_HEADERS.  This is clearer
        for the Makefile.am reader.  noinst_HEADERS would be the right
        variable to use in a directory containing only headers and no
        associated library or program.

        All header files must be listed somewhere; in a _SOURCES
        variable or in a _HEADERS variable.  Missing ones will not
        appear in the distribution.
        "
2023-02-13 16:33:57 +00:00
Mike Fleetwood 62305ecb45 Replace fragment of unit test code with trim_trailing_new_line() 2023-02-13 16:33:57 +00:00
Mike Fleetwood ad434bb651 Use libparted geometry to bound writing in erase_filesystem_signatures()
The code in erase_filesystem_signatures() used libparted
ped_device_write() which allowed any sector in the whole disk device to
be written.  The code only depended on calculations of somewhat
complicated zero offset ranges and the start partition offset to ensure
that it didn't zero sectors outside the target partition.  The code
doesn't overwrite partition boundaries, but there have been updates and
bug fixes to the calculation code.  To improve the safety create a
libparted geometry representing the partition, or whole disk device,
to be cleared and use ped_geometry_write() so that libparted enforces
writes are only within the partition boundary being erased.

Deliberately breaking erase_filesystem_signatures() code so that it
tries to write past the end of the partition produces this dialog:

                        Libparted Error
    (-) Attempt to write sectors 1024000-1024007 outside of
        partition on /dev/sdb.
                                      [ Cancel ] [ Ignore ]

And trying to write before the start of the partition produces this
dialog:

                       Libparted Bug
    (-) Assert (offset >= 0) at cs/geom.c:375 in function
        ped_geometry_write() failed.
                                                   [ No ]

Followed by GParted aborting and producing a core dump.  Not ideal from
libparted, but it does prevent GParted writing outside the partition
boundaries and only occurs in the case of a bug in
erase_filesystem_signatures() which is exercised on every Create and
Format Partition operation and now also unit tested.  So not something
we will let through to the users.
2023-02-13 16:33:57 +00:00
Mike Fleetwood 5255a39137 Add unit test of erasing Promise FastTrack RAID signatures (#220)
Since the previous commit "Also erase all Promise FastTrack RAID
signatures" the previous failing IntelSoftwareRAIDUnaligned test now
passes along with the new PromiseFastTrackRaid* tests.
    $ ./test_EraseFileSystemSignatures
    Running main() from test_EraseFileSystemSignatures.cc
    DISPLAY=":0.0"
    [==========] Running 4 tests from 1 test case.
    [----------] Global test environment set-up.
    [----------] 4 tests from EraseFileSystemSignaturesTest
    [ RUN      ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDAligned
    [       OK ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDAligned (158 ms)
    [ RUN      ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDUnaligned
    [       OK ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDUnaligned (81 ms)
    [ RUN      ] EraseFileSystemSignaturesTest.PromiseFastTrackRAIDAligned
    [       OK ] EraseFileSystemSignaturesTest.PromiseFastTrackRAIDAligned (74 ms)
    [ RUN      ] EraseFileSystemSignaturesTest.PromiseFastTrackRAIDUnaligned
    [       OK ] EraseFileSystemSignaturesTest.PromiseFastTrackRAIDUnaligned (74 ms)
    [----------] 4 tests from EraseFileSystemSignaturesTest (387 ms total)

    [----------] Global test environment tear-down
    [==========] 4 tests from 1 test case ran. (387 ms total)
    [  PASSED  ] 4 tests.

Closes #220 - Format to Cleared not clearing "pdc" ataraid signature
2023-02-13 16:33:57 +00:00
Mike Fleetwood 1c97eedd11 Also erase all Promise FastTrack RAID signatures (#220)
User reported that GParted didn't clear a pdc (Promise FastTrack) RAID
signature [1].  Reproduce this issue by creating a 16 MiB - 512 byte
test image with Promise FastTrack RAID signatures at all recognised
offsets [2].
    $ python << 'EOF'
    signature = b'Promise Technology, Inc.'
    import os
    fd = os.open('/tmp/test.img', os.O_CREAT|os.O_WRONLY)
    os.ftruncate(fd, 16*1024*1024 - 512)
    for offset in [63, 255, 256, 16, 399, 591, 675, 735, 911, 974, 991, 951, 3087]:
        os.lseek(fd, -(offset*512), os.SEEK_END)
        os.write(fd, signature)
    os.close(fd)
    EOF

Then use GParted Format to > Cleared.
    $ sudo ./gpartedbin /tmp/test.img

Afterwards blkid, and therefore GParted, still recognises this as a
Promise FastTrack RAID member.
    $ blkid /tmp/test.img
    /tmp/test.img: TYPE="promise_fasttrack_raid_member"

This is because the test image still contains multiple signatures.
    $ hexdump -C /tmp/test.img | grep Promise
    00e7e000  50 72 6f 6d 69 73 65 20  54 65 63 ...  |Promise Technolo|
    00fce000  50 72 6f 6d 69 73 65 20  54 65 63 ...  |Promise Technolo|
    00fdfe00  50 72 6f 6d 69 73 65 20  54 65 63 ...  |Promise Technolo|
    00ff8000  50 72 6f 6d 69 73 65 20  54 65 63 ...  |Promise Technolo|

Used a test image not an exact multiple of MiBs because drives generally
aren't an exact MiB multiple in size either and as the clearing of ZFS
labels L2 and L3 by writes of zeros at the end of the drive is rounded
to 256 KiBs there will be sectors after that not zeroed where other
Promise signatures remain.  The above signatures map back to these
sectors before the end:
    16*1024*1024 - 512 = 16776704
                                    512b sectors   KiB
    (0x00e7e000 - 16776704) / 512 = -3087          -1543.5
    (0x00fce000 - 16776704) / 512 =  -399           -199.5
    (0x00fdfe00 - 16776704) / 512 =  -256           -128
    (0x00ff8000 - 16776704) / 512 =   -63           -31.5
Promise FastTrack RAID signatures are always at multiples 512-byte
sectors (code uses left shift 9 to convert from sectors to byte offset)
[2].

Fix this by:
1. Replace existing zeroing of 3 ranges relative to the end of the
   device to be a single range covering the ZFS labels L2 and L3 to the
   end of the drive.  This will also clear the SWRaid 0.90 & 1.0
   super blocks, the Nilfs2 secondary super block, the Intel Software
   RAID signature found not zeroed in the unaligned unit test case and
   the above Promise FastTrack RAID signatures at -199.5 KiB and later.
2. Add zeroing of the final Promise FastTrack RAID signature at sector
   -3087.

Performed a review of all the other ATARAID super blocks detected by
blkid (files *_raid.c) [3] and they are all located within the last 11
sectors so will be zeroed by case 1. above.

[1] GParted forum thread: How to remove a ataraid partition ?
    http://gparted-forum.surf4.info/viewtopic.php?id=18104

[2] blkid from util-linux promise_raid.c:probe_pdcraid()
    https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/libblkid/src/superblocks/promise_raid.c?h=v2.38.1#n27

[3] blkid RAID member detection (files *_raid.c)
    https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/libblkid/src/superblocks/?h=v2.38.1

Closes #220 - Format to Cleared not clearing "pdc" ataraid signature
2023-02-13 16:33:57 +00:00
Mike Fleetwood 3dfc7ef4e4 Speed up signature erasing unit test in Alpine Linux CI test job (#220)
Each test in test_EraseFileSystemSignatures is taking just over 10
seconds to run in the Alpine Linux CI image:
    [ RUN      ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDAligned
    [       OK ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDAligned (10045 ms)
    [ RUN      ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDUnaligned
    ...
    [  FAILED  ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDUnaligned (10048 ms)
    [----------] 2 tests from EraseFileSystemSignaturesTest (20093 ms total)

    [----------] Global test environment tear-down
    [==========] 2 tests from 1 test case ran. (20093 ms total)

This is because the udevadm command is not found and so settle_device()
waits for 10 seconds in this call chain:
    erase_filesystem_signatures()
      settle_device(SETTLE_DEVICE_APPLY_MAX_WAIT_SECONDS)
        sleep(10)

Install udevadm command into the Alpine Linux CI job docker image to fix
this.  Now it's on a par with the time taken in the other distro CI test
jobs:
    [ RUN      ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDAligned
    [       OK ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDAligned (417 ms)
    [ RUN      ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDUnaligned
    ...
    [  FAILED  ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDUnaligned (165 ms)
    [----------] 2 tests from EraseFileSystemSignaturesTest (582 ms total)

    [----------] Global test environment tear-down
    [==========] 2 tests from 1 test case ran. (582 ms total)

Closes #220 - Format to Cleared not clearing "pdc" ataraid signature
2023-02-13 16:33:57 +00:00
Mike Fleetwood 8ec302e1b0 Move duplicated test code into shared modules (#220)
Move common testing code which doesn't need linking with GParted objects
into the common module.  Move the remaining common code used to print
GParted objects using the insertion operator (operator<<) into the
insertion_operators module.  Split the common code like this so that the
operator<<(std::ostream&, const OperationDetail&) function is not
included in test_PipeCapture and it is not forced to link with all the
non-UI related GParted objects.

The Automake manual provides guidance that when a header belongs to a
single program it is recommended to be listed in the program's _SOURCES
variable and for a directory only containing header files listing them
in the noinst_HEADERS variable is the right variable to use [1].
However the guidance doesn't cover this case for common.h and
insertion_operators.h; header files in a directory with other files and
used by multiple programs.  So just because we have gparted_core_OBJECTS
(normal Makefile, not Automake special variable) listing objects to link
with, choose to use noinst_HEADERS Automake variable to list needed
headers.

[1] GNU Automake manual, 9.2 Header files
    https://www.gnu.org/software/automake/manual/html_node/Headers.html
        "Usually, only header files that accompany installed libraries
        need to be installed.  Headers used by programs or convenience
        libraries are not installed.  The noinst_HEADERS variable can be
        used for such headers.  However, when the header belongs to a
        single convenience library or program, we recommend listing it
        in the program's or library's _SOURCES variable (see Defining
        program sources) instead of in noinst_HEADERS.  This is clearer
        for the Makefile.am reader.  noinst_HEADERS would be the right
        variable to use in a directory containing only headers and no
        associated library or program.

        All header files must be listed somewhere; in a _SOURCES
        variable or in a _HEADERS variable.  Missing ones will not
        appear in the distribution.
        "

Closes #220 - Format to Cleared not clearing "pdc" ataraid signature
2023-02-13 16:33:57 +00:00
Mike Fleetwood 4ce37d4fde Add initial unit test of erase_filesystem_signatures() (#220)
Initially just testing erasing of Intel Software RAID signatures.
Chosen because it was expected to work, but turned out not to be true in
all cases.

The code needs to initialise GParted_Core::mainthread, construct
Gtk::Main() and execute xvfb-run because of this call chain:
    GParted_Core::erase_filesystem_signatures()
      GParted_Core::settle_device()
        Utils::execute_command ("udevadm settle ...")
          status.foreground = (Glib::Thread::self() == GParted_Core::mainthread)
          Gtk::Main::run()
This was also needed when testing file system interface classes as
discussed in commits [1][2].

The test fails like this:
    $ ./test_EraseFileSystemSignatures
    ...
    [ RUN      ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDAligned
    [       OK ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDAligned (155 ms)
    [ RUN      ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDUnaligned
    test_EraseFileSystemSignatures.cc:286: Failure
    Failed
    image_contains_all_zeros(): First non-zero bytes:
    0x00001A00  "Intel Raid ISM C"  49 6E 74 65 6C 20 52 61 69 64 20 49 53 4D 20 43
    test_EraseFileSystemSignatures.cc:320: Failure
    Value of: image_contains_all_zeros()
      Actual: false
    Expected: true
    [  FAILED  ] EraseFileSystemSignaturesTest.IntelSoftwareRAIDUnaligned (92 ms)

Manually write the same test image:
    $ python << 'EOF'
    signature = b'Intel Raid ISM Cfg Sig. '
    import os
    fd = os.open('/tmp/test.img', os.O_CREAT|os.O_WRONLY)
    os.ftruncate(fd, 16*1024*1024 - 512)
    os.lseek(fd, -(2*512), os.SEEK_END)
    os.write(fd, signature)
    os.close(fd)
    EOF

Run gpartedbin /tmp/test.img and Format to > Cleared.  GParted continues
to display the the image file as containing an ataraid signature.
    $ blkid /tmp/test.img
    /tmp/test.img: TYPE="isw_raid_member"
    $ hexdump -C /tmp/test.img
    00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00fffa00  49 6e 74 65 6c 20 52 61  69 64 20 49 53 4d 20 43  |Intel Raid ISM C|
    00fffa10  66 67 20 53 69 67 2e 20  00 00 00 00 00 00 00 00  |fg Sig. ........|
    00fffa20  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    *
    00fffe00

This signature is not being cleared when the device/partition/image size
is 512 bytes smaller than a whole MiB because the last 3.5 KiB is left
unwritten.  This is because the last block of zeros written is 8 KiB
aligned to 4 KiB at the end of the device.

[1] a97c23c57c
    Add initial create ext2 only FileSystem interface class test (!49)
[2] 8db9a83b39
    Run test program under xvfb-run to satisfy need for an X11 display (!49)

Closes #220 - Format to Cleared not clearing "pdc" ataraid signature
2023-02-13 16:33:57 +00:00
Jordi Mas i Hernandez 1d92c7aab9 Update Catalan translation 2023-01-29 12:56:35 +00:00