Ensure blkid FS_Info cache has entries for all whole disk devices (#771244)
More recent versions of blkid don't report an ISO9660 file system on the whole disk device if partitions can be reports for embedded partitions. However when querying the whole disk device directly then the expected ISO9660 file system is reported. For example on CentOS 7 with the previous ISO images: # wget http://git.kernel.org/cgit/utils/util-linux/util-linux.git/plain/tests/ts/isosize/sample.iso.gz # dd if=/dev/zero bs=1M of=/dev/sdc # zcat sample.iso.gz | dd of=/dev/sdc # blkid -v blkid from util-linux 2.23.2 (libblkid 2.23.0, 25-Apr-2013) # blkid | fgrep /dev/sdc /dev/sdc1: UUID="2013-01-04-22-05-45-00" LABEL="ARCH_201301" TYPE="iso9660" PTTYPE="dos" # blkid /dev/sdc /dev/sdc: UUID="2013-01-04-22-05-45-00" LABEL="ARCH_201301" TYPE="iso9660" PTTYPE="dos" # wget http://cdimage.debian.org/debian-cd/8.6.0/amd64/iso-cd/debian-8.6.0-amd64-netinst.iso # dd if=/dev/zero bs=1M of=/dev/sdc # dd if=debian-8.6.0-amd64-netinst.iso bs=1M of=/dev/sdc # blkid | fgrep /dev/sdc /dev/sdc1: UUID="2016-09-17-14-23-48-00" LABEL="Debian 8.6.0 amd64 1" TYPE="iso9660" PTTYPE="dos" /dev/sdc2: SEC_TYPE="msdos" UUID="17F3-1162" TYPE="vfat" # blkid /dev/sdc /dev/sdc: UUID="2016-09-17-14-23-48-00" LABEL="Debian 8.6.0 amd64 1" TYPE="iso9660" PTTYPE="dos" This behavioural difference with blkid is probably as a result of newer versions of udev informing the kernel of the partitions embedded within the ISO9660 image, and not directly as a result of a change in blkid itself. Older distributions don't have partition entries for the above ISO images, but CentOS 7 (with udev 219) and later distributions do have partition entries: # fgrep sdc /proc/partitions 8 16 8388608 sdc 8 17 252928 sdc1 8 18 416 sdc2 Fix by ensuring that the blkid FS_Info cache has entries for whole disk devices, even if each entry has all empty attributes because there is a partition table and not a recognised file system. Calling blkid on whole disk devices containing partition tables produces output like this, with newer versions of blkid: # blkid /dev/sda /dev/sda: PTTYPE="dos" # blkid /dev/sdb /dev/sdb: PTTYPE="gpt" This will be loaded into the FS_Info cache as a blank entry for the device by run_blkid_load_cache(). There will be a path name but all the other attributes will be blank because there are no TYPE, SEC_TYPE, UUID or LABEL name value pairs. With older versions of blkid no output is produced at all. In that case load_fs_info_cache_extra_for_path() will create the same blank entry with just the path name defined. Bug 771244 - gparted does not recognize the iso9660 file system in cloned Ubuntu USB boot drives
This commit is contained in:
parent
683dc9d1ab
commit
b2190372d0
|
@ -48,8 +48,10 @@ public:
|
||||||
private:
|
private:
|
||||||
static void initialize_if_required();
|
static void initialize_if_required();
|
||||||
static void set_commands_found();
|
static void set_commands_found();
|
||||||
static void load_fs_info_cache();
|
|
||||||
static const FS_Entry & get_cache_entry_by_path( const Glib::ustring & path );
|
static const FS_Entry & get_cache_entry_by_path( const Glib::ustring & path );
|
||||||
|
static void load_fs_info_cache();
|
||||||
|
static void load_fs_info_cache_extra_for_path( const Glib::ustring & path );
|
||||||
|
static bool run_blkid_load_cache( const Glib::ustring & path = "" );
|
||||||
|
|
||||||
static bool fs_info_cache_initialized ;
|
static bool fs_info_cache_initialized ;
|
||||||
static bool blkid_found ;
|
static bool blkid_found ;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "FS_Info.h"
|
#include "FS_Info.h"
|
||||||
#include "BlockSpecial.h"
|
#include "BlockSpecial.h"
|
||||||
|
#include "Proc_Partitions_Info.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <glibmm/ustring.h>
|
#include <glibmm/ustring.h>
|
||||||
|
@ -158,12 +159,55 @@ void FS_Info::set_commands_found()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FS_Entry & FS_Info::get_cache_entry_by_path( const Glib::ustring & path )
|
||||||
|
{
|
||||||
|
BlockSpecial bs = BlockSpecial( path );
|
||||||
|
for ( unsigned int i = 0 ; i < fs_info_cache.size() ; i ++ )
|
||||||
|
if ( bs == fs_info_cache[i].path )
|
||||||
|
return fs_info_cache[i];
|
||||||
|
|
||||||
|
static FS_Entry not_found = {BlockSpecial(), "", "", "", false, ""};
|
||||||
|
return not_found;
|
||||||
|
}
|
||||||
|
|
||||||
void FS_Info::load_fs_info_cache()
|
void FS_Info::load_fs_info_cache()
|
||||||
{
|
{
|
||||||
fs_info_cache.clear();
|
fs_info_cache.clear();
|
||||||
|
// Run "blkid" and load entries into the cache.
|
||||||
|
run_blkid_load_cache();
|
||||||
|
|
||||||
// Parse blkid output line by line extracting fields mandatory field path and
|
// (#771244) Ensure the cache has entries for all whole disk devices, even if
|
||||||
// optional fields: type, sec_type, uuid, label.
|
// those entries are blank. Needed so that an ISO9660 image stored on a whole
|
||||||
|
// disk device is detected before any embedded partitions within the image.
|
||||||
|
const BlockSpecial empty_bs = BlockSpecial();
|
||||||
|
std::vector<Glib::ustring> all_devices = Proc_Partitions_Info::get_device_paths();
|
||||||
|
for ( unsigned int i = 0 ; i < all_devices.size() ; i ++ )
|
||||||
|
{
|
||||||
|
const FS_Entry & fs_entry = get_cache_entry_by_path( all_devices[i] );
|
||||||
|
if ( fs_entry.path == empty_bs )
|
||||||
|
{
|
||||||
|
// Run "blkid PATH" and load entry into cache for missing entries.
|
||||||
|
load_fs_info_cache_extra_for_path( all_devices[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FS_Info::load_fs_info_cache_extra_for_path( const Glib::ustring & path )
|
||||||
|
{
|
||||||
|
bool entry_added = run_blkid_load_cache( path );
|
||||||
|
if ( ! entry_added )
|
||||||
|
{
|
||||||
|
// Ran "blkid PATH" but didn't find details suitable for loading as a
|
||||||
|
// cache entry so add a blank entry for PATH name here.
|
||||||
|
FS_Entry fs_entry = {BlockSpecial( path ), "", "", "", false, ""};
|
||||||
|
fs_info_cache.push_back( fs_entry );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FS_Info::run_blkid_load_cache( const Glib::ustring & path )
|
||||||
|
{
|
||||||
|
// Parse blkid output line by line extracting mandatory field: path and optional
|
||||||
|
// fields: type, sec_type, uuid, label.
|
||||||
// Example output:
|
// Example output:
|
||||||
// /dev/sda1: UUID="f828ee8c-1e16-4ca9-b234-e4949dcd4bd1" TYPE="xfs"
|
// /dev/sda1: UUID="f828ee8c-1e16-4ca9-b234-e4949dcd4bd1" TYPE="xfs"
|
||||||
// /dev/sda2: UUID="p31pR5-qPLm-YICz-O09i-sB4u-mAH2-GVSNWG" TYPE="LVM2_member"
|
// /dev/sda2: UUID="p31pR5-qPLm-YICz-O09i-sB4u-mAH2-GVSNWG" TYPE="LVM2_member"
|
||||||
|
@ -173,20 +217,24 @@ void FS_Info::load_fs_info_cache()
|
||||||
// /dev/sdb1: LABEL="test-ext3" UUID="f218c3b8-237e-4fbe-92c5-76623bba4062" SEC_TYPE="ext2" TYPE="ext3" PARTUUID="71b3e059-30c5-492e-a526-9251dff7bbeb"
|
// /dev/sdb1: LABEL="test-ext3" UUID="f218c3b8-237e-4fbe-92c5-76623bba4062" SEC_TYPE="ext2" TYPE="ext3" PARTUUID="71b3e059-30c5-492e-a526-9251dff7bbeb"
|
||||||
// /dev/sdb2: SEC_TYPE="msdos" LABEL="TEST-FAT16" UUID="9F87-1061" TYPE="vfat" PARTUUID="9d07ad9a-d468-428f-9bfd-724f5efae4fb"
|
// /dev/sdb2: SEC_TYPE="msdos" LABEL="TEST-FAT16" UUID="9F87-1061" TYPE="vfat" PARTUUID="9d07ad9a-d468-428f-9bfd-724f5efae4fb"
|
||||||
// /dev/sdb3: PARTUUID="bb8438e1-d9f1-45d3-9888-e990b598900d"
|
// /dev/sdb3: PARTUUID="bb8438e1-d9f1-45d3-9888-e990b598900d"
|
||||||
|
Glib::ustring cmd = "blkid";
|
||||||
|
if ( path.size() )
|
||||||
|
cmd = cmd + " " + path;
|
||||||
Glib::ustring output;
|
Glib::ustring output;
|
||||||
Glib::ustring error;
|
Glib::ustring error;
|
||||||
if ( blkid_found &&
|
bool loaded_entries = false;
|
||||||
! Utils::execute_command( "blkid", output, error, true ) )
|
if ( blkid_found &&
|
||||||
|
! Utils::execute_command( cmd, output, error, true ) )
|
||||||
{
|
{
|
||||||
std::vector<Glib::ustring> lines;
|
std::vector<Glib::ustring> lines;
|
||||||
Utils::split( output, lines, "\n" );
|
Utils::split( output, lines, "\n" );
|
||||||
for ( unsigned int i = 0 ; i < lines.size() ; i ++ )
|
for ( unsigned int i = 0 ; i < lines.size() ; i ++ )
|
||||||
{
|
{
|
||||||
FS_Entry fs_entry = {BlockSpecial(), "", "", "", false, ""};
|
FS_Entry fs_entry = {BlockSpecial(), "", "", "", false, ""};
|
||||||
Glib::ustring path = Utils::regexp_label( lines[i], "^(.*): " );
|
Glib::ustring entry_path = Utils::regexp_label( lines[i], "^(.*): " );
|
||||||
if ( path.length() > 0 )
|
if ( entry_path.length() > 0 )
|
||||||
{
|
{
|
||||||
fs_entry.path = BlockSpecial( path );
|
fs_entry.path = BlockSpecial( entry_path );
|
||||||
fs_entry.type = Utils::regexp_label( lines[i], " TYPE=\"([^\"]*)\"" );
|
fs_entry.type = Utils::regexp_label( lines[i], " TYPE=\"([^\"]*)\"" );
|
||||||
fs_entry.sec_type = Utils::regexp_label( lines[i], " SEC_TYPE=\"([^\"]*)\"" );
|
fs_entry.sec_type = Utils::regexp_label( lines[i], " SEC_TYPE=\"([^\"]*)\"" );
|
||||||
fs_entry.uuid = Utils::regexp_label( lines[i], " UUID=\"([^\"]*)\"" );
|
fs_entry.uuid = Utils::regexp_label( lines[i], " UUID=\"([^\"]*)\"" );
|
||||||
|
@ -196,19 +244,12 @@ void FS_Info::load_fs_info_cache()
|
||||||
fs_entry.label = Utils::regexp_label( lines[i], " LABEL=\"([^\"]*)\"" );
|
fs_entry.label = Utils::regexp_label( lines[i], " LABEL=\"([^\"]*)\"" );
|
||||||
}
|
}
|
||||||
fs_info_cache.push_back( fs_entry );
|
fs_info_cache.push_back( fs_entry );
|
||||||
|
loaded_entries = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const FS_Entry & FS_Info::get_cache_entry_by_path( const Glib::ustring & path )
|
return loaded_entries;
|
||||||
{
|
|
||||||
for ( unsigned int i = 0 ; i < fs_info_cache.size() ; i ++ )
|
|
||||||
if ( path == fs_info_cache[i].path )
|
|
||||||
return fs_info_cache[i];
|
|
||||||
|
|
||||||
static FS_Entry not_found = {BlockSpecial(), "", "", "", false, ""};
|
|
||||||
return not_found;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}//GParted
|
}//GParted
|
||||||
|
|
|
@ -155,7 +155,8 @@ void GParted_Core::set_devices_thread( std::vector<Device> * pdevices )
|
||||||
// objects are created in the following caches.
|
// objects are created in the following caches.
|
||||||
Proc_Partitions_Info::load_cache(); // SHOULD BE SECOND. Caches /proc/partitions and
|
Proc_Partitions_Info::load_cache(); // SHOULD BE SECOND. Caches /proc/partitions and
|
||||||
// pre-populates BlockSpecial cache.
|
// pre-populates BlockSpecial cache.
|
||||||
FS_Info::load_cache();
|
FS_Info::load_cache(); // SHOULD BE THRID. Caches file system details
|
||||||
|
// from blkid output.
|
||||||
DMRaid dmraid( true ) ; //Refresh cache of dmraid device information
|
DMRaid dmraid( true ) ; //Refresh cache of dmraid device information
|
||||||
LVM2_PV_Info::clear_cache(); // Cache automatically loaded if and when needed
|
LVM2_PV_Info::clear_cache(); // Cache automatically loaded if and when needed
|
||||||
btrfs::clear_cache(); // Cache incrementally loaded if and when needed
|
btrfs::clear_cache(); // Cache incrementally loaded if and when needed
|
||||||
|
|
Loading…
Reference in New Issue