Commit Graph

4175 Commits

Author SHA1 Message Date
Mike Fleetwood f098ba1ec7 Stop using floating point calculations in FS resize() methods (!119)
A number of the file system specific resize() methods use floating point
calculations to convert from the new partition size in sectors to the
new file system size to be passed to the resize command in bytes or
kibibytes.  This is bad because there could be rounding errors
converting from integer to floating point, performing the calculation
and converting back.  Replace with integer only multiply and divide
calculations.  Integer division always truncates [1] which is exactly
what is needed.  The largest integer will be the size of the file system
in bytes held in a signed 64-bit long long, or Sector or Byte_Value
typedef of the same type.  This will limit the size that a file system
can be shrunk to, to 8 EiB - 1 byte.

[1] C++ Arithmetic operators
    https://en.cppreference.com/w/cpp/language/operator_arithmetic
        "the algebraic quotient of integer division is truncated towards
        zero (fractional part is discarded)"

Closes !119 -  Tidy-ups for file system interface classes
2023-10-29 15:50:43 +00:00
Sergej A 9ace657bb0 Update Russian translation 2023-10-22 16:02:03 +00:00
Florentina Mușat dc00b32260 Update Romanian translation 2023-10-21 12:29:03 +00:00
Anders Jonsson bbfec821ad Update Swedish translation 2023-10-19 11:32:28 +00:00
Alan Mortensen b5fb850dbb Update Danish translation 2023-10-12 15:24:22 +00:00
Yuri Chornoivan 78c1de74f1 Update Ukrainian translation 2023-10-05 17:43:34 +00:00
Mike Fleetwood 35e85e5b02 Write file system type as "[Encrypted] FSTYPE" to saved details
The GUI displays the file system of an open encrypted file system as
"[Encrypted] FSTYPE" [1].  However saved details just writes the file
system type as "luks".  Update saved details writing code to use the
same method the GUI currently uses [2].

