diff --git a/include/BlockSpecial.h b/include/BlockSpecial.h new file mode 100644 index 00000000..376e3b03 --- /dev/null +++ b/include/BlockSpecial.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2016 Mike Fleetwood + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + + +/* BlockSpecial + * + * Representation of a POSIX block special file, e.g. /dev/sda1. Also + * tracks the major, minor device numbers so that different names for + * the same block device can be compared equal. + * Refs: mknod(1) and mknod(2). + */ + +#ifndef GPARTED_BLOCKSPECIAL_H +#define GPARTED_BLOCKSPECIAL_H + +#include + +namespace GParted +{ + +class BlockSpecial +{ +public: + BlockSpecial(); + BlockSpecial( const Glib::ustring & name ); + ~BlockSpecial(); + + Glib::ustring m_name; // E.g. Block special file {"/dev/sda1", 8, 1}, + unsigned long m_major; // plain file {"FILENAME", 0, 0} and empty object + unsigned long m_minor; // {"", 0, 0}. +}; + +// Operator overloading > The Decision between Member and Non-member +// http://stackoverflow.com/questions/4421706/operator-overloading/4421729#4421729 +// "2. If a binary operator treats both operands equally (it leaves them unchanged), +// implement this operator as a non-member function." +bool operator==( const BlockSpecial & lhs, const BlockSpecial & rhs ); + +}//GParted + +#endif /* GPARTED_BLOCKSPECIAL_H */ diff --git a/include/LVM2_PV_Info.h b/include/LVM2_PV_Info.h index 25f0e1d1..37009475 100644 --- a/include/LVM2_PV_Info.h +++ b/include/LVM2_PV_Info.h @@ -25,14 +25,18 @@ #ifndef GPARTED_LVM2_PV_INFO_H #define GPARTED_LVM2_PV_INFO_H +#include "../include/BlockSpecial.h" #include "../include/Utils.h" +#include +#include + namespace GParted { struct LVM2_PV { - Glib::ustring pv_name; + BlockSpecial pv_name; Byte_Value pv_size; Byte_Value pv_free; Glib::ustring vg_name; diff --git a/include/Makefile.am b/include/Makefile.am index 61f722ed..32fc41c1 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,6 +1,7 @@ gparted_includedir = $(pkgincludedir) EXTRA_DIST = \ + BlockSpecial.h \ Copy_Blocks.h \ DMRaid.h \ Device.h \ diff --git a/po/POTFILES.in b/po/POTFILES.in index 3ef9bc21..63865aab 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -3,6 +3,7 @@ gparted.appdata.xml.in gparted.desktop.in.in include/Utils.h +src/BlockSpecial.cc src/Copy_Blocks.cc src/Dialog_Base_Partition.cc src/Dialog_Disklabel.cc diff --git a/src/BlockSpecial.cc b/src/BlockSpecial.cc new file mode 100644 index 00000000..1941b3f3 --- /dev/null +++ b/src/BlockSpecial.cc @@ -0,0 +1,55 @@ +/* Copyright (C) 2016 Mike Fleetwood + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "../include/BlockSpecial.h" + +#include +#include +#include +#include + +namespace GParted +{ + +BlockSpecial::BlockSpecial() : m_name( "" ), m_major( 0UL ), m_minor( 0UL ) +{ +} + +BlockSpecial::BlockSpecial( const Glib::ustring & name ) : m_name( name ), m_major( 0UL ), m_minor( 0UL ) +{ + struct stat sb; + if ( stat( name.c_str(), &sb ) == 0 && S_ISBLK( sb.st_mode ) ) + { + m_major = major( sb.st_rdev ); + m_minor = minor( sb.st_rdev ); + } +} + +BlockSpecial::~BlockSpecial() +{ +} + +bool operator==( const BlockSpecial & lhs, const BlockSpecial & rhs ) +{ + if ( lhs.m_major > 0UL && lhs.m_minor > 0UL ) + // Match block special files by major, minor device numbers. + return lhs.m_major == rhs.m_major && lhs.m_minor == rhs.m_minor; + else + // For non-block special files fall back to name string compare. + return lhs.m_name == rhs.m_name; +} + +} //GParted diff --git a/src/LVM2_PV_Info.cc b/src/LVM2_PV_Info.cc index 07c676cc..98a98b72 100644 --- a/src/LVM2_PV_Info.cc +++ b/src/LVM2_PV_Info.cc @@ -15,6 +15,7 @@ */ #include "../include/LVM2_PV_Info.h" +#include "../include/BlockSpecial.h" namespace GParted { @@ -37,13 +38,13 @@ enum LV_BIT // lvm_found - Is the "lvm" command available? // lvm2_pv_cache - Vector of PV fields: pv_name, pv_size, pv_free, vg_name. // E.g. -// //pv_name , pv_size , pv_free , vg_name -// [{"/dev/sda10", 1073741824, 1073741824, "" }, -// {"/dev/sda11", 1069547520, 1069547520, "Test-VG1"}, -// {"/dev/sda12", 1069547520, 335544320, "Test_VG2"}, -// {"/dev/sda13", 1069547520, 0, "Test_VG3"}, -// {"/dev/sda14", 1069547520, 566231040, "Test_VG3"}, -// {"/dev/sda15", 1069547520, 545259520, "Test-VG4"} +// //pv_name , pv_size , pv_free , vg_name +// [{BlockSpecial("/dev/sda10"), 1073741824, 1073741824, "" }, +// {BlockSpecial("/dev/sda11"), 1069547520, 1069547520, "Test-VG1"}, +// {BlockSpecial("/dev/sda12"), 1069547520, 335544320, "Test_VG2"}, +// {BlockSpecial("/dev/sda13"), 1069547520, 0, "Test_VG3"}, +// {BlockSpecial("/dev/sda14"), 1069547520, 566231040, "Test_VG3"}, +// {BlockSpecial("/dev/sda15"), 1069547520, 545259520, "Test-VG4"} // ] // lvm2_vg_cache - Vector storing VG fields: vg_name, vg_attr, lv_name, lv_attr. // See vgs(8) and lvs(8) for details of vg_attr and lv_attr respectively. @@ -145,7 +146,7 @@ std::vector LVM2_PV_Info::get_vg_members( const Glib::ustring & v { if ( vgname == lvm2_pv_cache[i].vg_name ) { - members.push_back( lvm2_pv_cache[i].pv_name ); + members.push_back( lvm2_pv_cache[i].pv_name.m_name ); } } @@ -252,10 +253,10 @@ void LVM2_PV_Info::load_lvm2_pv_info_cache() Utils::split( Utils::trim( lines[i] ), fields, "," ); if ( fields.size() < PVFIELD_COUNT ) continue; // Not enough fields - LVM2_PV pv; - pv.pv_name = fields[PVFIELD_PV_NAME]; - if ( pv.pv_name.size() == 0 ) + if ( fields[PVFIELD_PV_NAME] == "" ) continue; // Empty PV name + LVM2_PV pv; + pv.pv_name = BlockSpecial( fields[PVFIELD_PV_NAME] ); pv.pv_size = lvm2_pv_size_to_num( fields[PVFIELD_PV_SIZE] ); pv.pv_free = lvm2_pv_size_to_num( fields[PVFIELD_PV_FREE] ); pv.vg_name = fields[PVFIELD_VG_NAME]; @@ -331,12 +332,13 @@ void LVM2_PV_Info::load_lvm2_pv_info_cache() // Returns found cache entry or not found substitute. const LVM2_PV & LVM2_PV_Info::get_pv_cache_entry_by_name( const Glib::ustring & pvname ) { + BlockSpecial bs_pvname( pvname ); for ( unsigned int i = 0 ; i < lvm2_pv_cache.size() ; i ++ ) { - if ( pvname == lvm2_pv_cache[i].pv_name ) + if ( bs_pvname == lvm2_pv_cache[i].pv_name ) return lvm2_pv_cache[i]; } - static LVM2_PV pv = {"", -1, -1, ""}; + static LVM2_PV pv = {BlockSpecial(), -1, -1, ""}; return pv; } diff --git a/src/Makefile.am b/src/Makefile.am index 819c9108..39d6be38 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,6 +12,7 @@ AM_CXXFLAGS = -Wall sbin_PROGRAMS = gpartedbin gpartedbin_SOURCES = \ + BlockSpecial.cc \ Copy_Blocks.cc \ DMRaid.cc \ Device.cc \