Author: aschnell
Date: Tue Nov 10 11:33:00 2009
New Revision: 59454
URL: http://svn.opensuse.org/viewcvs/yast?rev=59454&view=rev
Log:
- added IMSM support by merging branch "tmp/mpatelcz/SP1-md" (fate #305883)
Added:
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.h
Modified:
branches/SuSE-Code-11-SP1-Branch/storage/ (props changed)
branches/SuSE-Code-11-SP1-Branch/storage/VERSION
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/bindings/ycp/LibStorage.i
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Container.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Makefile.am
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.cc
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageDefines.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageInterface.h
branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageTypes.cc
branches/SuSE-Code-11-SP1-Branch/storage/package/yast2-storage.changes
branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/custom_part_check_generated.ycp
branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-hd.ycp
branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-main.ycp
branches/SuSE-Code-11-SP1-Branch/storage/storage/src/inst_target_selection.ycp
branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/Storage.ycp
branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/StorageFields.ycp
Modified: branches/SuSE-Code-11-SP1-Branch/storage/VERSION
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/VERSION?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/VERSION (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/VERSION Tue Nov 10 11:33:00 2009
@@ -1 +1 @@
-2.17.81
+2.17.82
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/bindings/ycp/LibStorage.i
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/bindings/ycp/LibStorage.i?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/bindings/ycp/LibStorage.i (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/bindings/ycp/LibStorage.i Tue Nov 10 11:33:00 2009
@@ -25,6 +25,9 @@
specialize_sequence(storage::LvmLvInfo, TO_PACK, FROM_PACK, CHECK)
specialize_sequence(storage::MdInfo, TO_PACK, FROM_PACK, CHECK)
specialize_sequence(storage::MdStateInfo, TO_PACK, FROM_PACK, CHECK)
+specialize_sequence(storage::MdPartCoInfo, TO_PACK, FROM_PACK, CHECK)
+specialize_sequence(storage::MdPartInfo, TO_PACK, FROM_PACK, CHECK)
+specialize_sequence(storage::MdPartCoStateInfo, TO_PACK, FROM_PACK, CHECK)
specialize_sequence(storage::LoopInfo, TO_PACK, FROM_PACK, CHECK)
specialize_sequence(storage::DmInfo, TO_PACK, FROM_PACK, CHECK)
specialize_sequence(storage::NfsInfo, TO_PACK, FROM_PACK, CHECK)
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Container.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Container.cc?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Container.cc (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Container.cc Tue Nov 10 11:33:00 2009
@@ -462,5 +462,5 @@
}
const string Container::type_names[] = { "UNKNOWN", "DISK", "MD", "LOOP", "LVM",
- "DM", "DMRAID", "NFS", "DMMULTIPATH" };
+ "DM", "DMRAID", "NFS", "DMMULTIPATH", "MDPART" };
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.cc?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.cc (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.cc Tue Nov 10 11:33:00 2009
@@ -1106,6 +1106,11 @@
{
bool need_p = false;
unsigned i=0;
+ static Regex mdpart( "md[0123456789]+$" );
+ if ( mdpart.match( disk ) == true )
+ {
+ return true;
+ }
while( !need_p && ihttp://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.h?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.h (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Disk.h Tue Nov 10 11:33:00 2009
@@ -40,6 +40,7 @@
{
friend class Storage;
friend class DmPartCo;
+ friend class MdPartCo;
struct label_info
{
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.cc?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.cc (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.cc Tue Nov 10 11:33:00 2009
@@ -46,7 +46,7 @@
dev = name;
nm = undevName(name);
num_part = num_pe = free_pe = 0;
- active = valid = del_ptable = false;
+ active = del_ptable = false;
disk = NULL;
init( ppart );
}
@@ -301,8 +301,12 @@
activate_part(true);
}
getVolumes( ppart );
- active = valid = true;
+ active = true;
}
+ else
+ {
+ y2err("error dm " << nm << " table not found");
+ }
}
void
@@ -988,8 +992,6 @@
s << " delPT";
if( !d.active )
s << " inactive";
- if( !d.valid )
- s << " invalid";
return( s );
}
@@ -1015,13 +1017,6 @@
else
log += " active-->";
}
- if( valid!=p->valid )
- {
- if( p->valid )
- log += " -->valid";
- else
- log += " valid-->";
- }
}
return( log );
}
@@ -1066,7 +1061,7 @@
bool DmPartCo::equalContent( const DmPartCo& rhs ) const
{
bool ret = PeContainer::equalContent(rhs,false) &&
- active==rhs.active && valid==rhs.valid &&
+ active==rhs.active &&
del_ptable==rhs.del_ptable;
if( ret )
{
@@ -1089,7 +1084,6 @@
{
y2deb("constructed DmPartCo by copy constructor from " << rhs.nm);
active = rhs.active;
- valid = rhs.valid;
del_ptable = rhs.del_ptable;
disk = NULL;
if( rhs.disk )
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.h?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.h (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmPartCo.h Tue Nov 10 11:33:00 2009
@@ -48,7 +48,6 @@
virtual ~DmPartCo();
unsigned long long sizeK() const { return size_k; }
- unsigned isValid() const { return valid; }
const string& labelName() const { return disk->labelName(); }
const string& udevPath() const { return udev_path; }
const std::list<string>& udevId() const { return udev_id; }
@@ -195,7 +194,6 @@
Disk* disk;
bool active;
- bool valid;
bool del_ptable;
unsigned num_part;
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.cc?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.cc (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.cc Tue Nov 10 11:33:00 2009
@@ -178,10 +178,18 @@
}
-void
-DmmultipathCo::getMultipaths(list<string>& l)
+ bool
+ DmmultipathCo::isActivated(const string& name)
+ {
+ SystemCmd c(DMSETUPBIN " table " + quote(name));
+ return c.retcode() == 0 && c.numLines() >= 1 && isdigit(c.stdout()[0]);
+ }
+
+
+list<string>
+DmmultipathCo::getMultipaths()
{
- l.clear();
+ list<string> l;
SystemCmd c(MULTIPATHBIN " -d -v 2+ -ll");
if (c.numLines() > 0)
@@ -219,9 +227,17 @@
line = *c.getLine(i);
}
y2mil( "mp_list:" << mp_list );
+
if (mp_list.size() >= 1)
{
- l.push_back(unit);
+ if (isActivated(unit))
+ {
+ l.push_back(unit);
+ }
+ else
+ {
+ y2mil("ignoring inactive dmmultipath " << unit);
+ }
}
}
@@ -230,6 +246,7 @@
}
y2mil("detected multipaths " << l);
+ return l;
}
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.h?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.h (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmmultipathCo.h Tue Nov 10 11:33:00 2009
@@ -120,7 +120,9 @@
static void activate( bool val=true );
static bool isActive() { return active; }
- static void getMultipaths( std::list<string>& l );
+ static bool isActivated(const string& name);
+ static list<string> getMultipaths();
+
static bool multipathNotDeleted( const Dmmultipath&d ) { return( !d.deleted() ); }
void logData( const string& Dir );
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.cc?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.cc (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.cc Tue Nov 10 11:33:00 2009
@@ -28,6 +28,7 @@
#include "y2storage/DmraidCo.h"
#include "y2storage/Dmraid.h"
+#include "y2storage/MdPartCo.h"
#include "y2storage/SystemCmd.h"
#include "y2storage/AppUtil.h"
#include "y2storage/Storage.h"
@@ -148,27 +149,48 @@
}
}
-void DmraidCo::getRaids( list<string>& l )
+
+ bool
+ DmraidCo::isActivated(const string& name)
{
- l.clear();
- SystemCmd c(DMRAIDBIN " -s -c -c -c");
- for( unsigned i=0; i= 1 && isdigit(c.stdout()[0]);
+ }
+
+
+ list<string>
+ DmraidCo::getRaids()
+ {
+ list<string> l;
+
+ SystemCmd c(DMRAIDBIN " -s -c -c -c");
+ for( unsigned i=0; i=3 )
+ list<string> sl = splitString( *c.getLine(i), ":" );
+ if( sl.size()>=3 )
{
- list<string>::const_iterator ci = sl.begin();
- if( !ci->empty()
- && ci->find( "/dev/" )==string::npos
- && find( l.begin(), l.end(), *ci )==l.end())
+ list<string>::const_iterator ci = sl.begin();
+ if( !ci->empty()
+ && ci->find( "/dev/" )==string::npos
+ && find( l.begin(), l.end(), *ci )==l.end())
{
- l.push_back( *ci );
+ if (isActivated(*ci))
+ {
+ l.push_back( *ci );
+ }
+ else
+ {
+ y2mil("ignoring inactive dmraid " << *ci);
+ }
}
}
}
- y2mil( "detected Raids " << l );
+
+ y2mil("detected dmraids " << l);
+ return l;
}
+
string DmraidCo::removeText( bool doing ) const
{
string txt;
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.h?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.h (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/DmraidCo.h Tue Nov 10 11:33:00 2009
@@ -119,7 +119,9 @@
static string undevName( const string& name );
- static void getRaids( std::list<string>& l );
+ static bool isActivated(const string& name);
+ static list<string> getRaids();
+
static bool raidNotDeleted( const Dmraid&d ) { return( !d.deleted() ); }
int doRemove();
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Makefile.am
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Makefile.am?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Makefile.am (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Makefile.am Tue Nov 10 11:33:00 2009
@@ -33,6 +33,7 @@
DmraidCo.cc DmraidCo.h \
DmmultipathCo.cc DmmultipathCo.h \
DmCo.cc DmCo.h \
+ MdPartCo.cc MdPartCo.h \
MdCo.cc MdCo.h \
LoopCo.cc LoopCo.h \
NfsCo.cc NfsCo.h \
@@ -43,6 +44,7 @@
DmPart.cc DmPart.h \
Dmraid.cc Dmraid.h \
Dmmultipath.cc Dmmultipath.h \
+ MdPart.cc MdPart.h \
Md.cc Md.h \
Loop.cc Loop.h \
Nfs.cc Nfs.h \
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.cc?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.cc (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.cc Tue Nov 10 11:33:00 2009
@@ -28,6 +28,7 @@
#include "y2storage/MdCo.h"
#include "y2storage/Md.h"
+#include "y2storage/MdPartCo.h"
#include "y2storage/SystemCmd.h"
#include "y2storage/AppUtil.h"
#include "y2storage/Storage.h"
@@ -56,43 +57,30 @@
MdCo::~MdCo()
{
y2deb("destructed MdCo");
- delete tab;
}
void
MdCo::init()
{
- tab = NULL;
mjr = Md::mdMajor();
- initTab();
}
-void
-MdCo::initTab()
- {
- if( tab==NULL && !getStorage()->instsys() )
- tab = new EtcRaidtab( getStorage()->root() );
- }
void
MdCo::syncRaidtab()
- {
- delete tab;
- string d = getStorage()->root()+"/etc";
- if( !checkDir( d ) )
- createPath( d );
- tab = new EtcRaidtab( getStorage()->root() );
+{
MdPair p=mdPair(Md::notDeleted);
for( MdIter i=p.begin(); i!=p.end(); ++i )
- {
+ {
updateEntry( &(*i) );
- }
}
+}
+
void MdCo::updateEntry( const Md* m )
{
- initTab();
- if( tab )
+ EtcRaidtab* tab = getStorage()->getRaidtab();
+ if (tab)
{
list<string> lines;
list<string> devices;
@@ -109,20 +97,23 @@
string line;
std::ifstream file( "/proc/mdstat" );
classic(file);
- unsigned dummy;
getline( file, line );
while( file.good() )
{
- y2mil( "mdstat line:" << line );
- if( Md::mdStringNum(extractNthWord( 0, line ),dummy) )
- {
- string line2;
- getline( file, line2 );
- y2mil( "mdstat line:" << line2 );
- Md* m = new Md( *this, line, line2 );
- addMd( m );
- }
- getline( file, line );
+ string mdDev = extractNthWord( 0, line );
+ string line2;
+ getline(file,line2);
+
+ if( canHandleDev(mdDev,line2) )
+ {
+ Md* m = new Md( *this, line, line2 );
+ addMd( m );
+ getline(file,line);
+ }
+ else
+ {
+ line = line2;
+ }
}
file.close();
file.clear();
@@ -170,7 +161,10 @@
list<string> devs;
i->getDevs( devs );
for( list<string>::iterator s=devs.begin(); s!=devs.end(); ++s )
+ {
+ y2mil( " Setting device " << *s << " as used by UB_MD" );
getStorage()->setUsedBy( *s, UB_MD, num );
+ }
}
}
@@ -669,7 +663,7 @@
if( m != NULL )
{
if( !active )
- activate(true, getStorage()->tmpDir());
+ MdPartCo::activate(true, getStorage()->tmpDir());
if( !silent )
{
getStorage()->showInfoCb( m->removeText(true) );
@@ -697,7 +691,7 @@
}
if( ret==0 )
{
- initTab();
+ EtcRaidtab* tab = getStorage()->getRaidtab();
if( tab!=NULL )
{
tab->removeEntry( m->nr() );
@@ -800,7 +794,6 @@
{
y2deb("constructed MdCo by copy constructor from " << rhs.nm);
*this = rhs;
- this->tab = NULL;
ConstMdPair p = rhs.mdPair();
for( ConstMdIter i=p.begin(); i!=p.end(); ++i )
{
@@ -812,5 +805,49 @@
void MdCo::logData( const string& Dir ) {;}
+// Not a class member. Just check function.
+static bool showMdPartContainers(const Container& c )
+ {
+ return( c.deleted()==false && c.type()==MDPART);
+ }
+
+// No '/dev/' please.
+bool MdCo::isHandledByMdPart(const string& name)
+{
+ if( sto )
+ {
+ Storage::ConstContPair p = sto->contPair( showMdPartContainers );
+ for( Storage::ConstContIterator i = p.begin(); i != p.end(); ++i)
+ {
+ if( i->name() == name )
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool MdCo::canHandleDev(const string& name, const string& line2)
+{
+ unsigned dummy;
+ //If this is a valid MD name.
+ if( Md::mdStringNum(name,dummy) )
+ {
+ // if it's not used by Md Part
+ if (!isHandledByMdPart(name))
+ {
+ //Exclude 'container'
+ if( line2.find("external:imsm") == string::npos &&
+ line2.find("external:ddf") == string::npos )
+ {
+ y2mil("Device : " << name << " can be handled by Md.");
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool MdCo::active = false;
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.h?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.h (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdCo.h Tue Nov 10 11:33:00 2009
@@ -124,7 +124,6 @@
void addMd( Md* m );
void checkMd( Md* m );
void updateEntry( const Md* m );
- void initTab();
void init();
@@ -136,7 +135,13 @@
void logData( const string& Dir );
- EtcRaidtab *tab;
+ /* Return true if given device is alredy handled by MdPartCo. */
+ bool isHandledByMdPart(const string& name);
+
+ /* Return true if md device found in /proc/mdstat given by 'name'
+ * can be handled by Md classes.
+ * The line2 is a line following device name in mdstat. */
+ bool canHandleDev(const string& name, const string& line2);
static bool active;
};
Added: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.cc?rev=59454&view=auto
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.cc (added)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.cc Tue Nov 10 11:33:00 2009
@@ -0,0 +1,263 @@
+/*
+ * File: MdPart.cc
+ *
+ * Implementation of MdPart class which represents single partition on MD
+ * Device (RAID Volume).
+ *
+ * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ Textdomain "storage"
+*/
+
+#include <sstream>
+
+#include "y2storage/MdPart.h"
+#include "y2storage/MdPartCo.h"
+#include "y2storage/SystemCmd.h"
+#include "y2storage/ProcPart.h"
+#include "y2storage/AppUtil.h"
+#include "y2storage/Storage.h"
+
+
+namespace storage
+{
+ using namespace std;
+
+
+MdPart::MdPart(const MdPartCo& d, unsigned nr, Partition* pa) : Volume( d, nr, 0 )
+{
+ init( d.numToName(nr) );
+ numeric = true;
+ num = nr;
+ p = pa;
+ if( pa )
+ {
+ setSize( pa->sizeK() );
+ }
+ y2mil("constructed MdPart " << dev << " on MdPartCo : " << cont->name());
+}
+
+MdPart::MdPart(const MdPartCo& d, const MdPart& rhs)
+ : Volume( d, 0, 0 )
+{
+ y2deb("constructed MdPart by copy constructor from " << rhs.dev);
+ *this = rhs;
+}
+
+
+MdPart::~MdPart()
+{
+ y2deb("destructed MdPart " << dev);
+}
+
+void MdPart::init( const string& name )
+ {
+ p = NULL;
+ dev = "/dev/" + name;
+ string::size_type pos = name.find_last_of( "/" );
+ if( pos!=string::npos )
+ {
+ nm = name.substr( pos+1 );
+ }
+ else
+ {
+ nm = name;
+ }
+ }
+
+const MdPartCo* MdPart::co() const
+ {
+ return(dynamic_cast(cont));
+ }
+
+void MdPart::updateName()
+ {
+ if( p && p->nr() != num )
+ {
+ num = p->nr();
+ nm = co()->numToName(num);
+ dev = "/dev/" + nm;
+ }
+ }
+
+void MdPart::updateMinor()
+ {
+ unsigned long mj=mjr;
+ unsigned long mi=mnr;
+ getMajorMinor( dev, mj, mi );
+ if( mi!=mnr || mj!=mjr )
+ {
+ mnr = mi;
+ mjr = mj;
+ }
+ }
+
+void MdPart::updateSize()
+ {
+ if( p )
+ {
+ orig_size_k = p->origSizeK();
+ size_k = p->sizeK();
+ }
+ }
+
+void MdPart::updateSize( ProcPart& pp )
+ {
+ unsigned long long si = 0;
+ updateSize();
+ //In case of extended partition /proc/partition contains size 1.
+ if( p && p->type() != storage::EXTENDED )
+ {
+ if( mjr>0 && pp.getSize( nm, si ))
+ {
+ setSize( si );
+ }
+ }
+ }
+
+void MdPart::addUdevData()
+ {
+ addAltUdevId( num );
+ }
+//TODO: Is it OK? Check it
+static string udevCompleteIdPath( const string& s, unsigned nr )
+ {
+ return( "/dev/disk/by-id/" + s + "-part" + decString(nr) );
+ }
+
+
+void
+MdPart::addAltUdevId( unsigned num )
+{
+ list<string>::iterator i = alt_names.begin();
+ while( i!=alt_names.end() )
+ {
+ if( i->find( "/by-id/" ) != string::npos )
+ i = alt_names.erase( i );
+ else
+ ++i;
+ }
+ list<string>::const_iterator j = co()->udevId().begin();
+ while( j!=co()->udevId().end() )
+ {
+ alt_names.push_back( udevCompleteIdPath( *j, num ));
+ ++j;
+ }
+ mount_by = orig_mount_by = defaultMountBy();
+}
+
+
+const std::list<string>
+MdPart::udevId() const
+{
+ list<string> ret;
+ for (list<string>::const_iterator i = alt_names.begin();
+ i != alt_names.end(); i++)
+ {
+ if (i->find("/by-id/") != string::npos)
+ ret.push_back(*i);
+ }
+ return ret;
+}
+
+
+void MdPart::getCommitActions( std::liststorage::commitAction*& l ) const
+ {
+ unsigned s = l.size();
+ Volume::getCommitActions(l);
+ if( p )
+ {
+ if( s==l.size() && Partition::toChangeId( *p ) )
+ l.push_back( new commitAction( INCREASE, cont->staticType(),
+ setTypeText(false), this, false ));
+ }
+ }
+
+string MdPart::setTypeText( bool doing ) const
+ {
+ string txt;
+ string d = dev;
+ if( doing )
+ {
+ // displayed text during action, %1$s is replaced by partition name (e.g. pdc_dabaheedj1),
+ // %2$s is replaced by hexadecimal number (e.g. 8E)
+ txt = sformat( _("Setting type of partition %1$s to %2$X"),
+ d.c_str(), id() );
+ }
+ else
+ {
+ // displayed text before action, %1$s is replaced by partition name (e.g. pdc_dabaheedj1),
+ // %2$s is replaced by hexadecimal number (e.g. 8E)
+ txt = sformat( _("Set type of partition %1$s to %2$X"),
+ d.c_str(), id() );
+ }
+ return( txt );
+ }
+
+void MdPart::getInfo( MdPartInfo& tinfo ) const
+ {
+ ((Volume*)this)->getInfo( info.v );
+ if( p )
+ p->getInfo( info.p );
+ info.part = p!=NULL;
+ tinfo = info;
+ }
+
+
+std::ostream& operator<< (std::ostream& s, const MdPart &p )
+ {
+ s << "MdPart: ";
+ s << *(Volume*)&p;
+ return( s );
+ }
+
+bool MdPart::equalContent( const MdPart& rhs ) const
+ {
+ return( Volume::equalContent(rhs) );
+ }
+
+void MdPart::logDifference( const MdPart& rhs ) const
+{
+ string log = Volume::logDifference(rhs);
+ y2mil(log);
+}
+
+
+MdPart& MdPart::operator=(const MdPart& rhs)
+{
+ y2deb("operator= from " << rhs.nm);
+ *((Volume*)this) = rhs;
+ return *this;
+}
+
+
+void MdPart::getPartitionInfo(storage::PartitionInfo& pinfo)
+{
+ ((Volume*)this)->getInfo( pinfo.v );
+ if( p )
+ {
+ PartitionAddInfo info;
+ p->getInfo( info );
+ pinfo = info;
+ }
+
+}
+
+
+}
Added: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.h?rev=59454&view=auto
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.h (added)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPart.h Tue Nov 10 11:33:00 2009
@@ -0,0 +1,76 @@
+/*
+ * File: MdPart.h
+ *
+ * Declaration of MdPart class which represents single partition on MD
+ * Device (RAID Volume).
+ *
+ * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MD_PART_H
+#define MD_PART_H
+
+#include "y2storage/Md.h"
+#include "y2storage/Partition.h"
+
+namespace storage
+{
+
+class MdPartCo;
+class ProcPart;
+
+class MdPart : public Volume
+ {
+ public:
+ MdPart( const MdPartCo& d, unsigned nr, Partition* p=NULL );
+ MdPart( const MdPartCo& d, const MdPart& rd );
+ MdPart& operator=( const MdPart& );
+
+ virtual ~MdPart();
+ friend std::ostream& operator<< (std::ostream& s, const MdPart &p );
+ virtual void print( std::ostream& s ) const { s << *this; }
+ void getInfo( storage::MdPartInfo& info ) const;
+ void getPartitionInfo(storage::PartitionInfo& pinfo);
+ bool equalContent( const MdPart& rhs ) const;
+ void logDifference( const MdPart& d ) const;
+ void setPtr( Partition* pa ) { p=pa; };
+ Partition* getPtr() const { return p; };
+ unsigned id() const { return p?p->id():0; }
+ void updateName();
+ void updateMinor();
+ void updateSize( ProcPart& pp );
+ void updateSize();
+ void getCommitActions( std::liststorage::commitAction*& l ) const;
+ void addUdevData();
+ virtual const std::list<string> udevId() const;
+ virtual string setTypeText( bool doing=true ) const;
+ static bool notDeleted( const MdPart& l ) { return( !l.deleted() ); }
+
+ protected:
+ void init( const string& name );
+ void dataFromPart( const Partition* p );
+ virtual const string shortPrintedName() const { return( "MdPart" ); }
+ const MdPartCo* co() const;
+ void addAltUdevId( unsigned num );
+ Partition* p;
+
+ mutable storage::MdPartInfo info;
+ };
+
+}
+
+#endif
Added: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.cc?rev=59454&view=auto
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.cc (added)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.cc Tue Nov 10 11:33:00 2009
@@ -0,0 +1,2123 @@
+/*
+ * File: MdPartCo.cc
+ *
+ * Implementation of MdPartCo class which represents single MD Device (RAID
+ * Volume) like md126 which is a Container for partitions.
+ *
+ * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ Textdomain "storage"
+*/
+
+#include <sstream>
+#include <algorithm>
+#include <cctype>
+#include <string>
+
+#include
+#include <string>
+#include
+#include
+#include
+#include
+
+#include "y2storage/MdPartCo.h"
+#include "y2storage/MdPart.h"
+#include "y2storage/ProcPart.h"
+#include "y2storage/Partition.h"
+#include "y2storage/SystemCmd.h"
+#include "y2storage/AppUtil.h"
+#include "y2storage/Storage.h"
+#include "y2storage/StorageDefines.h"
+#include "y2storage/Regex.h"
+#include "y2storage/EtcRaidtab.h"
+
+
+namespace storage
+{
+ using namespace std;
+
+
+MdPartCo::MdPartCo( Storage * const s,
+ const string& name,
+ ProcPart* ppart )
+ : Container(s,"",staticType()) // MD?
+ {
+ y2mil("constructing MdPartCo : " << name);
+ makeDevName(name);
+ nm = undevName(name);
+
+ getMajorMinor();
+
+ del_ptable = false;
+ disk = NULL;
+
+ /* First Initialize RAID properties. */
+ initMd();
+ /* Initialize 'disk' part, partitions.*/
+ init( ppart );
+
+ y2mil("MdPartCo (nm=" << nm << ", dev=" << dev << ", level=" << md_type << ", disks=" << devs << ") ready.");
+
+ }
+
+MdPartCo::~MdPartCo()
+ {
+ if( disk )
+ {
+ delete disk;
+ disk = NULL;
+ }
+ y2deb("destructed MdPartCo : " << dev);
+ }
+
+bool MdPartCo::isMdPart(const string& name)
+{
+ string n = undevName(name);
+ static Regex mdpart( "^md[0123456789]+p[0123456789]+$" );
+ return (mdpart.match(n));
+}
+
+void MdPartCo::getPartNum(const string& device, unsigned& num)
+{
+ string dev = device;
+ string::size_type pos;
+
+ pos = dev.find("p");
+ if( pos != string::npos )
+ {
+ /* md125p12 - after p is 12, this will be returned. */
+ dev.substr(pos+1) >> num;
+ }
+ else
+ {
+ num = 0;
+ }
+}
+
+/* Add new partition after creation. Called in 'CreatePartition' */
+int
+MdPartCo::addNewDev(string& device)
+{
+ int ret = 0;
+ if ( isMdPart(device) == false )
+ {
+ ret = MD_PARTITION_NOT_FOUND;
+ }
+ else
+ {
+ unsigned number;
+ const string tmpS(device);
+ getPartNum(tmpS,number);
+ device = "/dev/" + numToName(number);
+ Partition *p = getPartition( number, false );
+ if( p==NULL )
+ {
+ ret = MDPART_PARTITION_NOT_FOUND;
+ }
+ else
+ {
+ MdPart * md = NULL;
+ newP( md, p->nr(), p );
+ md->getFsInfo( p );
+ md->setCreated();
+ addToList( md );
+ y2mil("device:" << device << " was added to MdPartCo : " << dev);
+
+ }
+ handleWholeDevice();
+ }
+ if( ret != 0 )
+ {
+ y2war("device:" << device << " was not added to MdPartCo : " << dev);
+ }
+ return ret;
+}
+
+
+int
+MdPartCo::createPartition( storage::PartitionType type,
+ long unsigned start,
+ long unsigned len,
+ string& device,
+ bool checkRelaxed )
+ {
+ y2milestone( "begin type %d at %ld len %ld relaxed:%d", type, start, len,
+ checkRelaxed );
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && readonly() )
+ ret = MDPART_CHANGE_READONLY;
+ if( ret==0 )
+ {
+ ret = disk->createPartition( type, start, len, device, checkRelaxed );
+ }
+ if( ret==0 )
+ {
+ ret = addNewDev( device );
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int
+MdPartCo::createPartition( long unsigned len, string& device, bool checkRelaxed )
+ {
+ y2milestone( "len %ld relaxed:%d", len, checkRelaxed );
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && readonly() )
+ ret = MDPART_CHANGE_READONLY;
+ if( ret==0 )
+ ret = disk->createPartition( len, device, checkRelaxed );
+ if( ret==0 )
+ ret = addNewDev( device );
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int
+MdPartCo::createPartition( storage::PartitionType type, string& device )
+ {
+ y2milestone( "type %u", type );
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && readonly() )
+ ret = MDPART_CHANGE_READONLY;
+ if( ret==0 )
+ ret = disk->createPartition( type, device );
+ if( ret==0 )
+ ret = addNewDev( device );
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int MdPartCo::updateDelDev()
+ {
+ int ret = 0;
+ list l;
+ MdPartPair p=mdpartPair();
+ MdPartIter i=p.begin();
+ while( i!=p.end() )
+ {
+ Partition *p = i->getPtr();
+ if( p && validPartition( p ) )
+ {
+ if( i->nr()!=p->nr() )
+ {
+ i->updateName();
+ y2mil( "updated name md:" << *i );
+ }
+ if( i->deleted() != p->deleted() )
+ {
+ i->setDeleted( p->deleted() );
+ y2mil( "updated del md:" << *i );
+ }
+ }
+ else
+ l.push_back( &(*i) );
+ ++i;
+ }
+ list::iterator vi = l.begin();
+ while( ret==0 && vi!=l.end() )
+ {
+ if( !removeFromList( *vi ))
+ ret = MDPART_PARTITION_NOT_FOUND;
+ ++vi;
+ }
+ handleWholeDevice();
+ return( ret );
+ }
+
+int
+MdPartCo::removePartition( unsigned nr )
+ {
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && readonly() )
+ ret = MDPART_CHANGE_READONLY;
+ if( ret==0 )
+ {
+ if( nr>0 )
+ {
+ ret = disk->removePartition( nr );
+ }
+ else
+ ret = MDPART_PARTITION_NOT_FOUND;
+ }
+ if( ret==0 )
+ ret = updateDelDev();
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int
+MdPartCo::removeVolume( Volume* v )
+ {
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && readonly() )
+ ret = MDPART_CHANGE_READONLY;
+ if( ret==0 )
+ {
+ unsigned num = v->nr();
+ if( num>0 )
+ ret = disk->removePartition( v->nr() );
+ }
+ if( ret==0 )
+ ret = updateDelDev();
+ getStorage()->logCo( this );
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+
+int
+MdPartCo::freeCylindersAfterPartition(const MdPart* dm, unsigned long& freeCyls) const
+{
+ const Partition* p = dm->getPtr();
+ int ret = p ? 0 : MDPART_PARTITION_NOT_FOUND;
+ if (ret == 0)
+ {
+ ret = disk->freeCylindersAfterPartition(p, freeCyls);
+ }
+ y2mil("ret:" << ret);
+ return ret;
+}
+
+
+int MdPartCo::resizePartition( MdPart* dm, unsigned long newCyl )
+ {
+ Partition * p = dm->getPtr();
+ int ret = p?0:MDPART_PARTITION_NOT_FOUND;
+ if( ret==0 )
+ {
+ p->getFsInfo( dm );
+ ret = disk->resizePartition( p, newCyl );
+ dm->updateSize();
+ }
+ y2mil( "dm:" << *dm );
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int
+MdPartCo::resizeVolume( Volume* v, unsigned long long newSize )
+ {
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && readonly() )
+ ret = MDPART_CHANGE_READONLY;
+ MdPart * l = dynamic_cast(v);
+ if( ret==0 && l==NULL )
+ ret = MDPART_INVALID_VOLUME;
+ if( ret==0 )
+ {
+ Partition *p = l->getPtr();
+ unsigned num = v->nr();
+ if( num>0 && p!=NULL )
+ {
+ p->getFsInfo( v );
+ ret = disk->resizeVolume( p, newSize );
+ }
+ else
+ ret = MDPART_PARTITION_NOT_FOUND;
+ }
+ if( ret==0 )
+ {
+ l->updateSize();
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+
+void
+MdPartCo::init( ProcPart* ppart )
+{
+ const string tmpS(nm);
+ if( ppart )
+ {
+ ppart->getSize( nm, size_k );
+ }
+ y2mil( " nm: " << nm << " size_k: " << size_k);
+ createDisk( ppart );
+ getVolumes( ppart );
+}
+
+void
+MdPartCo::createDisk( ProcPart* ppart )
+ {
+ if( disk )
+ delete disk;
+ disk = new Disk( getStorage(), dev, size_k );
+ disk->setNumMinor( 64 );
+ disk->setSilent();
+ disk->setSlave();
+ if( ppart )
+ {
+ disk->detect( *ppart );
+ }
+ }
+
+// Creates new partition.
+void
+MdPartCo::newP( MdPart*& dm, unsigned num, Partition* p )
+ {
+ dm = new MdPart( *this, num, p );
+ }
+
+//This seems to detect partitions from ppart and adds them to Container.
+void
+MdPartCo::getVolumes( ProcPart* ppart )
+ {
+ vols.clear();
+ num_part = 0;
+ Disk::PartPair pp = disk->partPair();
+ Disk::PartIter i = pp.begin();
+ MdPart * p = NULL;
+ while( i!=pp.end() )
+ {
+ newP( p, i->nr(), &(*i) );
+ if( ppart )
+ p->updateSize( *ppart );
+ num_part++;
+ addToList( p );
+ ++i;
+ }
+ handleWholeDevice();
+ }
+
+void MdPartCo::handleWholeDevice()
+ {
+ Disk::PartPair pp = disk->partPair( Partition::notDeleted );
+ y2milestone( "empty:%d", pp.empty() );
+
+ if( pp.empty() )
+ {
+ MdPart * p = NULL;
+ newP( p, 0, NULL );
+ p->setSize( size_k );
+ addToList( p );
+ }
+ else
+ {
+ MdPartIter i;
+ if( findMdPart( 0, i ))
+ {
+ MdPart* md = &(*i);
+ if( !removeFromList( md ))
+ y2err( "not found:" << *i );
+ }
+ }
+ }
+
+Partition*
+MdPartCo::getPartition( unsigned nr, bool del )
+ {
+ Partition* ret = NULL;
+ Disk::PartPair pp = disk->partPair();
+ Disk::PartIter i = pp.begin();
+ while( i!=pp.end() &&
+ (nr!=i->nr() || del!=i->deleted()) )
+ {
+ ++i;
+ }
+ if( i!=pp.end() )
+ ret = &(*i);
+ if( ret )
+ {
+ y2mil( "nr:" << nr << " del:" << del << " *p:" << *ret );
+ }
+ else
+ {
+ y2mil( "nr:" << nr << " del:" << del << " p:NULL" );
+ }
+ return( ret );
+ }
+
+bool
+MdPartCo::validPartition( const Partition* p )
+ {
+ bool ret = false;
+ Disk::PartPair pp = disk->partPair();
+ Disk::PartIter i = pp.begin();
+ while( i!=pp.end() && p != &(*i) )
+ ++i;
+ ret = i!=pp.end();
+ y2mil( "nr:" << p->nr() << " ret:" << ret );
+ return( ret );
+ }
+
+void MdPartCo::updatePointers( bool invalid )
+ {
+ MdPartPair p=mdpartPair();
+ MdPartIter i=p.begin();
+ while( i!=p.end() )
+ {
+ if( invalid )
+ i->setPtr( getPartition( i->nr(), i->deleted() ));
+ i->updateName();
+ ++i;
+ }
+ }
+
+void MdPartCo::updateMinor()
+ {
+ MdPartPair p=mdpartPair();
+ MdPartIter i=p.begin();
+ while( i!=p.end() )
+ {
+ i->updateMinor();
+ ++i;
+ }
+ }
+
+// Makes complete partition name (like md125p5)
+string MdPartCo::numToName( unsigned mdNum ) const
+ {
+ string ret = nm;
+ if( mdNum>0 )
+ {
+ ret += "p";
+ ret += decString(mdNum);
+ }
+ return( ret );
+ }
+
+int MdPartCo::nr()
+{
+ int n;
+ nm.erase(0,2) >> n;
+ return n;
+}
+
+
+//
+// Assumption is that we're using /dev not /dev/md
+// directory.
+string MdPartCo::undevName( const string& name )
+ {
+ string ret = name;
+ if( ret.find( "/dev/" ) == 0 )
+ ret.erase( 0, 5 );
+ return( ret );
+ }
+
+int MdPartCo::destroyPartitionTable( const string& new_label )
+ {
+ y2milestone( "begin" );
+ int ret = disk->destroyPartitionTable( new_label );
+ if( ret==0 )
+ {
+ VIter j = vols.begin();
+ while( j!=vols.end() )
+ {
+ if( (*j)->created() )
+ {
+ delete( *j );
+ j = vols.erase( j );
+ }
+ else
+ ++j;
+ }
+ bool save = getStorage()->getRecursiveRemoval();
+ getStorage()->setRecursiveRemoval(true);
+ if( getUsedByType() != UB_NONE )
+ {
+ getStorage()->removeUsing( device(), getUsedBy() );
+ }
+ ronly = false;
+ RVIter i = vols.rbegin();
+ while( i!=vols.rend() )
+ {
+ if( !(*i)->deleted() )
+ getStorage()->removeVolume( (*i)->device() );
+ ++i;
+ }
+ getStorage()->setRecursiveRemoval(save);
+ del_ptable = true;
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int MdPartCo::changePartitionId( unsigned nr, unsigned id )
+ {
+ int ret = nr>0?0:MDPART_PARTITION_NOT_FOUND;
+ if( ret==0 )
+ {
+ ret = disk->changePartitionId( nr, id );
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int MdPartCo::forgetChangePartitionId( unsigned nr )
+ {
+ int ret = nr>0?0:MDPART_PARTITION_NOT_FOUND;
+ if( ret==0 )
+ {
+ ret = disk->forgetChangePartitionId( nr );
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+
+int
+MdPartCo::nextFreePartition(PartitionType type, unsigned& nr, string& device) const
+{
+ int ret = disk->nextFreePartition( type, nr, device );
+ if( ret==0 )
+ {
+ device = "/dev/" + numToName(nr);
+ }
+ y2mil("ret:" << ret << " nr:" << nr << " device:" << device);
+ return ret;
+}
+
+
+int MdPartCo::changePartitionArea( unsigned nr, unsigned long start,
+ unsigned long len, bool checkRelaxed )
+ {
+ int ret = nr>0?0:MDPART_PARTITION_NOT_FOUND;
+ if( ret==0 )
+ {
+ ret = disk->changePartitionArea( nr, start, len, checkRelaxed );
+ MdPartIter i;
+ if( findMdPart( nr, i ))
+ i->updateSize();
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+bool MdPartCo::findMdPart( unsigned nr, MdPartIter& i )
+ {
+ MdPartPair p = mdpartPair( MdPart::notDeleted );
+ i=p.begin();
+ while( i!=p.end() && i->nr()!=nr )
+ ++i;
+ return( i!=p.end() );
+ }
+
+//Do we need to activate partition? it will be activated already
+void MdPartCo::activate_part( bool val )
+ {
+ (void)val;
+ }
+
+int MdPartCo::doSetType( MdPart* md )
+ {
+ y2milestone( "doSetType container %s name %s", name().c_str(),
+ md->name().c_str() );
+ Partition * p = md->getPtr();
+ int ret = p?0:MDPART_PARTITION_NOT_FOUND;
+ if( ret==0 )
+ {
+ if( !silent )
+ {
+ getStorage()->showInfoCb( md->setTypeText(true) );
+ }
+ ret = disk->doSetType( p );
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int MdPartCo::doCreateLabel()
+ {
+ y2milestone( "label:%s", labelName().c_str() );
+ int ret = 0;
+ if( !silent )
+ {
+ getStorage()->showInfoCb( setDiskLabelText(true) );
+ }
+ getStorage()->removeDmMapsTo( device() );
+ removePresentPartitions();
+ ret = disk->doCreateLabel();
+ if( ret==0 )
+ {
+ del_ptable = false;
+ removeFromMemory();
+ handleWholeDevice();
+ getStorage()->waitForDevice();
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int
+MdPartCo::removeMdPart()
+ {
+ int ret = 0;
+ y2milestone( "begin" );
+ if( readonly() )
+ {
+ ret = MDPART_CHANGE_READONLY;
+ }
+ if( ret==0 && !created() )
+ {
+ MdPartPair p=mdpartPair(MdPart::notDeleted);
+ for( MdPartIter i=p.begin(); i!=p.end(); ++i )
+ {
+ if( i->nr()>0 )
+ ret = removePartition( i->nr() );
+ }
+ p=mdpartPair(MdPart::notDeleted);
+ if( p.begin()!=p.end() && p.begin()->nr()==0 )
+ {
+ if( !removeFromList( &(*p.begin()) ))
+ y2err( "not found:" << *p.begin() );
+ }
+ setDeleted( true );
+ }
+ if( ret==0 )
+ {
+ //unuseDev(); - In PeContainer.
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+void MdPartCo::removePresentPartitions()
+ {
+ VolPair p = volPair();
+ if( !p.empty() )
+ {
+ bool save=silent;
+ setSilent( true );
+ list<VolIterator> l;
+ for( VolIterator i=p.begin(); i!=p.end(); ++i )
+ {
+ y2mil( "rem:" << *i );
+ if( !i->created() )
+ l.push_front( i );
+ }
+ for( list<VolIterator>::const_iterator i=l.begin(); i!=l.end(); ++i )
+ {
+ doRemove( &(**i) );
+ }
+ setSilent( save );
+ }
+ }
+
+void MdPartCo::removeFromMemory()
+ {
+ VIter i = vols.begin();
+ while( i!=vols.end() )
+ {
+ y2mil( "rem:" << *i );
+ if( !(*i)->created() )
+ {
+ i = vols.erase( i );
+ }
+ else
+ ++i;
+ }
+ }
+
+static bool toChangeId( const MdPart&d )
+ {
+ Partition* p = d.getPtr();
+ return( p!=NULL && !d.deleted() && Partition::toChangeId(*p) );
+ }
+
+int MdPartCo::getToCommit( CommitStage stage, list& col,
+ list& vol )
+ {
+ int ret = 0;
+ y2milestone( "ret:%d col:%zd vol:%zd", ret, col.size(), vol.size());
+ getStorage()->logCo( this );
+ unsigned long oco = col.size();
+ unsigned long ovo = vol.size();
+ Container::getToCommit( stage, col, vol );
+ if( stage==INCREASE )
+ {
+ MdPartPair p = mdpartPair( toChangeId );
+ for( MdPartIter i=p.begin(); i!=p.end(); ++i )
+ if( find( vol.begin(), vol.end(), &(*i) )==vol.end() )
+ vol.push_back( &(*i) );
+ }
+ if( del_ptable && find( col.begin(), col.end(), this )==col.end() )
+ col.push_back( this );
+ if( col.size()!=oco || vol.size()!=ovo )
+ y2milestone( "ret:%d col:%zd vol:%zd", ret, col.size(), vol.size());
+ return( ret );
+ }
+
+
+int MdPartCo::commitChanges( CommitStage stage, Volume* vol )
+ {
+ y2milestone( "name %s stage %d", name().c_str(), stage );
+ int ret = Container::commitChanges( stage, vol );
+ if( ret==0 && stage==INCREASE )
+ {
+ MdPart * dm = dynamic_cast(vol);
+ if( dm!=NULL )
+ {
+ Partition* p = dm->getPtr();
+ if( p && disk && Partition::toChangeId( *p ) )
+ ret = doSetType( dm );
+ }
+ else
+ ret = MDPART_INVALID_VOLUME;
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int MdPartCo::commitChanges( CommitStage stage )
+ {
+ y2milestone( "name %s stage %d", name().c_str(), stage );
+ int ret = 0;
+ if( stage==DECREASE && deleted() )
+ {
+ ret = doRemove();
+ }
+ else if( stage==DECREASE && del_ptable )
+ {
+ ret = doCreateLabel();
+ }
+ else
+ ret = MDPART_COMMIT_NOTHING_TODO;
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+void MdPartCo::getCommitActions( list& l ) const
+ {
+ y2mil( "l:" << l );
+ Container::getCommitActions( l );
+ y2mil( "l:" << l );
+ if( deleted() || del_ptable )
+ {
+ list::iterator i = l.begin();
+ while( i!=l.end() )
+ {
+ if( (*i)->stage==DECREASE )
+ {
+ delete( *i );
+ i=l.erase( i );
+ }
+ else
+ ++i;
+ }
+ string txt = deleted() ? removeText(false) :
+ setDiskLabelText(false);
+ l.push_front( new commitAction( DECREASE, staticType(),
+ txt, this, true ));
+ }
+ y2mil( "l:" << l );
+ }
+
+int
+MdPartCo::doCreate( Volume* v )
+ {
+ y2milestone( "Raid:%s part:%s", name().c_str(), v->name().c_str() );
+ MdPart * l = dynamic_cast(v);
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && l == NULL )
+ ret = MDPART_INVALID_VOLUME;
+ Partition *p = NULL;
+ if( ret==0 )
+ {
+ if( !silent )
+ {
+ getStorage()->showInfoCb( l->createText(true) );
+ }
+ p = l->getPtr();
+ if( p==NULL )
+ ret = MDPART_PARTITION_NOT_FOUND;
+ else
+ ret = disk->doCreate( p );
+ if( ret==0 && p->id()!=Partition::ID_LINUX )
+ ret = doSetType( l );
+ }
+ if( ret==0 )
+ {
+ l->setCreated(false);
+ if( active )
+ {
+ activate_part(false);
+ activate_part(true);
+ ProcPart pp;
+ updateMinor();
+ l->updateSize( pp );
+ }
+ if( p->type()!=EXTENDED )
+ getStorage()->waitForDevice( l->device() );
+ }
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int MdPartCo::doRemove()
+ {
+ return( MDPART_NO_REMOVE );
+ }
+
+int MdPartCo::doRemove( Volume* v )
+ {
+ y2milestone( "Raid:%s name:%s", name().c_str(), v->name().c_str() );
+ MdPart * l = dynamic_cast(v);
+ bool save_act = false;
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && l == NULL )
+ ret = MDPART_INVALID_VOLUME;
+ if( ret==0 )
+ {
+ if( !silent )
+ {
+ getStorage()->showInfoCb( l->removeText(true) );
+ }
+ ret = v->prepareRemove();
+ }
+ if( ret==0 )
+ {
+ save_act = active;
+ if( active )
+ activate_part(false);
+ Partition *p = l->getPtr();
+ if( p==NULL )
+ ret = MDPART_PARTITION_NOT_FOUND;
+ else if( !deleted() )
+ ret = disk->doRemove( p );
+ }
+ if( ret==0 )
+ {
+ if( !removeFromList( l ) )
+ ret = MDPART_REMOVE_PARTITION_LIST_ERASE;
+ }
+ if( save_act && !deleted() )
+ {
+ activate_part(true);
+ updateMinor();
+ }
+ if( ret==0 )
+ getStorage()->waitForDevice();
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+int MdPartCo::doResize( Volume* v )
+ {
+ y2milestone( "MdPart:%s name:%s", name().c_str(), v->name().c_str() );
+ MdPart * l = dynamic_cast(v);
+ int ret = disk ? 0 : MDPART_INTERNAL_ERR;
+ if( ret==0 && l == NULL )
+ ret = MDPART_INVALID_VOLUME;
+ bool remount = false;
+ bool needExtend = false;
+ if( ret==0 )
+ {
+ needExtend = !l->needShrink();
+ if( !silent )
+ {
+ getStorage()->showInfoCb( l->resizeText(true) );
+ }
+ if( l->isMounted() )
+ {
+ ret = l->umount();
+ if( ret==0 )
+ remount = true;
+ }
+ if( ret==0 && !needExtend && l->getFs()!=VFAT && l->getFs()!=FSNONE )
+ ret = l->resizeFs();
+ }
+ if( ret==0 )
+ {
+ Partition *p = l->getPtr();
+ if( p==NULL )
+ ret = MDPART_PARTITION_NOT_FOUND;
+ else
+ ret = disk->doResize( p );
+ }
+ if( ret==0 && active )
+ {
+ activate_part(false);
+ activate_part(true);
+ }
+ if( ret==0 && needExtend && l->getFs()!=VFAT && l->getFs()!=FSNONE )
+ ret = l->resizeFs();
+ if( ret==0 )
+ {
+ ProcPart pp;
+ updateMinor();
+ l->updateSize( pp );
+ getStorage()->waitForDevice( l->device() );
+ }
+ if( ret==0 && remount )
+ ret = l->mount();
+ y2mil("ret:" << ret);
+ return( ret );
+ }
+
+string MdPartCo::setDiskLabelText( bool doing ) const
+ {
+ string txt;
+ string d = dev;
+ if( doing )
+ {
+ // displayed text during action, %1$s is replaced by name (e.g. pdc_igeeeadj),
+ // %2$s is replaced by label name (e.g. msdos)
+ txt = sformat( _("Setting disk label of %1$s to %2$s"),
+ d.c_str(), labelName().c_str() );
+ }
+ else
+ {
+ // displayed text before action, %1$s is replaced by name (e.g. pdc_igeeeadj),
+ // %2$s is replaced by label name (e.g. msdos)
+ txt = sformat( _("Set disk label of %1$s to %2$s"),
+ d.c_str(), labelName().c_str() );
+ }
+ return( txt );
+ }
+
+string MdPartCo::removeText( bool doing ) const
+ {
+ string txt;
+ if( doing )
+ {
+ // displayed text during action, %1$s is replaced by a name (e.g. pdc_igeeeadj),
+ txt = sformat( _("Removing %1$s"), name().c_str() );
+ }
+ else
+ {
+ // displayed text before action, %1$s is replaced by a name (e.g. pdc_igeeeadj),
+ txt = sformat( _("Remove %1$s"), name().c_str() );
+ }
+ return( txt );
+ }
+
+
+void
+MdPartCo::setUdevData(const list<string>& id)
+{
+ if (disk)
+ {
+ disk->setUdevData("", id);
+ }
+}
+
+
+void MdPartCo::getInfo( MdPartCoInfo& tinfo ) const
+ {
+ if( disk )
+ {
+ disk->getInfo( info.d );
+ }
+ info.minor = mnr;
+
+ info.devices.clear();
+ for(list<string>::const_iterator i=devs.begin();
+ i != devs.end();
+ i++)
+ {
+ info.devices += *i;
+ info.devices += " ";
+ }
+
+ info.spares.clear();
+ for(list<string>::const_iterator i=spare.begin();
+ i != spare.end();
+ i++)
+ {
+ info.spares += *i;
+ info.spares += " ";
+ }
+ info.level = md_type;
+ info.nr = mnr;
+ info.parity = md_parity;
+ info.uuid = md_uuid;
+ info.sb_ver = sb_ver;
+ info.chunk = chunk_size;
+ info.md_name = md_name;
+
+ tinfo = info;
+ }
+
+
+int MdPartCo::getPartitionInfo(dequestorage::PartitionInfo& plist)
+{
+ int ret = 0;
+ if( !disk )
+ {
+ ret = MDPART_INTERNAL_ERR;
+ return ret;
+ }
+ Disk::PartPair p = disk->partPair (Disk::notDeleted);
+ for (Disk::PartIter i = p.begin(); i != p.end(); ++i)
+ {
+ plist.push_back( PartitionInfo() );
+ i->getInfo( plist.back() );
+ }
+ return ret;
+}
+
+
+std::ostream& operator<< (std::ostream& s, const MdPartCo& d )
+ {
+ s << *((Container*)&d);
+ s << " Name:" << d.md_name
+ << " MdNr:" << d.mnr
+ << " PNum:" << d.num_part;
+ if( !d.udev_id.empty() )
+ s << " UdevId:" << d.udev_id;
+ if( d.del_ptable )
+ s << " delPT";
+ if( !d.active )
+ s << " inactive";
+ return( s );
+ }
+
+
+string MdPartCo::getDiffString( const Container& d ) const
+ {
+ string log = Container::getDiffString( d );
+ const MdPartCo* p = dynamic_cast(&d);
+ if( p )
+ {
+ if( del_ptable!=p->del_ptable )
+ {
+ if( p->del_ptable )
+ log += " -->delPT";
+ else
+ log += " delPT-->";
+ }
+ if( active!=p->active )
+ {
+ if( p->active )
+ log += " -->active";
+ else
+ log += " active-->";
+ }
+ }
+ return( log );
+ }
+
+void MdPartCo::logDifference( const MdPartCo& d ) const
+ {
+ string log = getDiffString( d );
+
+ if( md_type!=d.md_type )
+ log += " Personality:" + md_names[md_type] + "-->" +
+ md_names[d.md_type];
+ if( md_parity!=d.md_parity )
+ log += " Parity:" + par_names[md_parity] + "-->" +
+ par_names[d.md_parity];
+ if( chunk_size!=d.chunk_size )
+ log += " Chunk:" + decString(chunk_size) + "-->" + decString(d.chunk_size);
+ if( sb_ver!=d.sb_ver )
+ log += " SbVer:" + sb_ver + "-->" + d.sb_ver;
+ if( md_uuid!=d.md_uuid )
+ log += " MD-UUID:" + md_uuid + "-->" + d.md_uuid;
+ if( md_name!=d.md_name )
+ {
+ log += " MDName:" + md_uuid + "-->" + d.md_uuid;
+ }
+ if( destrSb!=d.destrSb )
+ {
+ if( d.destrSb )
+ log += " -->destrSb";
+ else
+ log += " destrSb-->";
+ }
+ if( devs!=d.devs )
+ {
+ std::ostringstream b;
+ classic(b);
+ b << " Devices:" << devs << "-->" << d.devs;
+ log += b.str();
+ }
+ if( spare!=d.spare )
+ {
+ std::ostringstream b;
+ classic(b);
+ b << " Spares:" << spare << "-->" << d.spare;
+ log += b.str();
+ }
+ if( parent_container!=d.parent_container )
+ log += " ParentContainer:" + parent_container + "-->" + d.parent_container;
+
+ y2mil(log);
+ ConstMdPartPair pp=mdpartPair();
+ ConstMdPartIter i=pp.begin();
+ while( i!=pp.end() )
+ {
+ ConstMdPartPair pc=d.mdpartPair();
+ ConstMdPartIter j = pc.begin();
+ while( j!=pc.end() &&
+ (i->device()!=j->device() || i->created()!=j->created()) )
+ ++j;
+ if( j!=pc.end() )
+ {
+ if( !i->equalContent( *j ) )
+ i->logDifference( *j );
+ }
+ else
+ y2mil( " -->" << *i );
+ ++i;
+ }
+ pp=d.mdpartPair();
+ i=pp.begin();
+ while( i!=pp.end() )
+ {
+ ConstMdPartPair pc=mdpartPair();
+ ConstMdPartIter j = pc.begin();
+ while( j!=pc.end() &&
+ (i->device()!=j->device() || i->created()!=j->created()) )
+ ++j;
+ if( j==pc.end() )
+ y2mil( " <--" << *i );
+ ++i;
+ }
+ }
+
+bool MdPartCo::equalContent( const Container& rhs ) const
+ {
+ bool ret = Container::equalContent(rhs);
+ if( ret )
+ {
+ const MdPartCo* mdp = dynamic_cast(&rhs);
+ ret = ret &&
+ active==mdp->active &&
+ del_ptable==mdp->del_ptable;
+
+ ret = ret &&
+ (chunk_size == mdp->chunk_size &&
+ md_type == mdp->md_type &&
+ md_parity == mdp->md_parity &&
+ md_state == mdp->md_state &&
+ sb_ver == mdp->sb_ver &&
+ devs == mdp->devs &&
+ spare == mdp->spare &&
+ md_uuid == mdp->md_uuid &&
+ destrSb == mdp->destrSb &&
+ md_name == mdp->md_name);
+ if( ret )
+ {
+ if( sb_ver == "imsm" || sb_ver == "ddf" )
+ {
+ ret = ret && (parent_container == mdp->parent_container);
+ }
+ }
+ if( ret )
+ {
+ ConstMdPartPair pp = mdpartPair();
+ ConstMdPartPair pc = mdp->mdpartPair();
+ ConstMdPartIter i = pp.begin();
+ ConstMdPartIter j = pc.begin();
+ while( ret && i!=pp.end() && j!=pc.end() )
+ {
+ ret = ret && i->equalContent( *j );
+ ++i;
+ ++j;
+ }
+ ret = ret && i==pp.end() && j==pc.end();
+ }
+ }
+ return( ret );
+ }
+
+MdPartCo::MdPartCo( const MdPartCo& rhs ) : Container(rhs)
+ {
+ y2deb("constructed MdPartCo by copy constructor from " << rhs.nm);
+ active = rhs.active;
+ del_ptable = rhs.del_ptable;
+ chunk_size = rhs.chunk_size;
+ md_type = rhs.md_type;
+ md_parity = rhs.md_parity;
+ md_state = rhs.md_state;
+ parent_container = rhs.parent_container;
+ md_uuid = rhs.md_uuid;
+ sb_ver = rhs.sb_ver;
+ destrSb = rhs.destrSb;
+ devs = rhs.devs;
+ spare = rhs.spare;
+ md_name = rhs.md_name;
+
+ udev_path = rhs.udev_path;
+ udev_id = rhs.udev_id;
+
+ disk = NULL;
+ if( rhs.disk )
+ disk = new Disk( *rhs.disk );
+ getStorage()->waitForDevice();
+ ConstMdPartPair p = rhs.mdpartPair();
+ for( ConstMdPartIter i = p.begin(); i!=p.end(); ++i )
+ {
+ MdPart * p = new MdPart( *this, *i );
+ vols.push_back( p );
+ }
+ updatePointers(true);
+ num_part = rhs.num_part;
+ }
+
+bool MdPartCo::isMdName(const string& name)
+{
+ static Regex md("^md[0123456789]+");
+ return (md.match(name));
+}
+// Get list of active MD RAID's
+// cat /proc/mdstat
+// If we're looking for Volume then
+// find devname and in next line will be: 'external:imsm'
+//Personalities : [raid0] [raid1]
+//md125 : active (auto-read-only) raid1 sdb[1] sdc[0]
+// 130071552 blocks super external:/md127/1 [2/2] [UU]
+//
+//md126 : active raid0 sdb[1] sdc[0]
+// 52428800 blocks super external:/md127/0 128k chunks
+//
+//md127 : inactive sdc[1](S) sdb[0](S)
+// 4514 blocks super external:imsm
+//
+//unused devices: <none>
+
+
+list<string>
+MdPartCo::getMdRaids()
+{
+ y2mil( " called " );
+ list<string> l;
+ string line;
+ string dev_name;
+ std::ifstream file( "/proc/mdstat" );
+ classic(file);
+ getline( file, line );
+ while( file.good() )
+ {
+ string dev_name = extractNthWord( 0, line );
+ if( isMdName(dev_name) )
+ {
+ string line2;
+ getline(file,line2);
+ if( line2.find("external:imsm") == string::npos &&
+ line2.find("external:imsm") == string::npos)
+ {
+ // external:imsm or ddf not found. Assume that this is a Volume.
+ l.push_back(dev_name);
+ }
+ }
+ getline( file, line );
+ }
+ file.close();
+ file.clear();
+
+ y2mil("detected md devs : " << l);
+ return l;
+}
+
+void
+MdPartCo::getDevs( list<string>& devices, bool all, bool spares ) const
+ {
+ if( !all )
+ devices = spares ? spare : devs;
+ else
+ {
+ devices = devs;
+ devices.insert( devices.end(), spare.begin(), spare.end() );
+ }
+ }
+
+
+void MdPartCo::getSpareDevs(std::list<string>& devices )
+{
+ devices = spare;
+}
+
+
+bool MdPartCo::matchMdRegex( const string& dev )
+ {
+ static Regex md( "^md[0123456789]+$" );
+ return( md.match(dev));
+ }
+
+
+unsigned MdPartCo::mdMajor()
+ {
+ if( md_major==0 )
+ getMdMajor();
+ return( md_major );
+ }
+
+void MdPartCo::getMdMajor()
+ {
+ md_major = getMajorDevices( "md" );
+ }
+
+void MdPartCo::setSize(unsigned long long size )
+{
+ size_k = size;
+}
+
+void MdPartCo::getMdProps()
+{
+ y2mil("Called");
+
+ string property;
+
+ if( !readProp(METADATA, md_metadata) )
+ {
+ y2war("Failed to read metadata");
+ }
+
+ property.clear();
+ if( !readProp(COMPONENT_SIZE, property) )
+ {
+ y2war("Failed to read component_size");
+ setSize(0);
+ }
+ else
+ {
+ unsigned long long tmpSize;
+ property >> tmpSize;
+ setSize(tmpSize);
+ }
+
+ property.clear();
+ if( !readProp(CHUNK_SIZE, property) )
+ {
+ y2war("Failed to read chunk_size");
+ chunk_size = 0;
+ }
+ else
+ {
+ property >> chunk_size;
+ /* From 'B' in file to 'Kb' here. */
+ chunk_size /= 1024;
+ }
+
+ property.clear();
+ if( !readProp(ARRAY_STATE, property) )
+ {
+ md_state = storage::UNKNOWN;
+ y2war("array state unknown ");
+ }
+ else
+ {
+ if( property == "readonly" )
+ {
+ //setReadonly();
+ }
+ md_state = toMdArrayState(property);
+ }
+
+ if( !readProp(LEVEL, property) )
+ {
+ y2war("RAID type unknown");
+ md_type = storage::RAID_UNK;
+ }
+ else
+ {
+ md_type = toMdType(property);
+ }
+
+ //
+ setMdParity();
+ setMdDevs();
+ setSpares();
+ readMdMap();
+ setMetaData();
+ y2mil("Done");
+}
+
+bool MdPartCo::readProp(enum MdProperty prop, string& val)
+{
+ string path = sysfs_path + nm + "/md/" + md_props[prop];
+
+ if( access( path.c_str(), R_OK )==0 )
+ {
+ std::ifstream file( path.c_str() );
+ classic(file);
+ file >> val;
+ file.close();
+ file.clear();
+ }
+ else
+ {
+ y2war("File: " << sysfs_path << md_props[prop] << " = FAILED");
+ return false;
+ }
+ return true;
+}
+
+
+
+void MdPartCo::getSlaves(const string name, std::list<string>& devs_list )
+{
+ string path = sysfs_path + name + "/slaves";
+ DIR* dir;
+
+ devs_list.clear();
+
+ if ((dir = opendir(path.c_str())) != NULL)
+ {
+ struct dirent* entry;
+ while ((entry = readdir(dir)) != NULL)
+ {
+ string tmpS(entry->d_name);
+ y2mil("Entry : " << tmpS);
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
+ {
+ continue;
+ }
+ devs_list.push_back( ("/dev/"+tmpS) );
+ }
+ closedir(dir);
+ }
+ else
+ {
+ y2mil("Failed to opend directory");
+ }
+}
+
+
+void MdPartCo::setMdDevs()
+{
+ getSlaves(nm,devs);
+
+ for( list<string>::iterator s=devs.begin(); s!=devs.end(); ++s )
+ {
+ //It will be set always to last RAID that was detected.
+ getStorage()->setUsedBy( *s, UB_MDPART, nm );
+ }
+}
+
+
+void
+MdPartCo::getParent()
+{
+ string ret;
+ string con = md_metadata;
+ string::size_type pos1;
+ string::size_type pos2;
+
+ parent_container.clear();
+
+ if( md_metadata.empty() )
+ {
+ (void)readProp(METADATA, md_metadata);
+ con = md_metadata;
+ }
+
+ if( con.find("external:")==0 )
+ {
+ if( (pos1=con.find_first_of("/")) != string::npos )
+ {
+ if( (pos2=con.find_last_of("/")) != string::npos)
+ {
+ if( pos1 != pos2)
+ {
+ //Typically: external:/md127/0
+ parent_container.clear();
+ parent_container = con.substr(pos1+1,pos2-pos1-1);
+ }
+ }
+ }
+ else
+ {
+ // this is the Container
+ }
+ }
+ else
+ {
+ // No external metadata.
+ // Possibly this is raid with persistent metadata and no container.
+ }
+}
+
+void MdPartCo::setMetaData()
+{
+ if( parent_container.empty () )
+ {
+ getParent();
+ }
+ if( parent_container.empty() )
+ {
+ // No parent container.
+ sb_ver = md_metadata;
+ return;
+ }
+
+ string path = sysfs_path + parent_container + "/md/" + md_props[METADATA];
+ string val;
+
+ if( access( path.c_str(), R_OK )==0 )
+ {
+ std::ifstream file( path.c_str() );
+ classic(file);
+ file >> val;
+ file.close();
+ file.clear();
+
+ // It will be 'external:XXXX'
+ string::size_type pos = val.find(":");
+ if( pos != string::npos )
+ {
+ sb_ver = val.erase(0,pos+1);
+ }
+ }
+ return;
+}
+
+void MdPartCo::setMdParity()
+{
+ md_parity = PAR_NONE;
+ //Level 5 & 6 - left-symmetric
+ //Level 10 - n2 layout (0x102)
+ if( hasParity() )
+ {
+ switch( md_type )
+ {
+ case RAID5:
+ case RAID6:
+ md_parity = LEFT_ASYMMETRIC;
+ case RAID10:
+ /* Parity 'n2' */
+ //md_parity = PARITY_N2;
+ default:
+ return;
+ }
+ }
+}
+
+
+/* Spares: any disk that is in container and not in RAID. */
+void MdPartCo::setSpares()
+{
+ std::list<string> parent_devs;
+ std::list<string> diff_devs;
+
+ parent_devs.clear();
+ diff_devs.clear();
+ int found;
+
+ list<string>::const_iterator it1;
+ list<string>::const_iterator it2;
+
+ getParent();
+ if( parent_container.empty() )
+ {
+ spare.clear();
+ return;
+ }
+ getSlaves(parent_container,parent_devs);
+
+ for( it1 = parent_devs.begin(); it1 != parent_devs.end(); it1++ )
+ {
+ found = 0;
+ for(it2 = devs.begin(); it2 != devs.end(); it2++ )
+ {
+ if( *it1 == *it2 )
+ {
+ found++;
+ break;
+ }
+ }
+ if( found == 0 )
+ {
+ diff_devs.push_back(*it1);
+ }
+ }
+ spare = diff_devs;
+
+ for( list<string>::iterator s=spare.begin(); s!=spare.end(); ++s )
+ {
+ //It will be set always to last RAID that was detected.
+ getStorage()->setUsedBy( *s, UB_MDPART, nm );
+ }
+}
+
+bool MdPartCo::findMdMap(std::ifstream& file)
+{
+ const char* mdadm_map[] = {"/var/run/mdadm/map",
+ "/var/run/mdadm.map",
+ "/dev/.mdadm.map",
+ 0};
+ classic(file);
+ int i=0;
+ while( mdadm_map[i] )
+ {
+ file.open( mdadm_map[i] );
+ if( file.is_open() )
+ {
+ return true;
+ }
+ else
+ {
+ i++;
+ }
+ }
+ y2war(" Map File not found");
+ return false;
+}
+
+
+/* Will try to set: UUID, Name.*/
+/* Format: mdX metadata uuid /dev/md/md_name */
+bool MdPartCo::readMdMap()
+{
+ std::ifstream file;
+ string line;
+ classic(file);
+
+ /* Got file, now parse output. */
+ if( findMdMap(file) )
+ {
+ while( !file.eof() )
+ {
+ string val;
+ getline(file,line);
+ val = extractNthWord( MAP_DEV, line );
+ if( val == nm )
+ {
+ size_t found;
+ md_uuid = extractNthWord( MAP_UUID, line );
+ val = extractNthWord( MAP_NAME, line );
+ found = val.find_last_of("/");
+ md_name = val.substr(found+1);
+ file.close();
+ return true;
+ }
+ }
+ file.close();
+ }
+ return true;
+}
+
+
+void MdPartCo::initMd()
+{
+ /* Name is 'nm' read all props. */
+ getMdProps();
+}
+
+
+void MdPartCo::activate( bool val, const string& tmpDir )
+{
+ if( active!=val )
+ {
+ MdCo::activate(val,tmpDir);
+ active = val;
+ }
+}
+
+bool MdPartCo::matchRegex( const string& dev )
+ {
+ static Regex md( "^md[0123456789]+$" );
+ return( md.match(dev));
+ }
+
+bool MdPartCo::mdStringNum( const string& name, unsigned& num )
+ {
+ bool ret=false;
+ string d = undevDevice(name);
+ if( matchRegex( d ))
+ {
+ d.substr( 2 )>>num;
+ ret = true;
+ }
+ return( ret );
+ }
+
+
+MdType
+MdPartCo::toMdType( const string& val )
+ {
+ enum MdType ret = MULTIPATH;
+ while( ret!=RAID_UNK && val!=md_names[ret] )
+ {
+ ret = MdType(ret-1);
+ }
+ return( ret );
+ }
+
+MdParity
+MdPartCo::toMdParity( const string& val )
+ {
+ enum MdParity ret = RIGHT_SYMMETRIC;
+ while( ret!=PAR_NONE && val!=par_names[ret] )
+ {
+ ret = MdParity(ret-1);
+ }
+ return( ret );
+ }
+
+
+
+storage::MdArrayState
+MdPartCo::toMdArrayState( const string& val )
+{
+ enum storage::MdArrayState ret = storage::ACTIVE_IDLE;
+ while( ret!=storage::UNKNOWN && val!=md_states[ret] )
+ {
+ ret = storage::MdArrayState(ret-1);
+ }
+ return( ret );
+}
+
+
+void MdPartCo::getMdPartCoState(storage::MdPartCoStateInfo& info)
+{
+ string prop;
+
+ readProp(ARRAY_STATE,prop);
+
+ info.state = toMdArrayState(prop);
+
+ info.active = true; //?
+ info.degraded = false; //?
+}
+
+
+void MdPartCo::getMajorMinor()
+{
+ string path = sysfs_path + nm + "/dev";
+
+ if( access( path.c_str(), R_OK )==0 )
+ {
+ string val;
+ unsigned pos;
+
+ std::ifstream file( path.c_str() );
+ classic(file);
+ file >> val;
+
+ pos = val.find(":");
+ val.substr(0,pos) >> mjr;
+ val.substr(pos+1) >> mnr;
+
+ file.close();
+ file.clear();
+ }
+
+}
+
+void MdPartCo::makeDevName(const string& name )
+{
+ if( name.find("/dev/") != string::npos )
+ {
+ dev = name;
+ }
+ else
+ {
+ dev = "/dev/" + name;
+ }
+}
+
+
+bool MdPartCo::isImsmPlatform()
+{
+ bool ret = false;
+ SystemCmd c;
+
+ c.execute(MDADMBIN " --detail-platform");
+ c.select( "Platform : " );
+ //c.retcode()==0 && - mdadm returns 1.
+ if( c.numLines(true)>0 )
+ {
+ const string line = *c.getLine(0,true);
+ if( line.find("Intel(R) Matrix Storage Manager") != string::npos )
+ {
+ ret = true;
+ }
+ }
+ return ret;
+}
+
+/*
+ * Return true if on RAID Volume has a partition table
+ *
+ * : /usr/sbin/parted name print - will return:
+ * 1. List of partitions if partition table exits.
+ * 2. Error if no partition table is on device.
+ *
+ * Ad 2. Clean newly created device or FS on device.
+ */
+bool MdPartCo::hasPartitionTable(const string& name )
+{
+ //bool ret = false;
+ SystemCmd c;
+ bool ret = false;
+
+ string cmd = PARTEDCMD " " + quote("/dev/" + name) + " print";
+
+ c.execute(cmd);
+
+ //For clear md125 (just created)
+ //Error: /dev/md125: unrecognised disk label
+ //so $? contains 1.
+ //If dev has partition table then $? contains 0
+ if( c.retcode() == 0 )
+ {
+ ret = true;
+ //Still - it can contain:
+ // del: Unknown (unknown)
+ // Disk /dev/md125: 133GB
+ // Sector size (logical/physical): 512B/512B
+ // Partition Table: loop
+
+ c.select("Partition Table:");
+ if( c.numLines(true) > 0 )
+ {
+ string loop = *c.getLine(0,true);
+ if( loop.find("loop") != string::npos )
+ {
+ // It has 'loop' partition table so it's actually a volume.
+ ret = false;
+ }
+ }
+ }
+return ret;
+}
+
+
+/* Return true if there is no partition table and no FS */
+bool MdPartCo::hasFileSystem(const string& name)
+{
+ //bool ret = false;
+ SystemCmd c;
+ string cmd = BLKIDBIN " -c /dev/null " + quote("/dev/" + name);
+
+ c.execute(cmd);
+ // IF filesystem was bit found then it will return no output end error core 2.
+ if( c.retcode() != 0 )
+ {
+ return false;
+ }
+ // if FS is on device then it will be in TYPE="fsType" pair.
+ return true;
+}
+
+
+void
+MdPartCo::syncRaidtab()
+{
+ updateEntry();
+}
+
+
+void MdPartCo::updateEntry()
+ {
+ EtcRaidtab* tab = getStorage()->getRaidtab();
+ if( tab )
+ {
+ list<string> lines;
+ list<string> devices;
+ raidtabLines(lines);
+ getDevs( devices );
+ tab->updateEntry( nr(), lines, mdadmLine(), devices );
+ }
+ }
+
+string MdPartCo::mdadmLine() const
+ {
+ string line = "ARRAY " + device() + " level=" + pName();
+ line += " UUID=" + md_uuid;
+ y2mil("line:" << line);
+ return( line );
+ }
+
+void MdPartCo::raidtabLines( list<string>& lines ) const
+ {
+ lines.clear();
+ lines.push_back( "raiddev " + device() );
+ string tmp = " raid-level ";
+ switch( md_type )
+ {
+ case RAID1:
+ tmp += "1";
+ break;
+ case RAID5:
+ tmp += "5";
+ break;
+ case RAID6:
+ tmp += "6";
+ break;
+ case RAID10:
+ tmp += "10";
+ break;
+ case MULTIPATH:
+ tmp += "multipath";
+ break;
+ default:
+ tmp += "0";
+ break;
+ }
+ lines.push_back( tmp );
+ lines.push_back( " nr-raid-disks " + decString(devs.size()));
+ lines.push_back( " nr-spare-disks " + decString(spare.size()));
+ lines.push_back( " persistent-superblock 1" );
+ if( md_parity!=PAR_NONE )
+ lines.push_back( " parity-algorithm " + ptName());
+ if( chunk_size>0 )
+ lines.push_back( " chunk-size " + decString(chunk_size));
+ unsigned cnt = 0;
+ for( list<string>::const_iterator i=devs.begin(); i!=devs.end(); ++i )
+ {
+ lines.push_back( " device " + *i);
+ lines.push_back( " raid-disk " + decString(cnt++));
+ }
+ cnt = 0;
+ for( list<string>::const_iterator i=spare.begin(); i!=spare.end(); ++i )
+ {
+ lines.push_back( " device " + *i);
+ lines.push_back( " spare-disk " + decString(cnt++));
+ }
+ }
+
+int MdPartCo::scanForRaid(list<string>& raidNames)
+{
+ int ret = -1;
+ SystemCmd c(MDADMBIN " -Es ");
+ raidNames.clear();
+
+ if( c.retcode() == 0 )
+ {
+ raidNames.clear();
+ for(unsigned i = 0; i < c.numLines(false); i++ )
+ {
+ //Example:
+ //ARRAY metadata=imsm UUID=b...5
+ //ARRAY /dev/md/Vol_r5 container=b...5 member=0 UUID=0...c
+ //ARRAY metadata=imsm UUID=8...b
+ //ARRAY /dev/md/Vol0 container=8...b member=0 UUID=7...9
+ string line = *c.getLine(i);
+ string dev_name = extractNthWord( 1, line );
+ if( dev_name.find("/dev/md/") == 0 )
+ {
+ dev_name.erase(0,8);
+ raidNames.push_back(dev_name);
+ }
+ }
+ ret = 0;
+ }
+ y2mil(" Detected list of MD RAIDs : " << raidNames);
+ return ret;
+}
+
+storage::CType
+MdPartCo::envSelection(const string& name)
+{
+ string big = name;
+ std::transform(name.begin(), name.end(),
+ big.begin(),(int(*)(int))std::toupper);
+ string str = "YAST_STORAGE_" + big;
+ char * tenv = getenv( str.c_str() );
+ if( tenv == NULL )
+ {
+ return CUNKNOWN;
+ }
+ string isMd(tenv);
+ if( isMd == "MD" )
+ {
+ return MD;
+ }
+ if( isMd == "MDPART" )
+ {
+ return MDPART;
+ }
+ return CUNKNOWN;
+}
+
+bool MdPartCo::havePartsInProc(const string& name, ProcPart& ppart)
+{
+ string reg;
+ list <string> parts;
+ // Search /proc/partitions for partitions.
+ reg = name + "p[1-9]+";
+ parts.clear();
+ parts = ppart.getMatchingEntries( reg );
+ if( !parts.empty() )
+ {
+ return true;
+ }
+ return false;
+}
+
+list<string> MdPartCo::filterMdPartCo(list<string>& raidList,
+ ProcPart& ppart,
+ bool isInst)
+{
+ y2mil(" called ");
+ list<string> mdpList;
+
+ for( list<string>::const_iterator i=raidList.begin(); i!=raidList.end(); ++i )
+ {
+ storage::CType ct = MdPartCo::envSelection(*i);
+ if( ct == MD )
+ {
+ // skip
+ continue;
+ }
+ if (ct == MDPART )
+ {
+ mdpList.push_back(*i);
+ continue;
+ }
+ if( MdPartCo::havePartsInProc(*i,ppart) )
+ {
+ mdpList.push_back(*i);
+ continue;
+ }
+ if( isInst )
+ {
+ // 1. With Partition Table
+ // 2. Without Partition Table and without FS on it.
+ // 3. this gives: No FS.
+ if (!MdPartCo::hasFileSystem(*i))
+ {
+ mdpList.push_back(*i);
+ }
+ }
+ else
+ {
+ // In 'normal' mode ONLY volume with Partition Table.
+ // Partitions should be visible already so check it.
+ if( MdPartCo::hasPartitionTable(*i))
+ {
+ mdpList.push_back(*i);
+ }
+ }
+ } // for
+ y2mil("List of partitionable devs: " << mdpList);
+ return mdpList;
+}
+
+string MdPartCo::md_names[] = { "unknown", "raid0", "raid1", "raid5", "raid6",
+ "raid10", "multipath" };
+string MdPartCo::par_names[] = { "none", "left-asymmetric", "left-symmetric",
+ "right-asymmetric", "right-symmetric" };
+/* */
+string MdPartCo::md_states[] = {"clear", "inactive", "suspended", "readonly",
+ "read-auto", "clean", "active", "write-pending",
+ "active-idle"};
+
+string MdPartCo::md_props[] = {"metadata_version", "component_size", "chunk_size",
+ "array_state", "level", "layout" };
+/* */
+string MdPartCo::sysfs_path = "/sys/devices/virtual/block/";
+
+unsigned MdPartCo::md_major = 0;
+
+bool MdPartCo::active = false;
+
+bool MdPartCo::handlingMd = false;
+
+void MdPartCo::logData( const string& Dir ) {}
+
+
+}
Added: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.h?rev=59454&view=auto
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.h (added)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/MdPartCo.h Tue Nov 10 11:33:00 2009
@@ -0,0 +1,384 @@
+/*
+ * File: MdPartCo.cc
+ *
+ * Declaration of MdPartCo class which represents single MD Device (RAID
+ * Volume) like md126 which is a Container for partitions.
+ *
+ * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009 Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef MD_PART_CO_H
+#define MD_PART_CO_H
+
+#include <list>
+
+#include "y2storage/Container.h"
+#include "y2storage/Disk.h"
+#include "y2storage/MdPart.h"
+
+namespace storage
+{
+
+class Storage;
+class SystemCmd;
+class ProcPart;
+class Region;
+class EtcRaidtab;
+
+/**
+ * Class: MdPartCo
+ *
+ * Brief:
+ * MD RAID Volume that can be partitioned and used as container for partitions.
+*/
+class MdPartCo : public Container
+ {
+ friend class Storage;
+
+ public:
+ MdPartCo( Storage * const s,
+ const string& Name,
+ ProcPart* ppart = NULL);
+
+ MdPartCo( const MdPartCo& rhs );
+
+ virtual ~MdPartCo();
+
+
+ unsigned long long sizeK() const { return size_k; }
+ const string& labelName() const { return disk->labelName(); }
+ const string& udevPath() const { return udev_path; }
+ const std::list<string>& udevId() const { return udev_id; }
+ unsigned numPartitions() const { return disk->numPartitions(); }
+ static storage::CType staticType() { return storage::MDPART; }
+ friend std::ostream& operator<< (std::ostream&, const MdPartCo& );
+ void setUdevData(const list<string>& id);
+
+ /* Checks if name fits with MD name*/
+ bool matchMdName(const string& name ) { return (name==nm); }
+
+ void getMdPartCoState(storage::MdPartCoStateInfo& info);
+
+ int createPartition( storage::PartitionType type, long unsigned start,
+ long unsigned len, string& device,
+ bool checkRelaxed=false );
+ int createPartition( long unsigned len, string& device,
+ bool checkRelaxed=false );
+ int createPartition( storage::PartitionType type, string& device );
+ int removePartition( unsigned nr );
+ int changePartitionId( unsigned nr, unsigned id );
+ int forgetChangePartitionId( unsigned nr );
+ int changePartitionArea( unsigned nr, unsigned long start,
+ unsigned long size, bool checkRelaxed=false );
+ int nextFreePartition(storage::PartitionType type, unsigned& nr,
+ string& device) const;
+ int destroyPartitionTable( const string& new_label );
+ int freeCylindersAfterPartition(const MdPart* p, unsigned long& freeCyls) const;
+ int resizePartition( MdPart* p, unsigned long newCyl );
+ int resizeVolume( Volume* v, unsigned long long newSize );
+ int removeVolume( Volume* v );
+ int removeMdPart();
+
+ unsigned maxPrimary() const { return disk->maxPrimary(); }
+ bool extendedPossible() const { return disk->extendedPossible(); }
+ unsigned maxLogical() const { return disk->maxLogical(); }
+
+ unsigned int numPrimary() const { return disk->numPrimary(); }
+ bool hasExtended() const { return disk->hasExtended(); }
+ unsigned int numLogical() const { return disk->numLogical(); }
+
+ void getUnusedSpace(std::list<Region>& free, bool all = true, bool logical = false) const
+ { disk->getUnusedSpace(free, all, logical); }
+
+ unsigned long long cylinderToKb( unsigned long val ) const
+ { return disk->cylinderToKb( val ); }
+ unsigned long kbToCylinder( unsigned long long val ) const
+ { return disk->kbToCylinder( val ); }
+ string getPartName( unsigned nr ) const;
+
+ virtual void getCommitActions( std::liststorage::commitAction*& l ) const;
+ virtual int getToCommit( storage::CommitStage stage,
+ std::list& col,
+ std::list& vol );
+ virtual int commitChanges( storage::CommitStage stage );
+ int commitChanges( storage::CommitStage stage, Volume* vol );
+
+ Partition* getPartition( unsigned nr, bool del );
+ int getPartitionInfo(dequestorage::PartitionInfo& plist);
+ void getInfo( storage::MdPartCoInfo& info ) const;
+ bool equalContent( const Container& rhs ) const;
+ virtual string getDiffString( const Container& d ) const;
+ void logDifference( const MdPartCo& d ) const;
+ MdPartCo& operator= ( const MdPartCo& rhs );
+ static string undevName( const string& name );
+ string numToName( unsigned mdNum ) const;
+
+ static list<string> getMdRaids();
+
+ void syncRaidtab();
+
+ int nr();
+ /* RAID Related functionality */
+ unsigned long chunkSize() const { return chunk_size; }
+
+ storage::MdType personality() const { return md_type; }
+
+ storage::MdArrayState getArrayState() { return md_state; };
+
+ void getMdUuid( string&val ) { val=md_uuid; }
+
+ /* Raid Level of the RAID as string. */
+ const string& pName() const { return md_names[md_type]; }
+ /* Parity for some of RAID's. */
+ const string& ptName() const { return par_names[md_parity]; }
+ /* Devices from which RAID is composed. */
+ void getDevs( std::list<string>& devices, bool all=true, bool spare=false ) const;
+
+
+ void getSpareDevs(std::list<string>& devices );
+
+ /* Is MD device? */
+ static bool matchMdRegex( const string& dev );
+ /* MD Device major number. */
+ static unsigned mdMajor();
+
+ /* Raid Level as string for given type. */
+ static const string& pName( storage::MdType t ) { return md_names[t]; }
+
+ static void activate( bool val, const string& tmpDir );
+
+ static bool isActive( void ) { return active; }
+
+ /* Return true if on RAID Volume is partition table */
+ static bool hasPartitionTable(const string& name );
+ /* Return true if there is no Filesystem on device (it can contain partition table). */
+ static bool hasFileSystem(const string& name);
+
+
+ static void setHandlingDev(bool val) { handlingMd = val; }
+ static bool isHandlingDev() { return handlingMd; }
+
+ static bool isImsmPlatform();
+
+ static bool matchRegex( const string& dev );
+ static bool mdStringNum( const string& name, unsigned& num );
+
+ // This function will scann for MD RAIDs and will return
+ // list with detected RAID names.
+ static int scanForRaid(list<string>& raidNames);
+
+ /* filterMdPartCo
+ * Get list of detected MD RAIDs and filters them for
+ * those which can be handled by MdPartCo.
+ */
+ static list<string> filterMdPartCo(list<string>& raidList,
+ ProcPart& ppart,
+ bool isInst);
+
+
+ protected:
+ // iterators over partitions
+ // protected typedefs for iterators over partitions
+ typedef CastIterator MdPartInter;
+ typedef CastIterator MdPartCInter;
+ template< class Pred >
+ struct MdPartPI { typedef ContainerIter type; };
+ template< class Pred >
+ struct MdPartCPI { typedef ContainerIter type; };
+ typedef CheckFnc<const MdPart> CheckFncMdPart;
+ typedef CheckerIterator< CheckFncMdPart, MdPartPI<CheckFncMdPart>::type,
+ MdPartInter, MdPart > MdPartPIterator;
+ typedef CheckerIterator< CheckFncMdPart, MdPartCPI<CheckFncMdPart>::type,
+ MdPartCInter, const MdPart > MdPartCPIterator;
+ typedef DerefIterator MdPartIter;
+ typedef DerefIterator ConstMdPartIter;
+ typedef IterPair<MdPartIter> MdPartPair;
+ typedef IterPair<ConstMdPartIter> ConstMdPartPair;
+
+ MdPartPair mdpartPair( bool (* CheckMdPart)( const MdPart& )=NULL)
+ {
+ return( MdPartPair( mdpartBegin( CheckMdPart ), mdpartEnd( CheckMdPart ) ));
+ }
+ MdPartIter mdpartBegin( bool (* CheckMdPart)( const MdPart& )=NULL)
+ {
+ IterPair<MdPartInter> p( (MdPartInter(begin())), (MdPartInter(end())) );
+ return( MdPartIter( MdPartPIterator( p, CheckMdPart )) );
+ }
+ MdPartIter mdpartEnd( bool (* CheckMdPart)( const MdPart& )=NULL)
+ {
+ IterPair<MdPartInter> p( (MdPartInter(begin())), (MdPartInter(end())) );
+ return( MdPartIter( MdPartPIterator( p, CheckMdPart, true )) );
+ }
+
+ ConstMdPartPair mdpartPair( bool (* CheckMdPart)( const MdPart& )=NULL) const
+ {
+ return( ConstMdPartPair( mdpartBegin( CheckMdPart ), mdpartEnd( CheckMdPart ) ));
+ }
+ ConstMdPartIter mdpartBegin( bool (* CheckMdPart)( const MdPart& )=NULL) const
+ {
+ IterPair<MdPartCInter> p( (MdPartCInter(begin())), (MdPartCInter(end())) );
+ return( ConstMdPartIter( MdPartCPIterator( p, CheckMdPart )) );
+ }
+ ConstMdPartIter mdpartEnd( bool (* CheckMdPart)( const MdPart& )=NULL) const
+ {
+ IterPair<MdPartCInter> p( (MdPartCInter(begin())), (MdPartCInter(end())) );
+ return( ConstMdPartIter( MdPartCPIterator( p, CheckMdPart, true )) );
+ }
+
+ MdPartCo( Storage * const s, const string& File );
+ virtual void print( std::ostream& s ) const { s << *this; }
+ virtual Container* getCopy() const { return( new MdPartCo( *this ) ); }
+ void activate_part( bool val );
+ void init( ProcPart* ppart );
+ void createDisk( ProcPart* ppart );
+ void getVolumes( ProcPart* ppart );
+ void updatePointers( bool invalid=false );
+ void updateMinor();
+ virtual void newP( MdPart*& dm, unsigned num, Partition* p );
+ int addNewDev( string& device );
+ int updateDelDev();
+ void handleWholeDevice();
+ void removeFromMemory();
+ void removePresentPartitions();
+ bool validPartition( const Partition* p );
+ bool findMdPart( unsigned nr, MdPartIter& i );
+
+ void updateEntry();
+ string mdadmLine() const;
+ void raidtabLines( list<string>& lines ) const;
+
+
+ static bool partNotDeleted( const MdPart&d ) { return( !d.deleted() ); }
+
+ int doCreate( Volume* v );
+ int doRemove( Volume* v );
+ int doResize( Volume* v );
+ int doSetType( MdPart* v );
+ int doCreateLabel();
+ virtual int doRemove();
+ virtual string removeText( bool doing ) const;
+ virtual string setDiskLabelText( bool doing ) const;
+
+ void getMajorMinor(void);
+
+ /* Makes sure that dev=/dev/name is name doesn't contains this prefix*/
+ void makeDevName(const string& name );
+ /* Initialize the MD part of object.*/
+ void initMd(void);
+
+ void setSize(unsigned long long size );
+ /* */
+ static bool isMdName(const string& name);
+
+ bool isMdPart(const string& name);
+
+ void getPartNum(const string& device, unsigned& num);
+
+ void getMdProps(void);
+
+ void setSpares(void);
+
+ void logData( const string& Dir );
+ string udev_path;
+ std::list<string> udev_id;
+ string logfile_name;
+
+ Disk* disk;
+ bool del_ptable;
+ unsigned num_part;
+
+ /* RAID Related */
+
+ /* Returns container */
+ void getParent();
+
+ void setMetaData();
+
+ void setMdDevs();
+
+ void setMdParity();
+
+ /* returns devices listed as slaves in sysfs directory */
+ void getSlaves(const string name, std::list<string>& devs_list );
+
+ /* fields in 'map' file */
+ enum mdMap { MAP_DEV=0, MAP_META, MAP_UUID, MAP_NAME, };
+ bool findMdMap(std::ifstream& file);
+ bool readMdMap();
+
+
+ //Input: 'mdXXX' device.
+ static storage::CType envSelection(const string& name);
+ static bool havePartsInProc(const string& name, ProcPart& ppart);
+
+ static void getMdMajor();
+ static storage::MdType toMdType( const string& val );
+ static storage::MdParity toMdParity( const string& val );
+ static storage::MdArrayState toMdArrayState( const string& val );
+
+
+
+ unsigned long chunk_size;
+ storage::MdType md_type;
+ storage::MdParity md_parity;
+ storage::MdArrayState md_state;
+
+ /* Md Container - */
+ string parent_container;
+ string md_metadata;
+ string md_uuid;
+ string sb_ver;
+ bool destrSb;
+ std::list<string> devs;
+ std::list<string> spare;
+ static string md_names[storage::MULTIPATH+1];
+ static string par_names[storage::RIGHT_SYMMETRIC+1];
+ static string md_states[storage::ACTIVE_IDLE+1];
+ static unsigned md_major;
+
+ /* Name that is present in /dev/md directory.*/
+ string md_name;
+
+ static string sysfs_path;
+
+ enum MdProperty
+ {
+ METADATA=0,
+ COMPONENT_SIZE,
+ CHUNK_SIZE,
+ ARRAY_STATE,
+ LEVEL,
+ LAYOUT,
+ /* ... */
+ MDPROP_LAST,
+ };
+ static string md_props[MDPROP_LAST];
+
+ bool readProp(enum MdProperty prop, string& val);
+
+ /* For that RAID type parity means something */
+ bool hasParity() const
+ { return md_type == RAID5 || md_type == RAID6 || md_type == RAID10; }
+
+ mutable storage::MdPartCoInfo info;
+
+ static bool active;
+ static bool handlingMd;
+ };
+}
+
+#endif
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.cc?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.cc (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.cc Tue Nov 10 11:33:00 2009
@@ -49,6 +49,7 @@
#include "y2storage/Disk.h"
#include "y2storage/Dasd.h"
#include "y2storage/MdCo.h"
+#include "y2storage/MdPartCo.h"
#include "y2storage/DmCo.h"
#include "y2storage/LoopCo.h"
#include "y2storage/LvmVg.h"
@@ -56,6 +57,7 @@
#include "y2storage/ProcMounts.h"
#include "y2storage/ProcPart.h"
#include "y2storage/EtcFstab.h"
+#include "y2storage/EtcRaidtab.h"
#include "y2storage/AsciiFile.h"
#include "y2storage/StorageDefines.h"
@@ -130,6 +132,9 @@
defaultMountBy = MOUNTBY_ID;
detectMounted = true;
+ fstab = NULL;
+ raidtab = NULL;
+
logSystemInfo();
}
@@ -225,17 +230,32 @@
detectDisks( *ppart );
if( instsys() )
{
+ if( discoverMdPVols() == true )
+ {
+ // if 'yes' then activate md prior to dm
+ MdPartCo::activate( true, tmpDir() );
+ waitForDevice();
+ }
+ //Note:
+ //dmraid will not activate devices that were activated by
+ //mdadm. So this is safe.
DmraidCo::activate( true );
waitForDevice();
- MdCo::activate( true, tmpDir() );
- waitForDevice();
+ //If user said No then this is the way it was before.
+ if( MdPartCo::isHandlingDev() == false )
+ {
+ MdPartCo::activate(true, tmpDir() );
+ waitForDevice();
+ }
LvmVg::activate( true );
waitForDevice();
delete ppart;
ppart = new ProcPart;
}
+
detectDmraid( *ppart );
detectDmmultipath( *ppart );
+ detectMdParts(*ppart);
detectMds();
detectDm(*ppart, true);
detectLvmVgs();
@@ -251,6 +271,7 @@
SystemCmd::testmode = true;
rootprefix = testdir();
fstab = new EtcFstab( rootprefix );
+ raidtab = new EtcRaidtab(rootprefix);
string t = testdir() + "/volume_info";
if( access( t.c_str(), R_OK )==0 )
{
@@ -260,6 +281,8 @@
else
{
fstab = new EtcFstab( "/etc", isRootMounted() );
+ if (!instsys())
+ raidtab = new EtcRaidtab(root());
detectLoops( *ppart );
ProcMounts pm( this );
if( !instsys() )
@@ -405,6 +428,32 @@
}
}
+// Detect MD Partitionable Volumes.
+void Storage::detectMdParts(ProcPart& ppart)
+{
+ if( testmode() )
+ {
+ string file = testdir()+"/md";
+ if( access( file.c_str(), R_OK )==0 )
+ {
+ y2mil("MD PART CO in test mode not available yet");
+ }
+ }
+ else
+ {
+ list<string> l = MdPartCo::getMdRaids();
+ list<string> mdpartlist = MdPartCo::filterMdPartCo(l,ppart, instsys());
+ //
+ for( list<string>::const_iterator i = mdpartlist.begin();
+ i != mdpartlist.end();
+ i++)
+ {
+ MdPartCo * v = new MdPartCo( this, *i, &ppart );
+ // check for valid?
+ addToList( v );
+ }
+ }
+}
void Storage::detectMds()
{
@@ -426,6 +475,76 @@
}
}
+bool Storage::discoverMdPVols()
+{
+ if( !instsys() )
+ {
+ return false;
+ }
+ string mdDevs = "";
+ bool ret = MdPartCo::isImsmPlatform();
+ if( ret == true )
+ {
+ y2mil("Intel SW RAID Platform detected.");
+
+ list <string> l;
+ if( MdPartCo::scanForRaid(l) != 0 )
+ {
+ MdPartCo::activate( true, tmpDir() );
+ waitForDevice();
+ l = MdPartCo::getMdRaids();
+ MdPartCo::activate( false, "" );
+ }
+ if (!l.empty())
+ {
+ // At least ONE Volume must be detected
+ mdDevs.clear();
+ for( list<string>::const_iterator i=l.begin(); i!=l.end(); ++i )
+ {
+ mdDevs += " " + *i;
+ }
+ y2mil(" md raids:" + mdDevs);
+ if( !mdDevs.empty())
+ {
+ string txt = sformat(
+ // popup text %1$s is replaced by disk name e.g. /dev/hda
+ _("You are running on the Intel(R) Matrix Storage Manager compatible platform.\n"
+ "\n"
+ "Following MD compatible RAID devices were detected:\n"
+ "%1$s\n"
+ "If they are clean devices or contain partitions then you can choose to use\n"
+ "MD Partitionable RAID sysbsystem to handle them. In case of clean device you\n"
+ "will be able to install system on it and boot from such RAID.\n"
+ "Do you want MD Partitionable RAID subsystem to manage those partitions?"
+ ), mdDevs.c_str() );
+
+ if( yesnoPopupCb(txt) )
+ {
+ ret = true;
+ MdPartCo::setHandlingDev(true);
+ }
+ else
+ {
+ ret = false;
+ }
+ }
+ else
+ {
+ /* No mdDevs */
+ ret = false;
+ }
+ }
+ else
+ {
+ /* No RAIDs at all */
+ ret = false;
+ }
+ }
+ y2mil(" Exiting with status: " << ret);
+ return ret;
+}
+
+
void Storage::detectLoops( ProcPart& ppart )
{
if( testmode() )
@@ -456,7 +575,7 @@
addToList( new NfsCo( this, file ) );
}
}
- else
+ else if (getenv("YAST2_STORAGE_NO_NFS") == NULL)
{
NfsCo * v = new NfsCo( this, mounts );
if( !v->isEmpty() )
@@ -518,8 +637,7 @@
}
else if( getenv( "YAST2_STORAGE_NO_DMRAID" )==NULL )
{
- list<string> l;
- DmraidCo::getRaids(l);
+ const list<string> l = DmraidCo::getRaids();
if (!l.empty())
{
map by_id;
@@ -527,19 +645,10 @@
for( list<string>::const_iterator i=l.begin(); i!=l.end(); ++i )
{
DmraidCo * v = new DmraidCo( this, *i, ppart );
- if( v->isValid() )
- {
list<string> nm = by_id["dm-"+decString(v->minorNr())];
if( !nm.empty() )
v->setUdevData( nm );
addToList( v );
- }
- else
- {
- y2milestone( "inactive DMRAID %s", i->c_str() );
- v->unuseDev();
- delete( v );
- }
}
}
}
@@ -561,8 +670,7 @@
}
else if( getenv( "YAST2_STORAGE_NO_DMMULTIPATH" )==NULL )
{
- list<string> l;
- DmmultipathCo::getMultipaths(l);
+ const list<string> l = DmmultipathCo::getMultipaths();
if (!l.empty())
{
map by_id;
@@ -570,19 +678,10 @@
for( list<string>::const_iterator i=l.begin(); i!=l.end(); ++i )
{
DmmultipathCo * v = new DmmultipathCo( this, *i, ppart );
- if( v->isValid() )
- {
list<string> nm = by_id["dm-"+decString(v->minorNr())];
if (!nm.empty())
v->setUdevData( nm );
addToList( v );
- }
- else
- {
- y2mil("inactive DMMULTIPATH " << *i);
- v->unuseDev();
- delete v;
- }
}
}
}
@@ -718,6 +817,12 @@
if (dn == "." || dn == "..")
continue;
+ // Do not allow to detect MD Device as 'disk'
+ if( MdPartCo::isMdName(dn) )
+ {
+ continue;
+ }
+
Disk::SysfsInfo sysfsinfo;
if (!Disk::getSysfsInfo(SYSFSDIR "/" + dn, sysfsinfo))
continue;
@@ -1044,6 +1149,20 @@
}
}
}
+ if( ret==0 && !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ if( i->getUsedByType() != UB_NONE )
+ ret = STORAGE_DISK_USED_BY;
+ else
+ {
+ ret = i->createPartition( type, start, size, device, true );
+ }
+ }
+ }
if( !done && ret==0 )
{
ret = STORAGE_DISK_NOT_FOUND;
@@ -1113,6 +1232,27 @@
}
}
if( ret==0 && !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ if( i->getUsedByType() != UB_NONE )
+ ret = STORAGE_DISK_USED_BY;
+ else
+ {
+ unsigned long num_cyl = i->kbToCylinder( sizeK );
+ unsigned long long tmp_start = start;
+ if( tmp_start > i->kbToCylinder(1)/2 )
+ tmp_start -= i->kbToCylinder(1)/2;
+ else
+ tmp_start = 0;
+ unsigned long start_cyl = i->kbToCylinder( tmp_start )+1;
+ ret = i->createPartition( type, start_cyl, num_cyl, device, true );
+ }
+ }
+ }
+ if( ret==0 && !done )
{
ret = STORAGE_DISK_NOT_FOUND;
}
@@ -1163,6 +1303,21 @@
}
}
if( ret==0 && !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ if( i->getUsedByType() != UB_NONE )
+ ret = STORAGE_DISK_USED_BY;
+ else
+ {
+ unsigned long num_cyl = i->kbToCylinder( sizeK );
+ ret = i->createPartition( num_cyl, device, true );
+ }
+ }
+ }
+ if( ret==0 && !done )
{
ret = STORAGE_DISK_NOT_FOUND;
}
@@ -1194,6 +1349,15 @@
}
}
if( !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ ret = i->nextFreePartition( type, nr, device );
+ }
+ }
+ if( !done )
{
ret = STORAGE_DISK_NOT_FOUND;
}
@@ -1243,6 +1407,20 @@
}
}
if( ret==0 && !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ if( i->getUsedByType() != UB_NONE )
+ ret = STORAGE_DISK_USED_BY;
+ else
+ {
+ ret = i->createPartition( type, device );
+ }
+ }
+ }
+ if( ret==0 && !done )
{
ret = STORAGE_DISK_NOT_FOUND;
}
@@ -1272,6 +1450,15 @@
ret = i->cylinderToKb( size );
}
}
+ if( !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ ret = i->cylinderToKb( size );
+ }
+ }
y2milestone( "ret:%lld", ret );
return( ret );
}
@@ -1298,6 +1485,16 @@
ret = i->kbToCylinder( sizeK );
}
}
+ if( !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ ret = i->kbToCylinder( sizeK );
+ }
+ }
+
y2milestone( "ret:%ld", ret );
return( ret );
}
@@ -1356,6 +1553,28 @@
ret = STORAGE_REMOVE_PARTITION_INVALID_CONTAINER;
}
}
+ else if( cont->type() == MDPART )
+ {
+ MdPartCo* disk = dynamic_cast(&(*cont));
+ if( disk != NULL)
+ {
+ if( vol->getUsedByType() == UB_NONE || recursiveRemove )
+ {
+ if( vol->getUsedByType() != UB_NONE )
+ ret = removeUsing( vol->device(), vol->getUsedBy() );
+ if( ret==0 )
+ {
+ ret = disk->removePartition( vol->nr() );
+ }
+ }
+ else
+ ret = STORAGE_REMOVE_USED_VOLUME;
+ }
+ else
+ {
+ ret = STORAGE_REMOVE_PARTITION_INVALID_CONTAINER;
+ }
+ }
else
{
ret = STORAGE_REMOVE_PARTITION_INVALID_CONTAINER;
@@ -1413,6 +1632,18 @@
ret = STORAGE_CHANGE_AREA_INVALID_CONTAINER;
}
}
+ else if( cont->type() == MDPART )
+ {
+ MdPartCo* disk = dynamic_cast(&(*cont));
+ if( disk!=NULL )
+ {
+ ret = disk->changePartitionArea( vol->nr(), start, size );
+ }
+ else
+ {
+ ret = STORAGE_CHANGE_AREA_INVALID_CONTAINER;
+ }
+ }
else
{
ret = STORAGE_CHANGE_AREA_INVALID_CONTAINER;
@@ -1467,6 +1698,19 @@
ret = STORAGE_RESIZE_INVALID_CONTAINER;
}
}
+ else if ( cont->type() == MDPART )
+ {
+ MdPartCo* disk = dynamic_cast(&(*cont));
+ MdPart* p = dynamic_cast(&(*vol));
+ if( disk!=NULL && p!=NULL )
+ {
+ ret = disk->freeCylindersAfterPartition(p, freeCyls);
+ }
+ else
+ {
+ ret = STORAGE_RESIZE_INVALID_CONTAINER;
+ }
+ }
else
{
ret = STORAGE_RESIZE_INVALID_CONTAINER;
@@ -1519,6 +1763,18 @@
ret = STORAGE_CHANGE_PARTITION_ID_INVALID_CONTAINER;
}
}
+ else if ( cont->type()==MDPART )
+ {
+ MdPartCo* disk = dynamic_cast(&(*cont));
+ if( disk!=NULL )
+ {
+ ret = disk->changePartitionId( vol->nr(), id );
+ }
+ else
+ {
+ ret = STORAGE_CHANGE_PARTITION_ID_INVALID_CONTAINER;
+ }
+ }
else
{
ret = STORAGE_CHANGE_PARTITION_ID_INVALID_CONTAINER;
@@ -1594,6 +1850,21 @@
ret = STORAGE_RESIZE_INVALID_CONTAINER;
}
}
+ else if( cont->type()== MDPART )
+ {
+ MdPartCo* disk = dynamic_cast(&(*cont));
+ MdPart* p = dynamic_cast(&(*vol));
+ if( disk!=NULL && p!=NULL )
+ {
+ if( ignoreFs )
+ p->setIgnoreFs();
+ ret = disk->resizePartition( p, sizeCyl );
+ }
+ else
+ {
+ ret = STORAGE_RESIZE_INVALID_CONTAINER;
+ }
+ }
else
{
ret = STORAGE_RESIZE_INVALID_CONTAINER;
@@ -1649,6 +1920,19 @@
ret = STORAGE_CHANGE_PARTITION_ID_INVALID_CONTAINER;
}
}
+ else if( cont->type() == MDPART )
+ {
+ MdPartCo* disk = dynamic_cast(&(*cont));
+ if( disk!=NULL )
+ {
+ ret = disk->forgetChangePartitionId( vol->nr() );
+ }
+ else
+ {
+ ret = STORAGE_CHANGE_PARTITION_ID_INVALID_CONTAINER;
+ }
+
+ }
else
{
ret = STORAGE_CHANGE_PARTITION_ID_INVALID_CONTAINER;
@@ -1678,6 +1962,7 @@
DiskIterator i1 = findDisk( disk );
DmPartCoIterator i2 = findDmPartCo( disk );
+ MdPartCoIterator i3 = findMdPartCo( disk );
if (i1 != dEnd())
{
@@ -1761,6 +2046,47 @@
slots.push_back(slot);
}
}
+ else if (i3 != mdpCoEnd())
+ {
+ // maxPrimary() and maxLogical() include limits from partition table type and
+ // minor number range
+
+ bool primaryPossible = i3->numPrimary() + (i3->hasExtended() ? 1 : 0) < i3->maxPrimary();
+ bool extendedPossible = primaryPossible && i3->extendedPossible() && !i3->hasExtended();
+ bool logicalPossible = i3->hasExtended() && i3->numLogical() < (i3->maxLogical() - i3->maxPrimary());
+
+ list<Region> regions;
+
+ i3->getUnusedSpace(regions, false, false);
+ for (list<Region>::const_iterator region=regions.begin(); region!=regions.end(); region++)
+ {
+ PartitionSlotInfo slot;
+ slot.cylStart = region->start();
+ slot.cylSize = region->len();
+ slot.primarySlot = true;
+ slot.primaryPossible = primaryPossible;
+ slot.extendedSlot = true;
+ slot.extendedPossible = extendedPossible;
+ slot.logicalSlot = false;
+ slot.logicalPossible = false;
+ slots.push_back(slot);
+ }
+
+ i3->getUnusedSpace(regions, false, true);
+ for (list<Region>::const_iterator region=regions.begin(); region!=regions.end(); region++)
+ {
+ PartitionSlotInfo slot;
+ slot.cylStart = region->start();
+ slot.cylSize = region->len();
+ slot.primarySlot = false;
+ slot.primaryPossible = false;
+ slot.extendedSlot = false;
+ slot.extendedPossible = false;
+ slot.logicalSlot = true;
+ slot.logicalPossible = logicalPossible;
+ slots.push_back(slot);
+ }
+ }
else
{
ret = STORAGE_DISK_NOT_FOUND;
@@ -1801,6 +2127,15 @@
}
}
if( ret==0 && !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ ret = i->destroyPartitionTable( label );
+ }
+ }
+ if( ret==0 && !done )
{
ret = STORAGE_DISK_NOT_FOUND;
}
@@ -1843,6 +2178,15 @@
}
}
if( ret==0 && !done )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ done = true;
+ ret = DISK_INIT_NOT_POSSIBLE;
+ }
+ }
+ if( ret==0 && !done )
{
ret = STORAGE_DISK_NOT_FOUND;
}
@@ -3115,6 +3459,7 @@
return( ret );
}
+
int Storage::changeMdType( const string& name, MdType rtype )
{
int ret = 0;
@@ -3243,6 +3588,26 @@
return ret;
}
+// Find container 'name' and return its state.
+int Storage::getMdPartCoStateInfo(const string& name, MdPartCoStateInfo& info)
+{
+ CPair p = cPair();
+ ContIterator i = p.begin();
+
+ for( i=p.begin(); i!=p.end(); i++)
+ {
+ if( i->type()==MDPART )
+ {
+ MdPartCo* mdp = static_cast(&(*i));
+ if( mdp->matchMdName(name) )
+ {
+ mdp->getMdPartCoState(info);
+ break;
+ }
+ }
+ }
+ return( i != p.end() );
+}
int
Storage::computeMdSize(MdType md_type, list<string> devices, unsigned long long& sizeK)
@@ -4089,6 +4454,7 @@
DiskIterator d;
DmraidCoIterator r;
DmmultipathCoIterator m;
+ MdPartCoIterator md;
std::pair p = Disk::getDiskPartition( dev );
if( p.first=="/dev/md" )
{
@@ -4130,6 +4496,14 @@
info.numeric = true;
info.nr = p.second;
}
+ else if( (md=findMdPartCo(p.first))!=mdpCoEnd() )
+ {
+ info.cname = md->device();
+ info.vname = dev.substr( dev.find_last_of('/')+1 );
+ info.type = MDPART;
+ info.numeric = true;
+ info.nr = p.second;
+ }
else if( (m=findDmmultipathCo(p.first))!=dmmCoEnd() )
{
info.cname = m->device();
@@ -4242,10 +4616,12 @@
return( ret );
}
+
int Storage::getPartitionInfo( const string& disk,
dequestorage::PartitionInfo& plist )
{
int ret = 0;
+ bool done = false;
plist.clear();
assertInit();
DiskIterator i = findDisk( disk );
@@ -4257,9 +4633,21 @@
plist.push_back( PartitionInfo() );
i2->getInfo( plist.back() );
}
+ done = true;
}
- else
+ if( done == false )
+ {
+ MdPartCoIterator i = findMdPartCo( disk );
+ if( i != mdpCoEnd() )
+ {
+ ret = i->getPartitionInfo( plist );
+ done = false;
+ }
+ }
+ if( done == false)
+ {
ret = STORAGE_DISK_NOT_FOUND;
+ }
return( ret );
}
@@ -4393,6 +4781,61 @@
return( ret );
}
+int Storage::getMdPartCoInfo( const string& name, MdPartCoInfo& info)
+{
+ int ret = 0;
+ assertInit();
+ MdPartCoIterator i = findMdPartCo( name );
+ if( i != mdpCoEnd() )
+ {
+ i->getInfo( info );
+ }
+ else
+ ret = STORAGE_MDPART_CO_NOT_FOUND;
+ return( ret );
+}
+
+int Storage::getContMdPartCoInfo( const string& name, ContainerInfo& cinfo,
+ MdPartCoInfo& info)
+{
+ int ret = 0;
+ assertInit();
+ MdPartCoIterator i = findMdPartCo( name );
+ if( i != mdpCoEnd() )
+ {
+ ((const Container*)&(*i))->getInfo( cinfo );
+ i->getInfo( info );
+ }
+ else
+ ret = STORAGE_MDPART_CO_NOT_FOUND;
+ return( ret );
+
+}
+
+
+int Storage::getMdPartInfo( const string& device, deque<MdPartInfo>& plist )
+{
+ int ret = 0;
+ plist.clear();
+ assertInit();
+ MdPartCoIterator it = findMdPartCo(device);
+
+ if( it != mdpCoEnd() )
+ {
+ MdPartCo::MdPartPair p = it->mdpartPair(MdPart::notDeleted);
+
+ for( MdPartCo::MdPartIter i2 = p.begin(); i2 != p.end(); ++i2 )
+ {
+ plist.push_back( MdPartInfo() );
+ i2->getInfo( plist.back() );
+ }
+ }
+ else
+ ret = STORAGE_MDPART_CO_NOT_FOUND;
+ return( ret );
+}
+
+
int Storage::getNfsInfo( dequestorage::NfsInfo& plist )
{
int ret = 0;
@@ -5081,6 +5524,17 @@
return( ret );
}
+Storage::MdPartCoIterator Storage::findMdPartCo( const string& name )
+{
+ assertInit();
+ MdPartCoPair p = mdpCoPair();
+ MdPartCoIterator ret=p.begin();
+ string tname = MdPartCo::undevName(name);
+ while( ret!=p.end() && (ret->deleted() || ret->name()!=tname))
+ ++ret;
+ return( ret );
+}
+
bool Storage::knownDevice( const string& dev, bool disks_allowed )
{
bool ret=true;
@@ -5263,6 +5717,10 @@
case UB_DMRAID:
//ret = removeDmraidCo( name );
break;
+ case UB_MDPART:
+ y2war(device << " used by MD PART");
+ // ret = removeMdPartCo( name );
+ break;
case UB_DMMULTIPATH:
break;
case UB_NONE:
@@ -5279,12 +5737,35 @@
void Storage::rootMounted()
{
- MdCo* md;
root_mounted = true;
if( !root().empty() )
{
- if( haveMd(md) )
- md->syncRaidtab();
+ string d = root() + "/etc";
+ if (!checkDir(d))
+ createPath(d);
+
+ bool have_mds = false;
+
+ MdCo* md;
+ if (haveMd(md))
+ have_mds = true;
+
+ MdPartCoPair p = mdpCoPair();
+ if (!p.empty())
+ have_mds = true;
+
+ if (have_mds)
+ {
+ delete raidtab;
+ raidtab = new EtcRaidtab(root());
+
+ if (haveMd(md))
+ md->syncRaidtab();
+
+ for (MdPartCoIterator it = p.begin(); it != p.end(); ++it)
+ it->syncRaidtab();
+ }
+
if( instsys() )
{
string path = root()+"/etc/fstab";
@@ -5795,14 +6276,24 @@
y2mil("val:" << val);
if (val)
{
- Dm::activate(val);
- MdCo::activate(val, tmpDir());
+ if( MdPartCo::isHandlingDev() == true)
+ {
+ MdPartCo::activate(val, tmpDir());
+ Dm::activate(val);
+ }
+ else
+ {
+ Dm::activate(val);
+ MdPartCo::activate(val, tmpDir());
+ }
+
+
}
LvmVg::activate(val);
if (!val)
{
Dm::activate(val);
- MdCo::activate(val, tmpDir());
+ MdPartCo::activate(val, tmpDir());
}
}
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.h?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.h (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/Storage.h Tue Nov 10 11:33:00 2009
@@ -42,6 +42,8 @@
#include "y2storage/Dmmultipath.h"
#include "y2storage/MdCo.h"
#include "y2storage/Md.h"
+#include "y2storage/MdPartCo.h"
+#include "y2storage/MdPart.h"
#include "y2storage/DmCo.h"
#include "y2storage/LoopCo.h"
#include "y2storage/Loop.h"
@@ -194,6 +196,7 @@
*/
class EtcFstab;
+class EtcRaidtab;
class DiskData;
class Storage : public storage::StorageInterface
@@ -235,6 +238,8 @@
static bool notDeleted( const Container&d ) { return( !d.deleted() ); };
static bool isDmPart( const Container&d )
{ return d.type() == storage::DMRAID || d.type() == storage::DMMULTIPATH; }
+ static bool isMdPart( const Container&d )
+ { return( d.type()==storage::MDPART ); }
static void initDefaultLogger ();
@@ -260,6 +265,7 @@
static bool isPPCMac() { return( is_ppc_mac ); }
static bool isPPCPegasos() { return( is_ppc_pegasos ); }
EtcFstab* getFstab() { return fstab; }
+ EtcRaidtab* getRaidtab() { return raidtab; }
void handleLogFile( const string& name );
static bool testFilesEqual( const string& n1, const string& n2 );
void printInfo( std::ostream& str ) { printInfo( str, "" ); }
@@ -317,6 +323,7 @@
int getLvmLvInfo( const string& name,
dequestorage::LvmLvInfo& plist );
int getMdInfo( dequestorage::MdInfo& plist );
+ int getMdPartInfo( const string& device, dequestorage::MdPartInfo& plist );
int getDmInfo( dequestorage::DmInfo& plist );
int getNfsInfo( dequestorage::NfsInfo& plist );
int getLoopInfo( dequestorage::LoopInfo& plist );
@@ -465,6 +472,12 @@
int computeMdSize(MdType md_type, list<string> devices,
unsigned long long& sizeK);
+ int getMdPartCoInfo( const string& name, MdPartCoInfo& info);
+ int getContMdPartCoInfo( const string& name, ContainerInfo& cinfo,
+ MdPartCoInfo& info);
+ int getMdPartCoStateInfo(const string& name, MdPartCoStateInfo& info);
+ bool useMdForImsm() { return MdPartCo::isHandlingDev(); }
+
int addNfsDevice( const string& nfsDev, const string& opts,
unsigned long long sizeK, const string& mp );
int checkNfsDevice( const string& nfsDev, const string& opts,
@@ -1024,6 +1037,90 @@
}
+// iterators over MdPart container
+ protected:
+ // protected typedefs for iterators over DmPart container
+ typedef CastCheckFncIterator ContainerCMdPartIter;
+ template< class Pred >
+ struct ConstMdPartCoPI { typedef ContainerIter type; };
+ typedef CastCheckFncIterator ContainerMdPartIter;
+ template< class Pred >
+ struct MdPartCoPI { typedef ContainerIter type; };
+ template< class Pred >
+ struct MdPartCoI { typedef ContainerDerIter type; };
+ typedef CheckFnc<const MdPartCo> CheckFncMdPartCo;
+ typedef CheckerIterator< CheckFncMdPartCo, ConstMdPartCoPI<CheckFncMdPartCo>::type,
+ ContainerCMdPartIter, MdPartCo > ConstMdPartCoPIterator;
+ typedef CheckerIterator< CheckFncMdPartCo, MdPartCoPI<CheckFncMdPartCo>::type,
+ ContainerMdPartIter, MdPartCo > MdPartCoPIterator;
+ typedef DerefIterator MdPartCoIterator;
+ typedef IterPair<MdPartCoIterator> MdPartCoPair;
+
+ public:
+ // public typedefs for iterators over MdPart container
+ typedef DerefIterator ConstMdPartCoIterator;
+ template< class Pred >
+ struct ConstMdPartCoI
+ { typedef ContainerDerIter type; };
+ template< class Pred >
+ struct MdPartCoCondIPair { typedef MakeCondIterPair type; };
+ typedef IterPair<ConstMdPartCoIterator> ConstMdPartCoPair;
+
+ // public member functions for iterators over MdPart container
+ ConstMdPartCoPair mdpartCoPair( bool (* CheckFnc)( const MdPartCo& )=NULL ) const
+ {
+ return( ConstMdPartCoPair( mdpartCoBegin( CheckFnc ), mdpartCoEnd( CheckFnc ) ));
+ }
+ ConstMdPartCoIterator mdpartCoBegin( bool (* CheckFnc)( const MdPartCo& )=NULL ) const
+ {
+ IterPair<ContainerCMdPartIter> p( ContainerCMdPartIter( cont.begin(), cont.end() ),
+ ContainerCMdPartIter( cont.begin(), cont.end(), true ));
+ return( ConstMdPartCoIterator( ConstMdPartCoPIterator( p, CheckFnc )) );
+ }
+ ConstMdPartCoIterator mdpartCoEnd( bool (* CheckFnc)( const MdPartCo& )=NULL ) const
+ {
+ IterPair<ContainerCMdPartIter> p( ContainerCMdPartIter( cont.begin(), cont.end() ),
+ ContainerCMdPartIter( cont.begin(), cont.end(), true ));
+ return( ConstMdPartCoIterator( ConstMdPartCoPIterator( p, CheckFnc, true )) );
+ }
+ template< class Pred > typename MdPartCoCondIPair<Pred>::type mdPartCoCondPair( const Pred& p ) const
+ {
+ return( typename MdPartCoCondIPair<Pred>::type( mdpartCoCondBegin( p ), mdpartCoCondEnd( p ) ) );
+ }
+ template< class Pred > typename ConstMdPartCoI<Pred>::type mdpartCoCondBegin( const Pred& p ) const
+ {
+ IterPair<ContainerCMdPartIter> pair( ContainerCMdPartIter( cont.begin(), cont.end() ),
+ ContainerCMdPartIter( cont.begin(), cont.end(), true ));
+ return( typename ConstMdPartCoI<Pred>::type( typename ConstMdPartCoPI<Pred>::type( pair, p )) );
+ }
+ template< class Pred > typename ConstMdPartCoI<Pred>::type mdpartCoCondEnd( const Pred& p ) const
+ {
+ IterPair<ContainerCMdPartIter> pair( ContainerCMdPartIter( cont.begin(), cont.end() ),
+ ContainerCMdPartIter( cont.begin(), cont.end(), true ));
+ return( typename ConstMdPartCoI<Pred>::type( typename ConstMdPartCoPI<Pred>::type( pair, p, true )) );
+ }
+ protected:
+ // protected member functions for iterators over MdPart container
+ MdPartCoPair mdpCoPair( bool (* CheckFnc)( const MdPartCo& )=NULL )
+ {
+ return( MdPartCoPair( mdpCoBegin( CheckFnc ), mdpCoEnd( CheckFnc ) ));
+ }
+ MdPartCoIterator mdpCoBegin( bool (* CheckFnc)( const MdPartCo& )=NULL )
+ {
+ IterPair<ContainerMdPartIter> p( ContainerMdPartIter( cont.begin(), cont.end() ),
+ ContainerMdPartIter( cont.begin(), cont.end(), true ));
+ return( MdPartCoIterator( MdPartCoPIterator( p, CheckFnc )) );
+ }
+ MdPartCoIterator mdpCoEnd( bool (* CheckFnc)( const MdPartCo& )=NULL )
+ {
+ IterPair<ContainerMdPartIter> p( ContainerMdPartIter( cont.begin(), cont.end() ),
+ ContainerMdPartIter( cont.begin(), cont.end(), true ));
+ return( MdPartCoIterator( MdPartCoPIterator( p, CheckFnc, true )) );
+ }
+
+
+
// iterators over volumes
protected:
// protected typedefs for iterators over volumes
@@ -1339,6 +1436,72 @@
return( typename ConstMdI<Pred>::type( typename ConstMdPI<Pred>::type(pair, p, true )) );
}
+///////// iterators over software raid devices - Partitions
+ protected:
+ // protected typedefs for iterators over software raid devices
+ typedef CastIterator ConstMdPartInter;
+ template< class Pred >
+ struct ConstMdPartPI { typedef ContainerIter type; };
+ typedef CheckFnc<const MdPart> CheckFncMdPart;
+ typedef CheckerIterator< CheckFncMdPart, ConstMdPartPI<CheckFncMdPart>::type,
+ ConstMdPartInter, MdPart > ConstMdPartPIterator;
+ public:
+ // public typedefs for iterators over software raid devices
+ template< class Pred >
+ struct ConstMdPartI
+ { typedef ContainerDerIter type; };
+ template< class Pred >
+ struct MdPartCondIPair
+ { typedef MakeCondIterPair type;};
+ typedef DerefIterator ConstMdPartIterator;
+ typedef IterPair<ConstMdPartIterator> ConstMdPartPair;
+
+
+ // public member functions for iterators over software raid devices
+ ConstMdPartPair mdPartPair( bool (* CheckMdPart)( const MdPart& )=NULL ) const
+ {
+ return( ConstMdPartPair( mdPartBegin( CheckMdPart ), mdPartEnd( CheckMdPart ) ));
+ }
+
+ ConstMdPartIterator mdPartBegin( bool (* CheckMdPart)( const MdPart& )=NULL ) const
+ {
+ ConstVolInter b( contPair( isMdPart ) );
+ ConstVolInter e( contPair( isMdPart ), true );
+ IterPair<ConstMdPartInter> p( (ConstMdPartInter(b)), (ConstMdPartInter(e)) );
+ return( ConstMdPartIterator( ConstMdPartPIterator(p, CheckMdPart )));
+ }
+ ConstMdPartIterator mdPartEnd( bool (* CheckMdPart)( const MdPart& )=NULL ) const
+ {
+ ConstVolInter b( contPair( isMdPart ) );
+ ConstVolInter e( contPair( isMdPart ), true );
+ IterPair<ConstMdPartInter> p( (ConstMdPartInter(b)), (ConstMdPartInter(e)) );
+ return( ConstMdPartIterator( ConstMdPartPIterator(p, CheckMdPart, true )));
+ }
+ template< class Pred > typename MdPartCondIPair<Pred>::type mdPartCondPair( const Pred& p ) const
+ {
+ return( typename MdPartCondIPair<Pred>::type( mdPartCondBegin( p ), mdPartCondEnd( p ) ) );
+ }
+ template< class Pred > typename ConstMdPartI<Pred>::type mdPartCondBegin( const Pred& p ) const
+ {
+ ConstVolInter b( contPair( isMdPart ) );
+ ConstVolInter e( contPair( isMdPart ), true );
+ IterPair<ConstMdPartInter> pair( (ConstMdPartInter(b)), (ConstMdPartInter(e)) );
+ return( typename ConstMdPartI<Pred>::type( typename ConstMdPartPI<Pred>::type(pair, p) ) );
+ }
+ template< class Pred > typename ConstMdPartI<Pred>::type mdPartCondEnd( const Pred& p ) const
+ {
+ ConstVolInter b( contPair( isMdPart ) );
+ ConstVolInter e( contPair( isMdPart ), true );
+ IterPair<ConstMdPartInter> pair( (ConstMdPartInter(b)), (ConstMdPartInter(e)) );
+ return( typename ConstMdPartI<Pred>::type( typename ConstMdPartPI<Pred>::type(pair, p, true )) );
+ }
+
+
+
+
+
// iterators over file based loop devices
protected:
// protected typedefs for iterators over file based loop devices
@@ -1673,6 +1836,10 @@
void autodetectDisks( ProcPart& ppart );
void detectMultipath();
void detectMds();
+ void detectMdParts(ProcPart& ppart);
+ //Discovers that platfrom is IMSM and Partitionable RAID Volumes
+ //can be on it
+ bool discoverMdPVols();
void detectLoops( ProcPart& ppart );
void detectNfs( ProcMounts& mounts );
void detectLvmVgs();
@@ -1699,6 +1866,9 @@
DmraidCoIterator findDmraidCo( const string& name );
DmmultipathCoIterator findDmmultipathCo( const string& name );
DmPartCoIterator findDmPartCo( const string& name );
+
+ MdPartCoIterator findMdPartCo( const string& name );
+
bool findVolume( const string& device, ContIterator& c,
VolIterator& v );
bool findVolume( const string& device, VolIterator& v,
@@ -1750,6 +1920,7 @@
static bool is_ppc_pegasos;
CCont cont;
EtcFstab *fstab;
+ EtcRaidtab *raidtab;
CallbackProgressBar progress_bar_cb;
CallbackShowInstallInfo install_info_cb;
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageDefines.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageDefines.h?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageDefines.h (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageDefines.h Tue Nov 10 11:33:00 2009
@@ -73,5 +73,7 @@
#define MODPROBEBIN "/sbin/modprobe"
+#define BLKIDBIN "/sbin/blkid"
+
#endif
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageInterface.h
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageInterface.h?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageInterface.h (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageInterface.h Tue Nov 10 11:33:00 2009
@@ -134,10 +134,14 @@
enum MdParity { PAR_NONE, LEFT_ASYMMETRIC, LEFT_SYMMETRIC,
RIGHT_ASYMMETRIC, RIGHT_SYMMETRIC };
- enum UsedByType { UB_NONE, UB_LVM, UB_MD, UB_DM, UB_DMRAID, UB_DMMULTIPATH };
+ enum MdArrayState { UNKNOWN, CLEAR, INACTIVE, SUSPENDED, READONLY, READ_AUTO,
+ CLEAN, ACTIVE, WRITE_PENDING, ACTIVE_IDLE };
+
+ enum UsedByType { UB_NONE, UB_LVM, UB_MD, UB_DM, UB_DMRAID, UB_DMMULTIPATH,
+ UB_MDPART };
enum CType { CUNKNOWN, DISK, MD, LOOP, LVM, DM, DMRAID, NFSC, DMMULTIPATH,
- COTYPE_LAST_ENTRY };
+ MDPART, COTYPE_LAST_ENTRY };
/**
* typedef for a pointer to a function that is called on progress bar events
@@ -385,6 +389,48 @@
MdStateInfo() {}
bool active;
bool degraded;
+ enum MdArrayState state;
+ };
+
+ /**
+ * Contains info about a software raid device which is a container
+ * for partitions.
+ */
+ struct MdPartCoInfo
+ {
+ MdPartCoInfo() {}
+ DiskInfo d;
+ string devices;
+ string spares; // Spare disks
+ unsigned long minor;
+
+ unsigned level; // RAID level
+ unsigned nr; // MD device number
+ unsigned parity; // Parity (not for all RAID level)
+ string uuid; // MD Device UUID
+ string sb_ver; // Metadata version
+ unsigned long chunk; // Chunksize (strip size)
+ string md_name; // MD Device name (link in /dev/md/)
+ };
+
+ struct MdPartCoStateInfo
+ {
+ MdPartCoStateInfo() {}
+ bool active;
+ bool degraded;
+ enum MdArrayState state; // Few states at one?
+ };
+
+
+ /**
+ * Contains info about a partition on SW RAID device.
+ */
+ struct MdPartInfo
+ {
+ MdPartInfo() {}
+ VolumeInfo v;
+ PartitionAddInfo p;
+ bool part;
};
/**
@@ -554,6 +600,7 @@
STORAGE_RESIZE_INVALID_CONTAINER = -2029,
STORAGE_DMMULTIPATH_CO_NOT_FOUND = -2030,
STORAGE_ZERO_DEVICE_FAILED = -2031,
+ STORAGE_MDPART_CO_NOT_FOUND = -2032,
VOLUME_COMMIT_UNKNOWN_STAGE = -3000,
VOLUME_FSTAB_EMPTY_MOUNT = -3001,
@@ -656,6 +703,15 @@
MD_NO_CHANGE_ON_DISK = -6017,
MD_NO_CREATE_UNKNOWN = -6018,
MD_STATE_NOT_ON_DISK = -6019,
+ MD_PARTITION_NOT_FOUND = -6020,
+
+ MDPART_CHANGE_READONLY = -6100,
+ MDPART_INTERNAL_ERR = -6101,
+ MDPART_INVALID_VOLUME = -6012,
+ MDPART_PARTITION_NOT_FOUND = -6103,
+ MDPART_REMOVE_PARTITION_LIST_ERASE = -6104,
+ MDPART_COMMIT_NOTHING_TODO = -6105,
+ MDPART_NO_REMOVE = -6106,
LOOP_CHANGE_READONLY = -7000,
LOOP_DUPLICATE_FILE = -7001,
@@ -807,6 +863,43 @@
DmmultipathCoInfo& info) = 0;
/**
+ * Query container info for a MDPART container
+ *
+ * @param name name of container, e.g. md126
+ * @param info record that gets filled with MDPART Container special data
+ * @return zero if all is ok, a negative number to indicate an error
+ */
+ virtual int getMdPartCoInfo( const string& name, MdPartCoInfo& info) = 0;
+
+
+ /**
+ * Query container info for a MDPART container
+ *
+ * @param name name of container, e.g. md126
+ * @param cinfo record that gets filled with container general data
+ * @param info record that gets filled with MDPART Container special data
+ * @return zero if all is ok, a negative number to indicate an error
+ */
+ virtual int getContMdPartCoInfo( const string& name, ContainerInfo& cinfo,
+ MdPartCoInfo& info) = 0;
+
+ /**
+ * Checks if Md and MdPart are used for IMSM/ISW SW RAIDs.
+ *
+ * In 'normal mode' it will become true after first MdPart class is
+ * created and it will true until such class exist.
+ * In 'install mode' it will be true:
+ * a) if clean or partitioned IMSM RAIDs were detected and no YesOrNo
+ * callback was registered.
+ * b) if clean or partitioned IMSM RAIDs were detected and user chose
+ * 'yes' when asked to use Md classes for IMSM/ISW RAIDs.
+ *
+ * @return true if IMSM/ISW SW RAIDa are handled by Md/MdPart classes.
+ * False otherwise.
+ */
+ virtual bool useMdForImsm() = 0;
+
+ /**
* Query all volumes found in system
*
* @param infos list of records that get filled with volume info
@@ -851,6 +944,16 @@
virtual int getMdInfo( deque<MdInfo>& plist ) = 0;
/**
+ * Query infos for partitions on raid device in system
+ *
+ * @param device device name of the parent MdPartCo, e.g. /dev/md125
+ * @param plist list of records that get filled with MdPart specific info
+ * @return zero if all is ok, a negative number to indicate an error
+ */
+ virtual int getMdPartInfo( const string& device,
+ deque<MdPartInfo>& plist ) = 0;
+
+ /**
* Query infos for nfs devices in system
*
* @param plist list of records that get filled with nfs info
@@ -1763,6 +1866,18 @@
*/
virtual int getMdStateInfo(const string& name, MdStateInfo& info) = 0;
+ /**
+ * Get state of a MD software raid device.
+ *
+ * @pre This can only be done after the raid has been created on disk.
+ *
+ * @param name name of software raid device (e.g. /dev/md125)
+ * @param info record that gets filled with raid special data
+ * @return zero if all is ok, a negative number to indicate an error
+ */
+ virtual int getMdPartCoStateInfo(const string& name,
+ MdPartCoStateInfo& info) = 0;
+
/**
* Compute the size of a raid device.
*
Modified: branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageTypes.cc
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageTypes.cc?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageTypes.cc (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/libstorage/src/StorageTypes.cc Tue Nov 10 11:33:00 2009
@@ -82,6 +82,7 @@
case UB_LVM:
case UB_MD:
+ case UB_MDPART:
return "/dev/" + ub_name;
case UB_DM:
@@ -105,6 +106,9 @@
case storage::UB_MD:
st = "md";
break;
+ case storage::UB_MDPART:
+ st = "mdpart";
+ break;
case storage::UB_DM:
st = "dm";
break;
Modified: branches/SuSE-Code-11-SP1-Branch/storage/package/yast2-storage.changes
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/package/yast2-storage.changes?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/package/yast2-storage.changes (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/package/yast2-storage.changes Tue Nov 10 11:33:00 2009
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Tue Nov 10 11:28:26 CET 2009 - aschnell@suse.de
+
+- added IMSM support (fate #305883)
+- 2.17.82
+
+-------------------------------------------------------------------
Thu Nov 5 14:30:27 CET 2009 - kmachalkova@suse.cz
- Support for cloning the disk's partition layout (FaTE#303809)
Modified: branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/custom_part_check_generated.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/custom_part_check_generated.ycp?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/custom_part_check_generated.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/custom_part_check_generated.ycp Tue Nov 10 11:33:00 2009
@@ -84,7 +84,7 @@
list<map> part_info = diskinfo["partitions"]:[];
integer cyl_size = diskinfo["cyl_size"]:1000000;
- if (contains([ `CT_DISK, `CT_DMRAID, `CT_DMMULTIPATH ], diskinfo["type"]:`CT_UNKNOWN))
+ if (contains([ `CT_DISK, `CT_DMRAID, `CT_DMMULTIPATH, `CT_MDPART ], diskinfo["type"]:`CT_UNKNOWN))
diskless = false;
foreach( map part, part_info, ``{
Modified: branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-hd.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-hd.ycp?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-hd.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-hd.ycp Tue Nov 10 11:33:00 2009
@@ -21,7 +21,8 @@
{
symbol Predicate(map disk, map partition)
{
- return StorageFields::PredicateDiskType(disk, partition, [`CT_DMRAID, `CT_DMMULTIPATH, `CT_DISK]);
+ return StorageFields::PredicateDiskType(disk, partition, [`CT_DMRAID, `CT_DMMULTIPATH,
+ `CT_MDPART, `CT_DISK]);
}
boolean IsAvailable ( string client )
Modified: branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-main.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-main.ycp?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-main.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/storage/src/include/ep-main.ycp Tue Nov 10 11:33:00 2009
@@ -147,6 +147,7 @@
case `CT_DISK:
case `CT_DMRAID:
case `CT_DMMULTIPATH:
+ case `CT_MDPART:
huhu(disk, `hd, $[ `create : CreateHdPartitionPanel, `handle : HandleHdPartitionPanel ],
$[ `create : CreateHdDiskPanel, `handle : HandleHdDiskPanel ]);
break;
Modified: branches/SuSE-Code-11-SP1-Branch/storage/storage/src/inst_target_selection.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/storage/src/inst_target_selection.ycp?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/storage/src/inst_target_selection.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/storage/src/inst_target_selection.ycp Tue Nov 10 11:33:00 2009
@@ -66,7 +66,7 @@
map usable_target_map = filter(string d, map e, targetMap, {
return Storage::IsPartitionable(e) &&
- !contains([ `UB_DMRAID, `UB_DMMULTIPATH ], e["used_by_type"]:`UB_NONE);
+ !contains([ `UB_DMRAID, `UB_DMMULTIPATH, `UB_MDPART ], e["used_by_type"]:`UB_NONE);
});
integer dskcnt = size(usable_target_map);
Modified: branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/Storage.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/Storage.ycp?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/Storage.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/Storage.ycp Tue Nov 10 11:33:00 2009
@@ -57,6 +57,8 @@
import "LibStorage::DmPartInfo";
import "LibStorage::DmraidInfo";
import "LibStorage::DmmultipathInfo";
+ import "LibStorage::MdPartCoInfo";
+ import "LibStorage::MdPartInfo";
import "LibStorage::NfsInfo";
import "LibStorage::ContainerInfo";
import "LibStorage::DiskInfo";
@@ -83,6 +85,7 @@
LibStorage::DMRAID() : `CT_DMRAID,
LibStorage::DMMULTIPATH() : `CT_DMMULTIPATH,
LibStorage::DM() : `CT_DM,
+ LibStorage::MDPART() : `CT_MDPART,
LibStorage::NFSC() : `CT_NFS
]
];
@@ -94,6 +97,7 @@
LibStorage::UB_MD() : `UB_MD,
LibStorage::UB_DMRAID() : `UB_DMRAID,
LibStorage::UB_DMMULTIPATH() : `UB_DMMULTIPATH,
+ LibStorage::UB_MDPART() : `UB_MDPART,
LibStorage::UB_DM() : `UB_DM
]
];
@@ -166,8 +170,9 @@
map DiskMapVersion = $[];
map DiskMap = $[];
map ClassifiedSettings = $[];
-map type_order = $[ `CT_DISK : 0, `CT_MD : 1, `CT_DMRAID : 2, `CT_DMMULTIPATH : 3,
- `CT_LOOP : 4, `CT_DM : 5, `CT_LVM : 6, `CT_NFS : 7 ];
+map type_order = $[ `CT_DISK : 0, `CT_MD : 1, `CT_MDPART : 2, `CT_DMRAID : 3,
+ `CT_DMMULTIPATH : 4, `CT_LOOP : 5, `CT_DM : 6, `CT_LVM : 7,
+ `CT_NFS : 8 ];
list<string> hw_packages = [];
list<string> no_propose_disks = nil;
@@ -576,7 +581,12 @@
}
else if( search( device, "/dev/md" )==0 && size(ls)==2 )
{
- dlen = 7;
+ integer pos = find(device, "p");
+ y2milestone("device:%1 pos:%2", device, pos);
+ if (pos == nil)
+ dlen = 7;
+ else
+ dlen = pos;
}
else if( search( device, "/dev/loop" )==0 )
{
@@ -1558,6 +1568,21 @@
return( p );
}
+map mdPartMap(any info, map p)
+{
+ any vinfo = LibStorage::MdPartInfo::swig_v_get(info);
+ p = volumeMap(vinfo, p);
+ p["nr"] = 0;
+ boolean part = LibStorage::MdPartInfo::swig_part_get(info);
+ if (part)
+ {
+ any pinfo = LibStorage::MdPartInfo::swig_p_get(info);
+ p = partAddMap(pinfo, p);
+ }
+ y2milestone("mdPartMap ret:%1", p);
+ return p;
+}
+
map getContainerInfo( map c )
{
y2milestone( "getContainerInfo %1", c );
@@ -1653,6 +1678,46 @@
c["partitions"] = add( c["partitions"]:[], p );
});
}
+ else if( c["type"]:`CT_UNKNOWN == `CT_MDPART )
+ {
+ list<any> pinfos = [];
+ any infos = LibStorage::MdPartCoInfo::new("LibStorage::MdPartCoInfo");
+ string d = c["device"]:"";
+ ret = LibStorage::StorageInterface::getMdPartCoInfo(sint, d, infos);
+ if (ret == 0)
+ {
+ any dinfo = LibStorage::MdPartCoInfo::swig_d_get(infos);
+ c = diskMap(dinfo, c);
+ }
+ else
+ y2warning( "disk \"%1\" ret:%2", c["device"]:"", ret );
+
+ integer t = LibStorage::MdPartCoInfo::swig_level_get(infos);
+ c["raid_type"] = substring(sformat("%1", toSymbol(conv_mdtype, t)), 1);
+ if (c["raid_type"]:"" == "raid5")
+ {
+ t = LibStorage::MdPartCoInfo::swig_parity_get(infos);
+ symbol pt = toSymbol(conv_mdparity, t);
+ if (pt != `par_none)
+ c["parity_algorithm"] = substring(sformat("%1", pt), 1);
+ }
+ t = LibStorage::MdPartCoInfo::swig_chunk_get(infos);
+ if (t > 0)
+ {
+ c["chunk_size"] = t;
+ }
+ c["sb_ver"] = LibStorage::MdPartCoInfo::swig_sb_ver_get(infos);
+
+ c["partitions"] = [];
+ ret = LibStorage::StorageInterface::getMdPartInfo(sint, d, pinfos);
+ foreach(any info, pinfos, {
+ map p = $[];
+ p = mdPartMap(info, p);
+ p["fstype"] = Partitions::raid_name;
+ if (p["nr"]:-1 != 0)
+ c["partitions"] = add(c["partitions"]:[], p);
+ });
+ }
else if( c["type"]:`CT_UNKNOWN == `CT_LVM )
{
list<any> pinfos = [];
@@ -1839,7 +1904,7 @@
global boolean IsDiskType(symbol t)
{
- return contains([ `CT_DISK, `CT_DMRAID, `CT_DMMULTIPATH ], t);
+ return contains([ `CT_DISK, `CT_DMRAID, `CT_DMMULTIPATH, `CT_MDPART ], t);
}
/**
@@ -3202,7 +3267,7 @@
global boolean IsPartType(symbol t)
{
- return t == `CT_DMRAID || t == `CT_DMMULTIPATH || t == `CT_DISK;
+ return t == `CT_DMRAID || t == `CT_DMMULTIPATH || t == `CT_DISK || t == `CT_MDPART;
}
@@ -3589,8 +3654,8 @@
});
keys = maplist( string k, any e, tg, ``(k));
keys = sort( string a, string b, keys,
- ``( type_order[tg[a,"type"]:`CT_UNKNOWN]:6 >
- type_order[tg[b,"type"]:`CT_UNKNOWN]:6 ));
+ ``( type_order[tg[a,"type"]:`CT_UNKNOWN]:9 >
+ type_order[tg[b,"type"]:`CT_UNKNOWN]:9 ));
y2milestone( "SetTargetMap keys %1", keys );
foreach( string k, keys,
``{
@@ -3620,8 +3685,8 @@
});
keys = maplist( string k, any e, target, ``(k));
keys = sort( string a, string b, keys,
- ``( type_order[target[a,"type"]:`CT_UNKNOWN]:6 >
- type_order[target[b,"type"]:`CT_UNKNOWN]:6 ));
+ ``( type_order[target[a,"type"]:`CT_UNKNOWN]:9 >
+ type_order[target[b,"type"]:`CT_UNKNOWN]:9 ));
y2milestone( "SetTargetMap keys %1", keys );
foreach( string k, keys,
``{
@@ -3654,8 +3719,8 @@
});
keys = maplist( string k, any e, target, ``(k));
keys = sort( string a, string b, keys,
- ``( type_order[target[a,"type"]:`CT_UNKNOWN]:6 <
- type_order[target[b,"type"]:`CT_UNKNOWN]:6 ));
+ ``( type_order[target[a,"type"]:`CT_UNKNOWN]:9 <
+ type_order[target[b,"type"]:`CT_UNKNOWN]:9 ));
y2milestone( "SetTargetMap keys %1", keys );
foreach( string k, keys,
``{
@@ -4276,7 +4341,7 @@
global boolean IsPartitionable( map entry )
{
return entry["type"]:`CT_UNKNOWN==`CT_DMRAID || entry["type"]:`CT_UNKNOWN==`CT_DMMULTIPATH ||
- IsRealDisk( entry );
+ entry["type"]:`CT_UNKNOWN==`CT_MDPART || IsRealDisk( entry );
}
global define boolean DeviceRealDisk( string device )
@@ -5837,6 +5902,8 @@
need_crypt = true;
if( e["type"]:`CT_UNKNOWN==`CT_MD && size(e["partitions"]:[])>0 )
need_md = true;
+ if( e["type"]:`CT_UNKNOWN==`CT_MDPART )
+ need_md = true;
if( e["type"]:`CT_UNKNOWN==`CT_LVM )
need_lvm = true;
if( e["type"]:`CT_UNKNOWN==`CT_DMRAID )
Modified: branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/StorageFields.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/StorageFields.ycp?rev=59454&r1=59453&r2=59454&view=diff
==============================================================================
--- branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/StorageFields.ycp (original)
+++ branches/SuSE-Code-11-SP1-Branch/storage/storage/src/modules/StorageFields.ycp Tue Nov 10 11:33:00 2009
@@ -25,13 +25,13 @@
*/
global void IterateTargetMap(map target_map, void(map, map) callback)
{
- const map disk_order = $[ `CT_DMRAID : 0, `CT_DMMULTIPATH : 1, `CT_DISK : 2,
- `CT_MD : 3, `CT_LOOP : 4, `CT_LVM : 5, `CT_DM : 6, `CT_NFS : 8 ];
+ const map disk_order = $[ `CT_DMRAID : 0, `CT_DMMULTIPATH : 1, `CT_MDPART : 2, `CT_DISK : 3,
+ `CT_MD : 4, `CT_LOOP : 5, `CT_LVM : 6, `CT_DM : 7, `CT_NFS : 8 ];
list<string> keys = maplist(string dev, map disk, target_map, { return dev; });
keys = sort(string a, string b, keys, {
- integer oa = disk_order[target_map[a,"type"]:`CT_UNKNOWN]:8;
- integer ob = disk_order[target_map[b,"type"]:`CT_UNKNOWN]:8;
+ integer oa = disk_order[target_map[a, "type"]:`CT_UNKNOWN]:9;
+ integer ob = disk_order[target_map[b, "type"]:`CT_UNKNOWN]:9;
return (oa==ob) ? (a