ó i'dWc@s£ddljZddlmZmZmZmZmZddlm Z ddl m Z ddl m Z mZddlmZdZd Zd e fd „ƒYZdS( iÿÿÿÿN(t FD_NUMPARTt MAX_EXT_PARTStV_BACKUPtV_BOOTtV_NUMPAR(tEFI_NUMUSERPAR(t EFI_MAXPAR(t ShadowListtShadowExceptionBase(tSizei?i€itShadowPhysicalcBs5eZdZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZd efd „ƒYZd efd „ƒYZ d efd„ƒYZ defd„ƒYZ defd„ƒYZ defd„ƒYZ defd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd„ƒYZdefd „ƒYZd!efd"„ƒYZd#efd$„ƒYZd%efd&„ƒYZd'efd(„ƒYZd)efd*„ƒYZd+efd,„ƒYZd-efd.„ƒYZd/efd0„ƒYZd1efd2„ƒYZd3efd4„ƒYZd5efd6„ƒYZd7efd8„ƒYZd9efd:„ƒYZ d;efd<„ƒYZ!d=efd>„ƒYZ"d?efd@„ƒYZ#dAefdB„ƒYZ$dC„Z%dD„Z&dE„Z'dF„Z(dG„Z)dH„Z*dI„Z+dJ„Z,dK„Z-RS(Lsj ShadowPhysical - class to hold and validate Physical objects (GPTPartition, Partition and Slice) tWholeDiskIsTrueErrorcBseZd„ZRS(cCsddd|_dS(Ns-whole_disk attribute for this Disk is set to s,'true'. GPTPartitions, partitions or slices s!cannot be specified for this Disk(tvalue(tself((s physical.pyt__init__0s(t__name__t __module__R(((s physical.pyR /stGPTPartitionInUseErrorcBseZd„ZRS(cCsD|dd}d|kr3|d|dd7}nd||_dS(Ntused_byit used_names: %ss$GPT partition currently in use by %s(R (R tin_usets((s physical.pyR7s (RRR(((s physical.pyR6stDuplicateGPTPartitionNameErrorcBseZd„ZRS(cCsd||_dS(Ns&GPT partition name %s already inserted(R (R t gpart_name((s physical.pyR>s(RRR(((s physical.pyR=stInvalidGPTPartitionNameErrorcBseZd„ZRS(cCsd|d||_dS(Ns&Invalid name: '%s' for GPT partition s on disk: %s(R (R tnametctd((s physical.pyRBs(RRR(((s physical.pyRAst#InvalidGPTPartitionStartSectorErrorcBseZd„ZRS(cCs d|_dS(Ns.Invalid entry for GPT partition's start_sector(R (R ((s physical.pyRGs(RRR(((s physical.pyRFstOverlappingGPTPartitionErrorcBseZd„ZRS(cCsd|d||_dS(NsGPT partition %s overlaps withs existing GPT partition: %s(R (R tpartition_nametexisting_partition((s physical.pyRKs(RRR(((s physical.pyRJst OverlappingGPTPartitionVdevErrorcBseZd„ZRS(cCsdd|_dS(Ns)GPT partition in_vdev attribute overlaps s with parent(R (R ((s physical.pyRPs(RRR(((s physical.pyROst!OverlappingGPTPartitionZpoolErrorcBseZd„ZRS(cCsdd|_dS(Ns*GPT partition in_zpool attribute overlaps s with parent(R (R ((s physical.pyRUs(RRR(((s physical.pyR TstGPTPartitionTypeMissingErrorcBseZd„ZRS(cCs d|_dS(Ns(GPT partition has invalid partition type(R (R ((s physical.pyRZs(RRR(((s physical.pyR!YstTooManyGPTPartitionsErrorcBseZd„ZRS(cCsdt|_dS(Ns&Only %d GPT partitions may be inserted(RR (R ((s physical.pyR^s(RRR(((s physical.pyR"]stOverlappingSliceErrorcBseZd„ZRS(cCsd||f|_dS(Ns)Slice %s overlaps with existing slice: %s(R (R t slice_nametexisting_slice((s physical.pyRds(RRR(((s physical.pyR#cstOverlappingSliceZpoolErrorcBseZd„ZRS(cCs d|_dS(Ns-Slice in_zpool attribute overlaps with parent(R (R ((s physical.pyRis(RRR(((s physical.pyR&hstOverlappingSliceVdevErrorcBseZd„ZRS(cCs d|_dS(Ns,Slice in_vdev attribute overlaps with parent(R (R ((s physical.pyRms(RRR(((s physical.pyR'lstSliceTooLargeErrorcBseZd„ZRS(cCs d|_dS(NsSlice too large(R (R ((s physical.pyRqs(RRR(((s physical.pyR(pstDuplicateSliceNameErrorcBseZd„ZRS(cCsd||_dS(NsSlice name %s already inserted(R (R R$((s physical.pyRus(RRR(((s physical.pyR)tstTooManySlicesErrorcBseZd„ZRS(cCsdt|_dS(NsOnly %d slices may be inserted(RR (R ((s physical.pyRys(RRR(((s physical.pyR*xstInvalidSliceStartSectorErrorcBseZd„ZRS(cCs d|_dS(Ns&Invalid entry for slice's start_sector(R (R ((s physical.pyR}s(RRR(((s physical.pyR+|stSliceInUseErrorcBseZd„ZRS(cCsD|dd}d|kr3|d|dd7}nd||_dS(NRiRs: %ssSlice currently in use by %s(R (R RR((s physical.pyRs (RRR(((s physical.pyR,€stDuplicatePartitionNameErrorcBseZd„ZRS(cCsd||_dS(Ns"Partition name %s already inserted(R (R R((s physical.pyR‰s(RRR(((s physical.pyR-ˆstFAT16PartitionTooLargeErrorcBseZd„ZRS(cCsdd|_dS(Ns+FAT16 Partition is too large. It must not s exceed 4GB(R (R ((s physical.pyRs(RRR(((s physical.pyR.ŒstInvalidPartitionNameErrorcBseZd„ZRS(cCsd|d||_dS(Ns"Invalid name: '%s' for partition s on disk: %s(R (R RR((s physical.pyR’s(RRR(((s physical.pyR/‘st InvalidPartitionStartSectorErrorcBseZd„ZRS(cCs d|_dS(Ns*Invalid entry for partition's start_sector(R (R ((s physical.pyR—s(RRR(((s physical.pyR0–stInvalidTypeErrorcBseZd„ZRS(cCsdd||_dS(Ns0Invalid partition type for operation. Requires s type: %s(R (R t valid_type((s physical.pyR›s(RRR(((s physical.pyR1šstMultipleActivePartitionsErrorcBseZd„ZRS(cCsd||_dS(Ns%Partition %s already marked as active(R (R R((s physical.pyR s(RRR(((s physical.pyR3ŸstOverlappingPartitionErrorcBseZd„ZRS(cCsd|d||_dS(NsPartition %s overlaps with sexisting partition: %s(R (R RR((s physical.pyR¥s(RRR(((s physical.pyR4¤stOverlappingPartitionVdevErrorcBseZd„ZRS(cCs d|_dS(Ns0Partition in_vdev attribute overlaps with parent(R (R ((s physical.pyRªs(RRR(((s physical.pyR5©stOverlappingPartitionZpoolErrorcBseZd„ZRS(cCs d|_dS(Ns1Partition in_zpool attribute overlaps with parent(R (R ((s physical.pyR®s(RRR(((s physical.pyR6­stPartitionTypeMissingErrorcBseZd„ZRS(cCs d|_dS(Ns$Partition has invalid partition type(R (R ((s physical.pyR²s(RRR(((s physical.pyR7±stLogicalPartitionOverlapErrorcBseZd„ZRS(cCsdd|_dS(Ns+Logical partition exceeds the start or end s sector of the extended partition(R (R ((s physical.pyR·s(RRR(((s physical.pyR8¶stTooManyLogicalPartitionsErrorcBseZd„ZRS(cCsdt|_dS(Ns*Only %d logical partitions may be inserted(RR (R ((s physical.pyR¼s(RRR(((s physical.pyR9»stExtPartitionTooSmallErrorcBseZd„ZRS(cCsdd|_dS(Ns0Extended Partition is too small. It must be 63 ssectors or larger.(R (R ((s physical.pyRÂs(RRR(((s physical.pyR:ÁstNoExtPartitionsErrorcBseZd„ZRS(cCsdd|_dS(Ns/A logical partition exists without an extended t partition(R (R ((s physical.pyRÇs(RRR(((s physical.pyR;ÆstTooManyExtPartitionsErrorcBseZd„ZRS(cCsdd|_dS(Ns/There is already an extended partition set for s this Disk(R (R ((s physical.pyRÌs(RRR(((s physical.pyR=Ësc Cs tƒ}|jjjdkr-|jj}n |j}|jj}|jdddddtƒ}|sj|S|djdddtƒ}x|D]w}|j|ƒrú|jd|j ƒ}|sÁPnx6|D]+} | jj|jjkrÈ| j }PqÈqÈWn|rPqqW|S( sb in_use_check() - method to query the "discovered" DOC tree for in_use conflicts. t PartitionRt discoveredt max_countitnot_found_is_erritdisk( tdictt containert __class__Rtparentt root_objecttget_descendantstFalset name_matchesRR( R R Rt desired_disktrootR?tdisksRBt partyslicest partyslice((s physical.pyt in_use_checkÐs0         c Csqt|jdƒrU|jjjj}|jj}|jjrˆ|j|jƒƒqˆn3t|jdƒrˆ|jj j}|jj j}nt |j t ƒp©t |j tƒsÂ|j|jƒƒnd|j koÜ|kns÷|j|jƒƒn|dkr*|jttgkr*|j|ƒ}n|j }|j |j jd}x0|jD]%}|dkrt |jƒdkrPn|dkr¦t |jƒdkr¦qTn|j }|j |j jd} |jdkrT|jdkrT||koû| knsT||ko| knsT||ko3|knsT|| koO|knry|j|j|j|jƒƒqyqTqTWt|jƒtkr¨|j|jƒƒn|jg|jD]}|jdkr¸|j^q¸krû|j|j|jƒƒn|jd k r‡t|jdƒ|jkr;|j|jƒƒnt|jdƒr‡t|jj dƒ|jkr„|j|jƒƒq„q‡n|j d k rt|jd ƒ|j krÇ|j|j!ƒƒnt|jdƒrt|jj d ƒ|j kr|j|j!ƒƒqqn|j"|ƒ} | rZ|jd krZ|j# rZ|j|j$| ƒƒnt%j&|||ƒd S( sq insert_slice() - override method for validation of Slice DOC objects. the following checks are done as part of validation: - the parent Disk object does not have whole_disk attribute set - the start_sector of the slice is an int or long and is between 0 and the container's maximum size - no overlapping boundaries of the slice with any other slices already inserted - no more than V_NUMPAR slices - no duplicate indexes (ie. no duplicate slice numbers) - none of the parent objects have an in_zpool or in_vdev attribute set tgeometryt part_typeitVTOCiitdeletetin_zpooltin_vdevtpreserveN('thasattrRDt disk_proptdev_sizetsectorstlabelt whole_diskt set_errorR tsizeRFt isinstancet start_sectortinttlongR+ttagRRtcylinder_boundary_adjustmentt_shadowRtactionR#tlenRR*R)RUtNonetgetattrR&RVR'RPtforceR,Rtinsert( R tindexR t parent_sizeR\tcb_starttcb_endtslctstarttendtstats((s physical.pyt insert_sliceÿsh  ! !! 88#!  c CsJ|jjjj}|jj}|jdkrC|j|jƒƒn|j r°dt |j ƒkomt kn r°|j dkr°|j|jt|j ƒ|jjƒƒq°nt |j ƒt kr|j dkr|j|jt|j ƒ|jjƒƒqnt|jt ƒp#t|jtƒs<|j|jƒƒnt|jjdƒr°t|jjdƒdk r°d|jko’|jjjjkns°|j|jƒƒq°n|j|ƒ}|jjrá|j|jƒƒn|j}|j|jjd}xä|jD]Ù}|j}|j|jjd} |j dkr |j dkr ||kof| kns¿||ko‚| kns¿||kož|kns¿|| koº|knrä|j|j|j |j ƒƒqäq q Wt|jƒtkr|j|jƒƒn|j g|jD]}|j dkr#|j ^q#krf|j|j |j ƒƒn|j!dk r©t|jdƒ|j!kr©|j|j"ƒƒq©n|j#dk rìt|jdƒ|j#krì|j|j$ƒƒqìn|j%|ƒ} | r3|j dkr3|j& r3|j|j'| ƒƒnt(j)|||ƒdS( sÍ insert_gptpartition() - override method for validation of GPTPartition DOC objects. the following checks are done as part of validation: - the parent Disk object does not have whole_disk attribute set - the start_sector of the slice is an int or long and is between 0 and the container's maximum size - no overlapping boundaries of the GPT partition with any other GPT partitions already inserted - no more than EFI_NUMUSERPAR for non-reserved or non-preserved partitions - no duplicate indexes (ie. no duplicate GPT partition numbers) - none of the parent objects have an in_zpool or in_vdev attribute set iRWRZiRTRURVN(*RDRYRZR[R\RRRiR^R!t is_reservedRbRRRgRtstrRR`RaRcRRXRjtsector_boundary_adjustmentR]R R_RfRRhRR"RRUR RVRRPRkRRRl( R RmR RnR\t new_starttnew_endtgpartRrRsRt((s physical.pytinsert_gptpartitionvsf  & " "   8 !cCsÅ|jdkr%|j|jƒƒndt|jƒkoIttknsy|j|jt |jƒ|j j ƒƒn|j r”|j |ƒ}nt|jtƒpµt|jtƒsÎ|j|jƒƒnt|j jdƒrBt|j jdƒdk rBd|jko$|j jjjknsB|j|jƒƒqBn|j jrd|j|jƒƒn|jrrd}x8|jD]-}|jr}|j|jkrª|}qªq}q}W|dkrÐ|j|jƒƒqrg|jD]$}|jrÚ|jdkrÚ|^qÚ}t|ƒtkr,|j|j ƒƒnt!|d„ƒ}d}xE|D]=} | j| j"j} | |jkrK| |krK| }qKqKW|dkr|j|j} | t#kro|jdkro|jt#|_|j"jt#} t$t | ƒt$j%ƒ|_"qoqr|j|} | t#krr|jdkrr|jt#| 7_|j"jt#} t$t | ƒt$j%ƒ|_"qrn|j rá|j&|j'kráxQ|jD]C}|jr¬q—n|j&|j'kr—|j|j(|jƒƒq—q—Wn|j} | |j"jd}x…|jD]z}|j r7|j}||j"jd}n%|jt#}||j"jdt#}|j rw|jrÏqqÏnX|jrÀ|jdkrÀ| |ks§||krÀ|j|j)ƒƒqÀn|j rÏqn|jdkr|jdkr|| ko|kns]||ko |kns]| |ko<|kns]| |koX|knr‚|j|j*|j|jƒƒq‚qqWt|j jdƒrá|j jjdk rá|j rá|j jjj}|j|j"j}n|jg|jD]}|jdkrñ|j^qñkr4|j|j+|jƒƒn|jrªx?|jD]4}|jrG|jdkrG|j|j,ƒƒqGqGW|j"jt#krª|j|j-ƒƒqªn|j.dƒ|j.dƒ|j.d ƒg}|j|kr(|jdkr(|j"j/t$j0d d kr(|j|j1ƒƒq(n|j2dk rkt|j d ƒ|j2krk|j|j3ƒƒqkn|j4dk r®t|j d ƒ|j4kr®|j|j5ƒƒq®nt6j7|||ƒdS(se insert_partition() - override method for validation of Partition DOC objects. the following checks are done as part of validation: - Partition objects *must* have a part_type. - the parent Disk object does not have whole_disk attribute set - the start_sector of the slice is an int or long and is between 0 and the container's maximum size - if a partition is a logical partition, ensure there is an extended partition somewhere in indexes 1-4 - no more than MAX_EXT_PARTS logical partitions - logical partitions fall within the boundaries of the extended partition - Only one active primary partition - primary partitions are not larger than the Disk - no overlapping boundaries of the partition with any other partitions already inserted - no duplicate indexes - the extended partition is at least 63 sectors in size and there is only one extended partition specified - none of the parent objects have an in_zpool or in_vdev attribute set iRZiRTcSst|j|jƒS(N(tcmpRa(txty((s physical.pyt<stcreatesFAT16 (Upto 32M)sFAT16 (>32M, HUGEDOS)sWIN95 FAT16(LBA)tgbiRURVN(8RRRiR^R7RbRRRR/RwRDRt is_primaryReR`RaRcR0RXRYRjRZR[R]R t is_logicalRft is_extendedtEXTENDED_ID_LISTR;RgRhR9tsortedR_tLOGICAL_ADJUSTMENTR t sector_unitstbootidtACTIVER3R8R4R-R=R:t name_to_numt byte_valuetunitsR.RUR6RVR5RRl(R RmR t extended_partR<tpt logical_listtslisttclosest_endpointtlogicalt end_pointtdifftnew_sizetp_starttp_endRrRst disk_sizetp_sizet fat16_list((s physical.pytinsert_partitionäsÐ$)            " "          88  !   cCs„t|jdƒr5|jj r5tj|||ƒnKtj|jƒi|jd6|j d6|j d6}||j j ||ƒdS(Ntvalidate_childrent GPTPartitiontSliceR>( RXRDRžRRlterrsvctclear_error_list_by_mod_idtmod_idR|RuRRER(R RmR t insert_map((s physical.pyRlÃs    cCsntj|jƒt|dƒrZ|j|ƒ}|rZ|j rZ|j|j|ƒƒqZntj ||ƒdS(NRk( R¡R¢R£RXRPRkR^R,Rtremove(R R Rt((s physical.pyR¥Õs c Cs;|jdkr|St|jdƒrU|jjj}|jjjj}|jj}nKt|jdƒr |jj jj}|jj jjj}|jj j}n|j |dkr|j |||}||j }||_ t t |j j|ƒt jƒ|_ nd|j ko!|knrd|dkrd||_ t t |j j|ƒt jƒ|_ n|j j|dkr­|j j||}t t |ƒt jƒ|_ n|dkr7t|dƒrÑd}nt|dƒréd}n||j j||kr7||||} t t | ƒt jƒ|_ q7n|S( s NOTE: MBR/VTOC SPECIFIC - do not use for GPT disk partitioning. cylinder_boundary_adjustment() - method to adjust a Partition or Slice object's start_sector and size value to fall on cylinder boundaries value - DOC object to adjust RRQRRitx86Rkii(RgRXRDRQtcylsizeRYRZR[t kernel_archRFRaR RwR_R‰( R R t cyl_boundaryRštarchtnew_start_sectort differenceR—tmax_cylt end_cylinder((s physical.pyReãsD     +     "c CsÚ|jdkr|S|jjj}|jjjj}t|dkrMd}n t|}|jjj}|j |krº||j }||_ t t |j j|ƒt j d|ƒ|_ n|j |dkr'|j |||}||j }||_ t t |j j|ƒt j d|ƒ|_ n|j |j jd}||jjj} | |krt t | |j dƒt j d|ƒ|_ n|j j|dkrÖt t |j j||ƒt j d|ƒ|_ n|S(s‡ NOTE: GPT SPECIFIC - do not use for MBR/VTOC disk partitioning. sector_boundary_adjustment() - method to adjust a GPTPartition objects start_sector and size value to align with 128KB physical block boundaries and avoid overlapping with either the primary or secondary EFI labels at the beginning or end of the disk. Some larger disks, iSCSI, zvols etc. implement larger physical block sizes, up to 128KB for Sun Storage Array Luns. Some of these can emulate a 512 byte block size for compatibility. If not aligned properly, the file system would appear to be logically aligned but physically end up misaligned across physical sectors, which causes performance problems. This method rounds GPT partitions on disks reporting < 128KB block size to multiples of 128KB. value - DOC object to adjust Riit blocksize(RgRDRQR¯RYRZR[tEFI_BLOCKSIZE_LCMtgpt_primary_table_sizeRaR RwR_R‰tgpt_backup_table_size( R R t block_sizeRštblock_multipliertmin_start_sectorR¬R«t end_sectort bkup_start((s physical.pyRx(sB            cGsDtj||Œd|_||_x|D]}|j|ƒq)WdS(Nsphysical validation(RRR£RDtappend(R RDtargstentry((s physical.pyRws    (.RRt__doc__RR RRRRRRR R!R"R#R&R'R(R)R*R+R,R-R.R/R0R1R3R4R5R6R7R8R9R:R;R=RPRuR|RRlR¥ReRxR(((s physical.pyR +sV / w n ß   E Oi(tsolaris_install.errsvcR¡t libadm.constRRRRRt libefi.constRtlibefi.cstructRtsolaris_install.target.shadowRRtsolaris_install.target.sizeR RˆR°R (((s physical.pyts(