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 unsigned numPartitions() const;
00097 bool isDasd() const { return( nm.find("dasd")==0 ); }
00098 bool isIScsi() const { return transport == ISCSI; }
00099 static bool isIScsi(const Disk& d) { return d.isIScsi(); }
00100 bool isLogical( unsigned nr ) const;
00101 bool detect(SystemInfo& systeminfo);
00102 static storage::CType staticType() { return storage::DISK; }
00103 friend std::ostream& operator<< (std::ostream&, const Disk& );
00104 void triggerUdevUpdate() const;
00105
00106 static bool needP( const string& dev );
00107 static string partNaming(const string& disk);
00108 void setUdevData(const string& path, const list<string>& id);
00109 virtual int createPartition( storage::PartitionType type, long unsigned start,
00110 long unsigned len, string& device,
00111 bool checkRelaxed=false );
00112 int createPartition( long unsigned len, string& device,
00113 bool checkRelaxed=false );
00114 int createPartition( storage::PartitionType type, string& device );
00115 virtual int removePartition( unsigned nr );
00116 virtual int changePartitionId( unsigned nr, unsigned id );
00117 virtual int initializeDisk( bool ) { return storage::DISK_INIT_NOT_POSSIBLE; }
00118 bool initializeDisk() const { return init_disk; }
00119 void resetInitDisk() { init_disk=false; }
00120 int forgetChangePartitionId( unsigned nr );
00121 int changePartitionArea(unsigned nr, const Region& cylRegion, bool checkRelaxed = false);
00122 int nextFreePartition(storage::PartitionType type, unsigned& nr,
00123 string& device) const;
00124 int destroyPartitionTable( const string& new_label );
00125 unsigned availablePartNumber(storage::PartitionType type = storage::PRIMARY) const;
00126 virtual void getCommitActions(list<commitAction>& l) const;
00127 virtual void getToCommit(storage::CommitStage stage, list<const Container*>& col,
00128 list<const Volume*>& vol) const;
00129 virtual int commitChanges( storage::CommitStage stage );
00130 int commitChanges( storage::CommitStage stage, Volume* vol );
00131 int freeCylindersAroundPartition(const Partition* p, unsigned long& freeCylsBefore,
00132 unsigned long& freeCylsAfter) const;
00133 virtual int resizePartition( Partition* p, unsigned long newCyl );
00134 int resizeVolume( Volume* v, unsigned long long newSize );
00135 int removeVolume( Volume* v );
00136 void getUnusedSpace(std::list<Region>& free, bool all = true,
00137 bool logical = false) const;
00138 unsigned int numPrimary() const;
00139 bool hasExtended() const;
00140 unsigned int numLogical() const;
00141 Text setDiskLabelText(bool doing) const;
00142
00143 unsigned long long cylinderToKb(unsigned long cylinder) const
00144 { return geometry.cylinderToKb(cylinder); }
00145 unsigned long kbToCylinder(unsigned long long kb) const
00146 { return geometry.kbToCylinder(kb); }
00147
00148 unsigned long long sectorToKb(unsigned long long sector) const
00149 { return geometry.sectorToKb(sector); }
00150 unsigned long long kbToSector(unsigned long long kb) const
00151 { return geometry.kbToSector(kb); }
00152
00153 string getPartName(unsigned nr) const;
00154 string getPartDevice(unsigned nr) const;
00155
00156 void getInfo( storage::DiskInfo& info ) const;
00157 bool equalContent( const Container& rhs ) const;
00158
00159 void logDifference(std::ostream& log, const Disk& rhs) const;
00160 virtual void logDifferenceWithVolumes(std::ostream& log, const Container& rhs) const;
00161
00162 bool FakeDisk() const { return(range==1); }
00163
00164 static std::pair<string,unsigned> getDiskPartition( const string& dev );
00165
00166 static bool getDlabelCapabilities(const string& dlabel,
00167 storage::DlabelCapabilities& dlabelcapabilities);
00168
00169 struct SysfsInfo
00170 {
00171 unsigned long range;
00172 unsigned long long size;
00173 bool vbd;
00174 };
00175
00176 static bool getSysfsInfo(const string& sysfsdir, SysfsInfo& sysfsinfo);
00177
00178 protected:
00179
00180
00181
00182 typedef CastIterator<VIter, Partition *> PartInter;
00183 typedef CastIterator<CVIter, const Partition *> PartCInter;
00184 template< class Pred >
00185 struct PartitionPI { typedef ContainerIter<Pred, PartInter> type; };
00186 template< class Pred >
00187 struct PartitionCPI { typedef ContainerIter<Pred, PartCInter> type; };
00188 typedef CheckFnc<const Partition> CheckFncPartition;
00189 typedef CheckerIterator< CheckFncPartition, PartitionPI<CheckFncPartition>::type,
00190 PartInter, Partition > PartPIterator;
00191 typedef CheckerIterator< CheckFncPartition, PartitionCPI<CheckFncPartition>::type,
00192 PartCInter, const Partition > PartCPIterator;
00193 typedef DerefIterator<PartPIterator,Partition> PartIter;
00194 typedef IterPair<PartIter> PartPair;
00195
00196 PartPair partPair( bool (* CheckPart)( const Partition& )=NULL)
00197 {
00198 return( PartPair( partBegin( CheckPart ), partEnd( CheckPart ) ));
00199 }
00200 PartIter partBegin( bool (* CheckPart)( const Partition& )=NULL)
00201 {
00202 IterPair<PartInter> p( (PartInter(begin())), (PartInter(end())) );
00203 return( PartIter( PartPIterator( p, CheckPart )) );
00204 }
00205 PartIter partEnd( bool (* CheckPart)( const Partition& )=NULL)
00206 {
00207 IterPair<PartInter> p( (PartInter(begin())), (PartInter(end())) );
00208 return( PartIter( PartPIterator( p, CheckPart, true )) );
00209 }
00210
00211 public:
00212 typedef DerefIterator<PartCPIterator,const Partition> ConstPartIter;
00213 typedef IterPair<ConstPartIter> ConstPartPair;
00214 ConstPartPair partPair( bool (* CheckPart)( const Partition& )=NULL) const
00215 {
00216 return( ConstPartPair( partBegin( CheckPart ), partEnd( CheckPart ) ));
00217 }
00218 ConstPartIter partBegin( bool (* CheckPart)( const Partition& )=NULL) const
00219 {
00220 IterPair<PartCInter> p( (PartCInter(begin())), (PartCInter(end())) );
00221 return( ConstPartIter( PartCPIterator( p, CheckPart )) );
00222 }
00223 ConstPartIter partEnd( bool (* CheckPart)( const Partition& )=NULL) const
00224 {
00225 IterPair<PartCInter> p( (PartCInter(begin())), (PartCInter(end())) );
00226 return( ConstPartIter( PartCPIterator( p, CheckPart, true )) );
00227 }
00228
00229 protected:
00230
00231 virtual bool detectGeometry();
00232 virtual bool detectPartitions(SystemInfo& systeminfo);
00233 bool getSysfsInfo();
00234 int checkSystemError( const string& cmd_line, const SystemCmd& cmd ) const;
00235 int execCheckFailed( const string& cmd_line, bool stop_hald=true );
00236 int execCheckFailed( SystemCmd& cmd, const string& cmd_line,
00237 bool stop_hald=true );
00238 bool checkPartedOutput(SystemInfo& systeminfo);
00239 list<string> partitionsKernelKnowns(const ProcParts& parts) const;
00240 bool checkPartedValid(SystemInfo& systeminfo, list<Partition*>& pl,
00241 unsigned long& rng) const;
00242 virtual bool checkPartitionsValid(SystemInfo& systeminfo, const list<Partition*>& pl) const;
00243
00244 bool callDelpart(unsigned nr) const;
00245 bool callAddpart(unsigned nr, const Region& blkRegion) const;
00246
00247 bool getPartedValues( Partition *p ) const;
00248 bool getPartedSectors( const Partition *p, unsigned long long& start,
00249 unsigned long long& end ) const;
00250 const Partition * getPartitionAfter( const Partition * p ) const;
00251 void addPartition( unsigned num, unsigned long long sz,
00252 SystemInfo& ppart );
00253 virtual void print( std::ostream& s ) const { s << *this; }
00254 virtual Container* getCopy() const { return( new Disk( *this ) ); }
00255 virtual void redetectGeometry();
00256 void changeNumbers( const PartIter& b, const PartIter& e,
00257 unsigned start, int incr );
00258 int createChecks(PartitionType& type, const Region& cylRegion, bool checkRelaxed) const;
00259 void removePresentPartitions();
00260 void removeFromMemory();
00261 void enlargeGpt();
00262
00263
00264 unsigned long long procExtendedBlks() const;
00265
00266 virtual int doCreate( Volume* v );
00267 virtual int doRemove( Volume* v );
00268 virtual int doResize( Volume* v );
00269 virtual int doSetType( Volume* v );
00270 virtual int doCreateLabel();
00271
00272 virtual void logData(const string& Dir) const;
00273
00274 void setLabelData( const string& );
00275
00276 virtual string defaultLabel() const;
00277
00278 static const label_info labels[];
00279 static const string p_disks[];
00280
00281 Geometry geometry;
00282 Geometry new_geometry;
00283
00284 string label;
00285 string udev_path;
00286 list<string> udev_id;
00287 string detected_label;
00288 string logfile_name;
00289 unsigned max_primary;
00290 bool ext_possible;
00291 unsigned max_logical;
00292 bool init_disk;
00293 Transport transport;
00294 bool dmp_slave;
00295 bool no_addpart;
00296 bool gpt_enlarge;
00297 unsigned long range;
00298 bool del_ptable;
00299
00300 mutable storage::DiskInfo info;
00301
00302 private:
00303
00304 Disk& operator=(const Disk&);
00305
00306 };
00307
00308 }
00309
00310 #endif