Use btrfs filesystem label to read the FS label (!105)
Until now GParted has run 'btrfs filesystem show' to read the file system label. This has a number of issues and limitations: 1. Doesn't work on a file system image so can't be unit tested in the GitLab CI test job where a loop device can't be created [1] or as a non-root user. 2. Reported failed exit status 1 when successfully showing a mounted btrfs, but only when using btrfs-progs v3.14 and 3.14.1 [2][3]. 3. Failed to distinguish between label set to "none" and no label reported as none, but only when mounted and with btrfs-progs v3.12 [3]. As non-root user run btrfs read label unit test: $ tests/test_SupportedFileSystems --gtest_filter='*CreateAndReadLabel/btrfs' ... [ RUN ] My/SupportedFileSystemsTest.CreateAndReadLabel/btrfs test_SupportedFileSystem.cc:539: Skip test. Not root to be able to create required loop device [ OK ] My/SupportedFileSystemsTest.CreateAndReadLabel/btrfs (0 ms) Even as root, 'btrfs filesystem show' fails to work on an image file: # truncate -s 256M /tmp/test.img # mkfs.btrfs /tmp/test.img # btrfs filesystem show /tmp/test.img ERROR: not a valid btrfs filesystem: /tmp/test.img # echo $? 1 # rm /tmp/test.img Instead use 'btrfs filesystem label' to read the label. It also works on an image file, the exit status is informative and output is just the label followed by a new line character [4] so very simple to parse. Error case: $ truncate -s 256M /tmp/test.img $ btrfs filesystem label /tmp/test.img No valid Btrfs found on /tmp/test.img $ echo $? 255 No label case: $ mkfs.btrfs /tmp/test.img $ btrfs filesystem label /tmp/test.img $ echo $? 0 $ btrfs filesystem label /tmp/test.img | hexdump -C 00000000 0a |.| 00000001 Label case: $ mkfs.btrfs -L 'label with > new line and trailing space ' /tmp/test.img $ btrfs filesystem label /tmp/test.img label with new line and trailing space $ echo $? 0 $ btrfs filesystem label /tmp/test.img | hexdump -C 00000000 6c 61 62 65 6c 20 77 69 74 68 0a 6e 65 77 20 6c |label with.new l| 00000010 69 6e 65 20 61 6e 64 20 74 72 61 69 6c 69 6e 67 |ine and trailing| 00000020 20 73 70 61 63 65 20 0a | space .| 00000028 Run 'btrfs filesystem label' always passing the block device as this works for both mounted and unmounted file systems. This is in contrast to writing the label for a mounted btrfs where the mount mount must be used [5]. # mkfs.btrfs -L 'test label' /dev/sdb1 # btrfs filesystem label /dev/sdb1 test label # mount /dev/sdb1 /mnt/1 # btrfs filesystem label /dev/sdb1 test label [1]07ad43a107
Create loop devices for BTRFS read file system interface tests (!49) [2]82c6265fa5
Update parsing of btrfs filesystem show for the UUID (#733601) [3]eca732fb0c
Update parsing of btrfs filesystem show for the label (#733601) [4] btrfs-progs v3.14, cmd_label() function https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git/tree/cmds-filesystem.c?h=v3.14#n984 [5]eb034b1759
Add labelling of mounted btrfs (#163) Closes !105 - Update used btrfs file system commands, new minimum is btrfs-progs 4.5
This commit is contained in:
parent
f30317477a
commit
ee823b0be4
45
src/btrfs.cc
45
src/btrfs.cc
|
@ -20,8 +20,10 @@
|
|||
#include "FileSystem.h"
|
||||
#include "Mount_Info.h"
|
||||
#include "Partition.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <glibmm/ustring.h>
|
||||
#include <glibmm/miscutils.h>
|
||||
#include <glibmm/shell.h>
|
||||
|
||||
|
@ -341,40 +343,29 @@ bool btrfs::resize( const Partition & partition_new, OperationDetail & operation
|
|||
return success ;
|
||||
}
|
||||
|
||||
void btrfs::read_label( Partition & partition )
|
||||
|
||||
void btrfs::read_label(Partition& partition)
|
||||
{
|
||||
Utils::execute_command("btrfs filesystem show " + Glib::shell_quote(partition.get_path()),
|
||||
output, error, true);
|
||||
//In many cases the exit status doesn't reflect valid output or an error condition
|
||||
// so rely on parsing the output to determine success.
|
||||
|
||||
if ( output .compare( 0, 18, "Label: none uuid:" ) == 0 )
|
||||
exit_status = Utils::execute_command("btrfs filesystem label " + Glib::shell_quote(partition.get_path()),
|
||||
output, error, true);
|
||||
if (exit_status != 0)
|
||||
{
|
||||
//Indistinguishable cases of either no label or the label is actually set
|
||||
// to "none". Assume no label case.
|
||||
partition.set_filesystem_label( "" );
|
||||
if (! output.empty())
|
||||
partition.push_back_message(output);
|
||||
if (! error.empty())
|
||||
partition.push_back_message(error);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try matching a label enclosed in single quotes, then without quotes, to
|
||||
// handle reporting of mounted file systems by old btrfs-progs 3.12.
|
||||
Glib::ustring label = Utils::regexp_label( output, "^Label: '(.*)' uuid:" ) ;
|
||||
if ( label .empty() )
|
||||
label = Utils::regexp_label( output, "^Label: (.*) uuid:" ) ;
|
||||
|
||||
if ( ! label .empty() )
|
||||
partition.set_filesystem_label( label );
|
||||
else
|
||||
{
|
||||
if ( ! output .empty() )
|
||||
partition.push_back_message( output );
|
||||
// Strip terminating new line from output.
|
||||
size_t len = output.length();
|
||||
if (len > 0 && output[len-1] == '\n')
|
||||
output.resize(len-1);
|
||||
|
||||
if ( ! error .empty() )
|
||||
partition.push_back_message( error );
|
||||
}
|
||||
}
|
||||
partition.set_filesystem_label(output);
|
||||
}
|
||||
|
||||
|
||||
void btrfs::read_uuid( Partition & partition )
|
||||
{
|
||||
Utils::execute_command("btrfs filesystem show " + Glib::shell_quote(partition.get_path()),
|
||||
|
|
Loading…
Reference in New Issue