[1] commit cb3cc505ce
    Display "[Encrypted] FSTYPE" in the File System column (#760080)

[2] commit bd6fc67afb
    Provide virtual Partition::get_filesystem_string() method (#774818)
2023-10-04 16:03:09 +00:00
Mike Fleetwood 1115fa2be8 Increment GParted Manual version 2023-10-04 16:03:09 +00:00
Mike Fleetwood 3d2dec2e11 Remove Attempt Data Rescue from the GParted Manual (!118)
Keep the paragraph discussing photorec and move just after testdisk is
mentioned in the Recovering Partition Tables section.

Closes !118 - Remove Attempt Data Rescue and use of gpart
2023-10-04 16:03:09 +00:00
Mike Fleetwood 8ce9074ac6 Remove Attempt Data Rescue and use of gpart (!118)
gpart scans a drive trying to guess the location of partitions when an
MBR partition table is lost [1].  However the tool is unmaintained,
takes hours or days of 100% CPU time to scan a drive and provides no
progress indication [2][3][4].  We keep recommending killing the gpart
process and using TestDisk [5] instead.

Therefore remove Device > Attempt Data Rescue and the use of gpart from
GParted.

[1] Gpart
    https://github.com/baruch/gpart
[2] Have you had a good or bad experience with Dev->Attempt Data Rescue?
    http://gparted-forum.surf4.info/viewtopic.php?id=17992
    No good, only bad experiences using gpart were reported.
[3] Gparted does not say anything
    http://gparted-forum.surf4.info/viewtopic.php?id=17749
    Forum user reported waiting 48 hours with no progress indication.
    We recommended using TestDisk.
[4] How cancel Data Rescue process?
    http://gparted-forum.surf4.info/viewtopic.php?id=18143
    Forum user reported it will take 3 days to scan their external 480GB
    drive.  We recommended using TestDisk instead.
[5] TestDisk, Data Recovery
    https://www.cgsecurity.org/wiki/TestDisk

Closes !118 - Remove Attempt Data Rescue and use of gpart
2023-10-04 16:03:09 +00:00
Mike Fleetwood 2febe04665 Replace deprecated Google Test API INSTANTIATE_TEST_CASE_P() (!117)
When compiling the tests, this warning is reported:

    $ make check
    ... warning: ...: INSTANTIATE_TEST_CASE_P is deprecated, please use INSTANTIATE_TEST_SUITE_P [-Wdeprecated-declarations]
       static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \
                                          ^
    test_SupportedFileSystems.cc:625:1: note: in expansion of macro 'INSTANTIATE_TEST_CASE_P'

Google Test 1.10.0 release notes [1] say:
    High Level Changes:
    This release deprecated "....TEST_CASE" API in favor of
    "....TEST_SUITE".  In a nutshell if you have code that uses
    something like "INSTANTIATE_TYPED_TEST_CASE_P " - this and all other
    "*_TEST_CASE " are now deprecated in favor of more standard
    _TEST_SUITE.

Replace the deprecated API with the new API.

[1] Google Test release v1.10.0
    https://github.com/google/googletest/releases/tag/release-1.10.0

Closes !117 - Require C++11 compilation
2023-09-23 15:30:15 +00:00
Mike Fleetwood 1ccb782156 Update to Google Test 1.10.0 (!117)
So far GParted includes Google Test 1.8.1 [1], which was the latest
release which supported pre-C++11 compilers [2].  Now that GParted
requires C++11 compilation, update to Google Test 1.10.0.  Replace the
following files and directories from Google Test 1.10.0:
    LICENSE
    README.md
    include/
    src/
Note the LICENSE file is identical, where as the other files have
changed.  This includes file additions and removals, hence the change
to Makefile.am too.

Even though Google Test releases up to and including 1.12.1 are
compilable with C++11 compilers [3], it is not possible to upgrade
beyond Google Test 1.10.0 at this time because later releases fail to
compile on on still supported RHEL / CentOS 7 with this error:

    $ cd lib/gtest
    $ make check
    ...
    ./include/gtest/gtest-matchers.h:414:12: error: 'is_trivially_copy_constructible' is not a member of 'std'
                std::is_trivially_copy_constructible<M>::value &&
                ^

This failure turns out to be because GCC libstdc++ 4.8.5 doesn't include
is_trivially_copy_constructible et al [4][5].

[1] commit 2b222978f5
    Update to Google Test 1.8.1
[2] Google Test release v1.8.1
    https://github.com/google/googletest/releases/tag/release-1.8.1
    "The 1.8.x is the last release supporting pre-C++11 compilers."
[3] Google Test release v1.12.1
    https://github.com/google/googletest/releases/tag/release-1.12.1
    "This will be the last release to support C++11.  Future releases
    will require at least C++14."
[4] 'is_trivially_copyable' is not a member of 'std'
    https://stackoverflow.com/questions/25123458/is-trivially-copyable-is-not-a-member-of-std/25123551#25123551
    "Some of them are not implemented.  If we look at libstdc++'s C++11
    status page:
    Type properties are listed as partially implemented.
    They list as missing:
    ...
    is trivially_copy_constructible
    "
[5] The GNU C++ Library, 1. Status, C++11
    https://gcc.gnu.org/onlinedocs/gcc-4.8.3/libstdc++/manual/manual/status.html#status.iso.2011
    "
    | Section  | Description     | Status  | Comments
    ...
    | 20.9.4.3 | Type properties | Partial | Missing
    is_trivially_copyable, is_trivially_constructible,
    is_trivially_default_constructible, is_trivially_copy_constructible,
    is_trivially_move_constructible, is_trivially_assignable,
    is_trivially_default_assignable, is_trivially_copy_assignable,
    is_trivially_move_assignable |
    "

Closes !117 - Require C++11 compilation
2023-09-23 15:30:15 +00:00
Mike Fleetwood 3b469273de C++11: Also convert NULL to nullptr in unit tests (!117)
Closes !117 - Require C++11 compilation
2023-09-23 15:30:15 +00:00
Mike Fleetwood 40665913bf C++11: Convert NULL to nullptr (!117)
In C++11, nullptr [1] is the strongly typed value to use instead of the
macro NULL [2].  Use everywhere [3][4].

[1] nullptr, the pointer literal (since C++11)
    https://en.cppreference.com/w/cpp/language/nullptr
[2] NULL
    https://en.cppreference.com/w/cpp/types/NULL
[3] Bjarne Stroustrup's C++ Style and Technique FAQ, Should I use NULL
    or 0?
    https://www.stroustrup.com/bs_faq2.html#null
        "In C++, the definition of NULL is 0, so there is only an
        aesthetic difference.  I prefer to avoid macros, so I use 0.
        Another problem with NULL is that people sometimes mistakenly
        believe that it is different from 0 and/or not an integer.  In
        pre-standard code, NULL was/is sometimes defined to something
        unsuitable and therefore had/has to be avoided.  That's less
        common these days.

        If you have to name the null pointer, call it nullptr; that's
        what it's called in C++11.  Then, "nullptr" will be a keyword.
        "
[4] What is nullptr in C++? Advantages, Use Cases & Examples
    https://favtutor.com/blogs/nullptr-cpp
        "Advantages of nullptr
        ...
        Compatible: Null pointers are compatible with null pointer
        constants in the C style (such as NULL and 0).  This implies
        that old C code that uses these constants and null pointers can
        communicate with each other in C++.
        "

Closes !117 - Require C++11 compilation
2023-09-23 15:30:15 +00:00
Mike Fleetwood 6bf7668f8e Increase minimum required gtkmm to 3.18.0 (!117)
As discussed in the previous commit the oldest supported distributions
now provide gtkmm versions higher that 3.18.0 (which requires C++11
compilation).  Therefore increase the minimum required version to gtkmm
3.18.0.  This allows removal of HAVE_LABEL_SET_XALIGN autoconf
definition and associated fallback code.

Closes !117 - Require C++11 compilation
2023-09-23 15:30:15 +00:00
Mike Fleetwood 9f473b70cb Always require C++11 compilation (!117)
All the oldest supported distributions now have versions of GTK C++
libraries which require C++11 compilation, therefore forcing GParted to
require C++11 compilation [1][2][3].  Fragment of existing ./configure
output which lists the library versions requiring C++11 compilation:

    $ ./configure
    ...
    checking for glibmm >= 2.45.40 which requires C++11 compilation... yes
    checking for libsigc++ >= 2.5.1 which requires C++11 compilation... yes
    checking for gtkmm >= 3.18.0 which requires C++11 compilation... yes
    checking whether g++ supports C++11 features with -std=gnu++11... yes

The oldest supported distributions and their versions of GTK C++
libraries and GCC compiler:

    Distribution        gtkmm    glibmm   libsigc++   gcc

    Debian 10           3.24.0   2.58.0   2.10.1      4.8.3
    RHEL / CentOS 7.9   3.22.2   2.56.0   2.10.0      4.8.5
    SLES 12 SP5         3.20.1   2.48.1   2.8.0       4.8
    Ubuntu 20.04 LTS    3.24.2   2.64.2   2.10.2      9.3.0

Technically GCC didn't have full C++11 support until GCC 4.8.1 [6] and
SLES 12 SP5 only has GCC 4.8 (as well as many later versions of GCC).
However which ever version of the GCC compiler is being used to compile
the GTK C++ libraries it must have all the features needed to compile
those libraries.

Simplify the configure script and just always require a C++11 capable
compiler.  This also allows the use of C++11 features in the GParted
code.

[1] commit cc0740148e
    port-to-gtk3: Switch to Gtkmm3 (#7)
[2] commit 707bae6fed
    Enable C++11 compilation when using libsigc++ 2.5.1 and later (#758545)
[3] commit d6d7cb2bbf
    Enable C++11 compilation when using glibmm 2.45.40 and later (#756035)
[4] SUSE Product Support Lifecycle, SUSE Linux Enterprise Server 12
    https://www.suse.com/lifecycle/#suse-linux-enterprise-server-12
[5] SUSE package search
    https://scc.suse.com/packages?name=SUSE%20Linux%20Enterprise%20Server&version=12.5&arch=x86_64&query=&module=
[6] C++ Standards Support in GCC, C++11 Support in GCC
    https://gcc.gnu.org/projects/cxx-status.html#cxx11

Closes !117 - Require C++11 compilation
2023-09-23 15:30:15 +00:00
Daniel Rusek 1e548c55a6 Update Czech translation 2023-09-03 21:18:40 +00:00
Luming Zh 1a021dc6a0 Update Chinese (China) translation 2023-09-02 15:08:05 +00:00
Danial Behzadi d17a061555 Update Persian translation 2023-08-28 09:38:03 +00:00
Baurzhan Muftakhidinov 81d67fdf78 Update Kazakh translation 2023-08-20 12:50:03 +00:00
Sabri Ünal be65404569 Update Turkish translation 2023-08-18 18:02:11 +00:00
Mike Fleetwood e8ba722643 Add missing .gitignore entry for test_EraseFileSystemSignatures 2023-08-15 17:04:30 +00:00
Mike Fleetwood 0ecb45e7b1 Also find system default udev rules in /usr/lib/udev/rules.d (!116)
When blanking of udev rules was first tested [1][2] and added [3] all
the distributions at the time (CentOS 6, Debian 6, Fedora 19,
openSUSE 12.2, Ubuntu 12.04 LTS) stored the system default rules in
directory /lib/udev/rules.d.  Now most distributions (CentOS Stream 9,
Debian 11, Fedora 38, Ubuntu 22.04 LTS, openSUSE Leap 15.4) store the
system default rules in directory /usr/lib/udev/rules.d.  Most of these
distributions have a merged /usr file system [4][5] so /lib is a symlink
to /usr/lib and the system default rules can still found using the
original directory.  But openSUSE 15.4 doesn't have a merged /usr so the
gparted shell wrapper doesn't find the system default rules in directory
/usr/lib/udev/rules.d and doesn't prevent auto starting of Linux
Software RAID arrays and bcache devices during a storage probe.

An extra consideration is that Alpine Linux 3.17 doesn't have a merged
/usr file system, but has both /lib/udev/rules.d and
/usr/lib/udev/rules.d directories with different rules files.  Therefore
fix this by checking for system default udev rules in both directories.

[1] Bug 709640 - Linux Swap Suspend and Software RAID partitions not
    recognised, comment 7
    https://bugzilla.gnome.org/show_bug.cgi?id=709640#c7
[2] Bug 709640 - Linux Swap Suspend and Software RAID partitions not
    recognised, comment 12
    https://bugzilla.gnome.org/show_bug.cgi?id=709640#c12
[3] a255abf343
    Prevent GParted starting stopped Linux Software RAID arrays (#709640)
[4] The Case for the /usr Merge
    http://0pointer.de/blog/projects/the-usr-merge
[5] The Case for the /usr Merge
    https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/

Closes !116 - Systemd mount masking and udev rule location updates
2023-08-15 17:04:30 +00:00
Mike Fleetwood 852816be70 Avoid masking/unmasking the empty list of mount units (!116)
After the previous commit "Stop masking the root file system mount
unit", GParted now reports this error to the terminal on Debian 10 and
11:
    # gparted
    To few arguments.
    GParted 1.5.0-git
    configuration --enable-online-resize
    libparted 3.2

Debian installations, at least on PC hardware and using BIOS booting so
they don't have a /boot/efi file system, only have a single file system,
/ (root).  That is now excluded from masking so gparted shell wrapper
runs systemctl without any mount units to mask.  Hence the error.
    # systemctl --runtime mask --quiet --
    Too few arguments.
    # echo $?
    1

Fix this by only masking and unmasking units when the list of mounts
is non-empty.

Closes !116 - Systemd mount masking and udev rule location updates
2023-08-15 17:04:30 +00:00
Mike Fleetwood 4dc683b261 Stop masking the root file system mount unit (!116)
Masking the root file system (-.mount) unit lead to a Debian package
upgrade failing as reported here [1].  This was fixed in systemd 245
[2][3] by not allowing perpetual units to be masked.  As the root file
system can't be mounted or unmounted while GParted is running, it
doesn't need to be prevented by masking the unit.  Therefore stop
masking the root file system mount unit.

[1] Debian bug #948710 -  handle masked .mount unit more gracefully
    https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=948710
[2] systemd issue #14550 - Handle masked .mount units more gracefully
    https://github.com/systemd/systemd/issues/14550
[3] core: never allow perpetual units to be masked
    88414eed6f

Closes !116 - Systemd mount masking and udev rule location updates
2023-08-15 17:04:30 +00:00
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