00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef DISK_H
00024 #define DISK_H
00025
00026 #include <list>
00027
00028 #include "storage/Container.h"
00029 #include "storage/Partition.h"
00030 #include "storage/Geometry.h"
00031
00032
00033 namespace storage
00034 {
00035 using std::list;
00036
00037
00038 class Storage;
00039 class SystemCmd;
00040 class SystemInfo;
00041 class ArchInfo;
00042 class ProcParts;
00043 class Region;
00044
00045
00046 class Disk : public Container
00047 {
00048 friend class Storage;
00049 friend class DmPartCo;
00050 friend class MdPartCo;
00051
00052 struct label_info
00053 {
00054 string name;
00055 bool extended;
00056 unsigned primary;
00057 unsigned logical;
00058 unsigned long long max_sectors;
00059 };
00060
00061 public:
00062
00063 Disk(Storage* s, const string& name, const string& device, unsigned long long Size,
00064 SystemInfo& systeminfo);
00065 Disk(Storage* s, const string& name, const string& device, unsigned num,
00066 unsigned long long Size, SystemInfo& systeminfo);
00067 Disk(Storage* s, const xmlNode* node);
00068 Disk(const Disk& c);
00069 virtual ~Disk();
00070
00071 void saveData(xmlNode* node) const;
00072
00073 unsigned long cylinders() const { return geometry.cylinders; }
00074 unsigned heads() const { return geometry.heads; }
00075 unsigned sectors() const { return geometry.sectors; }
00076 unsigned sectorSize() const { return geometry.sector_size; }
00077 const Geometry& getGeometry() const { return geometry; }
00078
00079 Region usableCylRegion() const;
00080
00081 unsigned long numMinor() const { return range; }
00082 unsigned maxPrimary() const { return max_primary; }
00083 bool extendedPossible() const { return ext_possible; }
00084 unsigned maxLogical() const { return max_logical; }
00085 const string& labelName() const { return label; }
00086 virtual string udevPath() const { return udev_path; }
00087 virtual list<string> udevId() const { return udev_id; }
00088 void setSlave( bool val=true ) { dmp_slave=val; }
00089 void setAddpart( bool val=true ) { no_addpart=!val; }
00090 void setNumMinor( unsigned long val ) { range=val; }
00091
00092 virtual string procName() const { return nm; }
00093 virtual string sysfsPath() const;
00094 static string sysfsPath( const string& device );
00095
00096
00097 Region detectSysfsBlkRegion(bool log_error = true) const;
00098
00099 unsigned numPartitions() const;
00100 bool isDasd() const { return( nm.find("dasd")==0 ); }
00101 bool isIScsi() const { return transport == ISCSI; }
00102 static bool isIScsi(const Disk& d) { return d.isIScsi(); }
00103 bool isLogical( unsigned nr ) const;
00104 bool detect(SystemInfo& systeminfo);
00105 static storage::CType staticType() { return storage::DISK; }
00106 friend std::ostream& operator<< (std::ostream&, const Disk& );
00107 void triggerUdevUpdate() const;
00108
00109 static bool needP( const string& dev );
00110 static string partNaming(const string& disk);
00111 void setUdevData(const string& path, const list<string>& id);
00112 virtual int createPartition( storage::PartitionType type, long unsigned start,
00113 long unsigned len, string& device,
00114 bool checkRelaxed=false );
00115 int createPartition( long unsigned len, string& device,
00116 bool checkRelaxed=false );
00117 int createPartition( storage::PartitionType type, string& device );
00118 virtual int removePartition( unsigned nr );
00119 virtual int changePartitionId( unsigned nr, unsigned id );
00120 virtual int initializeDisk( bool ) { return storage::DISK_INIT_NOT_POSSIBLE; }
00121 bool initializeDisk() const { return init_disk; }
00122 void resetInitDisk() { init_disk=false; }
00123 int forgetChangePartitionId( unsigned nr );
00124 int changePartitionArea(unsigned nr, const Region& cylRegion, bool checkRelaxed = false);
00125 int nextFreePartition(storage::PartitionType type, unsigned& nr,
00126 string& device) const;
00127 int destroyPartitionTable( const string& new_label );
00128 unsigned availablePartNumber(storage::PartitionType type = storage::PRIMARY) const;
00129 virtual void getCommitActions(list<commitAction>& l) const;
00130 virtual void getToCommit(storage::CommitStage stage, list<const Container*>& col,
00131 list<const Volume*>& vol) const;
00132 virtual int commitChanges( storage::CommitStage stage );
00133 int commitChanges( storage::CommitStage stage, Volume* vol );
00134 int freeCylindersAroundPartition(const Partition* p, unsigned long& freeCylsBefore,
00135 unsigned long& freeCylsAfter) const;
00136 virtual int resizePartition( Partition* p, unsigned long newCyl );
00137 int resizeVolume( Volume* v, unsigned long long newSize );
00138 int removeVolume( Volume* v );
00139 void getUnusedSpace(std::list<Region>& free, bool all = true,
00140 bool logical = false) const;
00141 unsigned int numPrimary() const;
00142 bool hasExtended() const;
00143 unsigned int numLogical() const;
00144 Text setDiskLabelText(bool doing) const;
00145
00146 unsigned long long cylinderToKb(unsigned long cylinder) const
00147 { return geometry.cylinderToKb(cylinder); }
00148 unsigned long kbToCylinder(unsigned long long kb) const
00149 { return geometry.kbToCylinder(kb); }
00150
00151 unsigned long long sectorToKb(unsigned long long sector) const
00152 { return geometry.sectorToKb(sector); }
00153 unsigned long long kbToSector(unsigned long long kb) const
00154 { return geometry.kbToSector(kb); }
00155
00156 string getPartName(unsigned nr) const;
00157 string getPartDevice(unsigned nr) const;
00158
00159 void getInfo( storage::DiskInfo& info ) const;
00160 bool equalContent( const Container& rhs ) const;
00161
00162 void logDifference(std::ostream& log, const Disk& rhs) const;
00163 virtual void logDifferenceWithVolumes(std::ostream& log, const Container& rhs) const;
00164
00165 bool FakeDisk() const { return(range==1); }
00166
00167 static std::pair<string,unsigned> getDiskPartition( const string& dev );
00168
00169 static bool getDlabelCapabilities(const string& dlabel,
00170 storage::DlabelCapabilities& dlabelcapabilities);
00171
00172 struct SysfsInfo
00173 {
00174 unsigned long range;
00175 unsigned long long size;
00176 bool vbd;
00177 };
00178
00179 static bool getSysfsInfo(const string& sysfsdir, SysfsInfo& sysfsinfo);
00180 static string devToSysfs(const string& nm);
00181 static string sysfsToDev(const string& nm);
00182
00183 protected:
00184
00185
00186
00187 typedef CastIterator<VIter, Partition *> PartInter;
00188 typedef CastIterator<CVIter, const Partition *> PartCInter;
00189 template< class Pred >
00190 struct PartitionPI { typedef ContainerIter<Pred, PartInter> type; };
00191 template< class Pred >
00192 struct PartitionCPI { typedef ContainerIter<Pred, PartCInter> type; };
00193 typedef CheckFnc<const Partition> CheckFncPartition;
00194 typedef CheckerIterator< CheckFncPartition, PartitionPI<CheckFncPartition>::type,
00195 PartInter, Partition > PartPIterator;
00196 typedef CheckerIterator< CheckFncPartition, PartitionCPI<CheckFncPartition>::type,
00197 PartCInter, const Partition > PartCPIterator;
00198 typedef DerefIterator<PartPIterator,Partition> PartIter;
00199 typedef IterPair<PartIter> PartPair;
00200
00201 PartPair partPair( bool (* CheckPart)( const Partition& )=NULL)
00202 {
00203 return( PartPair( partBegin( CheckPart ), partEnd( CheckPart ) ));
00204 }
00205 PartIter partBegin( bool (* CheckPart)( const Partition& )=NULL)
00206 {
00207 IterPair<PartInter> p( (PartInter(begin())), (PartInter(end())) );
00208 return( PartIter( PartPIterator( p, CheckPart )) );
00209 }
00210 PartIter partEnd( bool (* CheckPart)( const Partition& )=NULL)
00211 {
00212 IterPair<PartInter> p( (PartInter(begin())), (PartInter(end())) );
00213 return( PartIter( PartPIterator( p, CheckPart, true )) );
00214 }
00215
00216 public:
00217 typedef DerefIterator<PartCPIterator,const Partition> ConstPartIter;
00218 typedef IterPair<ConstPartIter> ConstPartPair;
00219 ConstPartPair partPair( bool (* CheckPart)( const Partition& )=NULL) const
00220 {
00221 return( ConstPartPair( partBegin( CheckPart ), partEnd( CheckPart ) ));
00222 }
00223 ConstPartIter partBegin( bool (* CheckPart)( const Partition& )=NULL) const
00224 {
00225 IterPair<PartCInter> p( (PartCInter(begin())), (PartCInter(end())) );
00226 return( ConstPartIter( PartCPIterator( p, CheckPart )) );
00227 }
00228 ConstPartIter partEnd( bool (* CheckPart)( const Partition& )=NULL) const
00229 {
00230 IterPair<PartCInter> p( (PartCInter(begin())), (PartCInter(end())) );
00231 return( ConstPartIter( PartCPIterator( p, CheckPart, true )) );
00232 }
00233
00234 protected:
00235
00236 virtual bool detectGeometry();
00237 virtual bool detectPartitions(SystemInfo& systeminfo);
00238 bool getSysfsInfo();
00239 int checkSystemError( const string& cmd_line, const SystemCmd& cmd ) const;
00240 int execCheckFailed( const string& cmd_line, bool stop_hald=true );
00241 int execCheckFailed( SystemCmd& cmd, const string& cmd_line,
00242 bool stop_hald=true );
00243 bool checkPartedOutput(SystemInfo& systeminfo);
00244 list<string> partitionsKernelKnowns(const ProcParts& parts) const;
00245 bool checkPartedValid(SystemInfo& systeminfo, list<Partition*>& pl,
00246 unsigned long& rng) const;
00247 virtual bool checkPartitionsValid(SystemInfo& systeminfo, const list<Partition*>& pl) const;
00248 bool checkFakePartition(SystemInfo& systeminfo, const list<Partition*>& pl) const;
00249
00250 bool callDelpart(unsigned nr) const;
00251 bool callAddpart(unsigned nr, const Region& blkRegion) const;
00252
00253 bool getPartedValues( Partition *p ) const;
00254 bool getPartedSectors( const Partition *p, unsigned long long& start,
00255 unsigned long long& end ) const;
00256 const Partition * getPartitionAfter( const Partition * p ) const;
00257 void addPartition( unsigned num, unsigned long long sz,
00258 SystemInfo& ppart );
00259 virtual void print( std::ostream& s ) const { s << *this; }
00260 virtual Container* getCopy() const { return( new Disk( *this ) ); }
00261 virtual void redetectGeometry();
00262 void changeNumbers( const PartIter& b, const PartIter& e,
00263 unsigned start, int incr );
00264 int createChecks(PartitionType& type, const Region& cylRegion, bool checkRelaxed) const;
00265 void removePresentPartitions();
00266 void removeFromMemory();
00267 void enlargeGpt();
00268
00269
00270 unsigned long long procExtendedBlks() const;
00271
00272 virtual int doCreate( Volume* v );
00273 virtual int doRemove( Volume* v );
00274 virtual int doResize( Volume* v );
00275 virtual int doSetType( Volume* v );
00276 virtual int doCreateLabel();
00277
00278 virtual void logData(const string& Dir) const;
00279
00280 void setLabelData( const string& );
00281
00282 virtual string defaultLabel() const;
00283
00284 static const label_info labels[];
00285 static const string p_disks[];
00286
00287 Geometry geometry;
00288 Geometry new_geometry;
00289
00290 string label;
00291 string udev_path;
00292 list<string> udev_id;
00293 string detected_label;
00294 string logfile_name;
00295 unsigned max_primary;
00296 bool ext_possible;
00297 unsigned max_logical;
00298 bool init_disk;
00299 Transport transport;
00300 bool dmp_slave;
00301 bool no_addpart;
00302 bool gpt_enlarge;
00303 unsigned long range;
00304 bool del_ptable;
00305 bool has_fake_partition;
00306
00307 mutable storage::DiskInfo info;
00308
00309 private:
00310
00311 Disk& operator=(const Disk&);
00312
00313 };
00314
00315 }
00316
00317 #endif