• Home
  • Raw
  • Download

Lines Matching +full:- +full:- +full:disk

1 /* gpt.cc -- Functions for loading, saving, and manipulating legacy MBR and GPT partition
6 /* This program is copyright (c) 2009-2024 by Roderick W. Smith. It is distributed
51 int r = -1; in log2_32()
81 sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default in GPTData()
146 sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default in GPTData()
252 cout << "\nProblem: The main header's self-pointer doesn't point to itself. This problem\n" in Verify()
254 << "problems. Think carefully before saving changes with 'w' or using this disk.\n"; in Verify()
257 if (secondHeader.currentLBA != (diskSize - UINT64_C(1))) { in Verify()
259 cout << "\nProblem: The secondary header's self-pointer indicates that it doesn't reside\n" in Verify()
260 << "at the end of the disk. If you've added a disk to a RAID array, use the 'e'\n" in Verify()
294 cout << "\nProblem: main header's disk GUID (" << mainHeader.diskGUID in Verify()
295 << ") doesn't\nmatch the backup GPT header's disk GUID (" in Verify()
318 // Check that the disk size will hold the data... in Verify()
321 cout << "\nProblem: Disk is too small to hold all the data!\n" in Verify()
322 << "(Disk size is " << diskSize << " sectors, needs to be " in Verify()
335 cout << "\nProblem: Main partition table appears impossibly early on the disk.\n" in Verify()
347 << "but is generally ill-advised. Using 'j' on the experts' menu can adjust this\n" in Verify()
350 if (secondHeader.partitionEntriesLBA != diskSize - GetTableSizeInSectors() - 1) { in Verify()
352 << secondHeader.partitionEntriesLBA + GetTableSizeInSectors() - 1 in Verify()
354 << "This is helpful in some exotic configurations, but is generally ill-advised.\n" in Verify()
359 << mainHeader.partitionEntriesLBA + GetTableSizeInSectors() - 1 << ")\n" in Verify()
361 << "but is unusual. The util-linux fdisk program often creates disks like this.\n" in Verify()
375 cout << "\nProblem: GPT claims the disk is larger than it is! (Claimed last usable\n" in Verify()
377 << mainHeader.backupLBA << " and disk size is " << diskSize << " sectors.\n" in Verify()
390 // Check for MBR-specific problems.... in Verify()
397 << "ignore the disk, but it is required to boot from a GPT disk on some BIOS-based\n" in Verify()
406 cout << "\nPartition(s) in the protective MBR are too big for the disk! Creating a\n" in Verify()
421 << testAlignment << "-sector boundary. This may\nresult " in Verify()
427 << testAlignment << "-sector boundary. This may\nresult " in Verify()
428 << "in problems with some disk encryption tools.\n"; in Verify()
432 cout << "\nConsult http://www.ibm.com/developerworks/linux/library/l-4kb-sector-disks/\n" in Verify()
433 << "for information on disk alignment.\n"; in Verify()
472 // If the disk size is 0 (the default), then it means that various in CheckGPTSize()
477 overlap = mainHeader.firstUsableLBA - firstUsedBlock; in CheckGPTSize()
487 } // Problem at start of disk in CheckGPTSize()
489 overlap = lastUsedBlock - mainHeader.lastUsableLBA; in CheckGPTSize()
492 if (lastUsedBlock > (diskSize - 2)) { in CheckGPTSize()
499 } // Problem at end of disk in CheckGPTSize()
517 valid -= 1; in CheckHeaderValidity()
519 valid -= 1; in CheckHeaderValidity()
528 valid -= 2; in CheckHeaderValidity()
530 valid -= 2; in CheckHeaderValidity()
538 // Check for an Apple disk signature in CheckHeaderValidity()
549 // Note: Must be called with header in platform-ordered byte order.
558 oldCRC = header->headerCRC; in CheckHeaderCRC()
559 header->headerCRC = UINT32_C(0); in CheckHeaderCRC()
561 hSize = header->headerSize; in CheckHeaderCRC()
593 header->headerCRC = oldCRC; in CheckHeaderCRC()
598 // been made. Must be called on platform-ordered data (this function reverses
660 mainHeader.partitionEntriesLBA = secondHeader.firstUsableLBA - GetTableSizeInSectors(); in RebuildMainHeader()
701 mbrLast = mbrFirst + (uint64_t) protectiveMBR.GetLength(i) - UINT64_C(1); in FindHybridMismatches()
748 // Find partitions that are insane -- they start after they end or are too
749 // big for the disk. (The latter should duplicate detection of overlaps
765 cout << "\nProblem: partition " << i + 1 << " is too big for the disk.\n"; in FindInsanePartitions()
775 * Begin functions that load data from disk or save data to disk. *
780 // the partition table to a new disk and saving backups.
787 // store disk information.... in SetDisk()
807 bsdDisklabel.ReadBSDData(&myDisk, 0, diskSize - 1); in PartitionScan()
816 cerr << "\aThe protective MBR's 0xEE partition is oversized! Auto-repairing.\n\n"; in PartitionScan()
832 << "This disk appears to contain an Apple-format (APM) partition table!\n"; in PartitionScan()
840 // Read GPT data from a disk.
851 … << ". It will be impossible to save\nchanges to this disk's partition table!\n"; in LoadPartitions()
854 << "'sysctl kern.geom.debugflags=16' at a shell prompt, and re-running this\n" in LoadPartitions()
859 … << "https://www.quora.com/How-do-I-turn-off-the-rootless-in-OS-X-El-Capitan-10-11\n" in LoadPartitions()
864 myDisk.Close(); // Close and re-open read-only in case of bugs in LoadPartitions()
869 // store disk information.... in LoadPartitions()
882 bsdDisklabel.ReadBSDData(&myDisk, 0, diskSize - 1); in LoadPartitions()
909 cout << "Disk is too small to hold GPT data (" << diskSize in LoadPartitions()
931 allOK = LoadHeader(&secondHeader, myDisk, diskSize - UINT64_C(1), &secondCrcOk) && allOK; in ForceLoadGPTData()
933 cout << "Warning! Disk size is smaller than the main header indicates! Loading\n" in ForceLoadGPTData()
934 << "secondary header from the last sector of the disk! You should use 'v' to\n" in ForceLoadGPTData()
935 << "verify disk integrity, and perhaps options on the experts' menu to repair\n" in ForceLoadGPTData()
936 << "the disk.\n"; in ForceLoadGPTData()
999 mainPartsCrcOk = 0; // LoadSecondTableAsMain() resets this, so re-flag as bad in ForceLoadGPTData()
1007 cerr << "Warning! One or more CRCs don't match. You should repair the disk!\n"; in ForceLoadGPTData()
1050 // Load a single GPT header (main or backup) from the specified disk device and
1051 // sector. Applies byte-order corrections on big-endian platforms. Sets crcOk
1055 int GPTData::LoadHeader(struct GPTHeader *header, DiskIO & disk, uint64_t sector, int *crcOk) { in LoadHeader() argument
1059 disk.Seek(sector); in LoadHeader()
1060 if (disk.Read(&tempHeader, 512) != 512) { in LoadHeader()
1072 // Print the below warning only if the CRC is OK -- but correct the in LoadHeader()
1081 cerr << " supports only " << sizeof(GPTPart) << "-byte entries.\n"; in LoadHeader()
1095 // Load a partition table (either main or secondary) from the specified disk,
1100 int GPTData::LoadPartitionTable(const struct GPTHeader & header, DiskIO & disk, uint64_t sector) { in LoadPartitionTable() argument
1107 } else if (disk.OpenForRead()) { in LoadPartitionTable()
1109 retval = disk.Seek(header.partitionEntriesLBA); in LoadPartitionTable()
1111 retval = disk.Seek(sector); in LoadPartitionTable()
1117 if (disk.Read(partitions, sizeOfParts) != (int) sizeOfParts) { in LoadPartitionTable()
1152 if (myDisk.Seek(header->partitionEntriesLBA)) { in CheckTable()
1153 partsToCheck = new GPTPart[header->numParts]; in CheckTable()
1154 sizeOfParts = header->numParts * header->sizeOfPartitionEntries; in CheckTable()
1163 allOK = (newCRC == header->partitionEntriesCRC); in CheckTable()
1168 if (newCRC != otherHeader->partitionEntriesCRC) { in CheckTable()
1179 // Writes GPT (and protective MBR) to disk. If quiet==1, moves the second
1180 // header later on the disk without asking for permission, if necessary, and
1191 // This test should only fail on read-only disks.... in SaveGPTData()
1193 cout << "The justLooking flag is set. This probably means you can't write to the disk.\n"; in SaveGPTData()
1197 // Check that disk is really big enough to handle the second header... in SaveGPTData()
1199 cerr << "Caution! Secondary header was placed beyond the disk's limits! Moving the\n" in SaveGPTData()
1212 if (mainHeader.backupLBA < (diskSize - UINT64_C(1))) { in SaveGPTData()
1214 cout << "Warning! Secondary header is placed too early on the disk! Do you want to\n" in SaveGPTData()
1250 cerr << "\nPartition(s) in the protective MBR are too big for the disk! Creating a\n" in SaveGPTData()
1294 // re-read the partition table in SaveGPTData()
1297 // system the MBR write failed but everything else was OK (on a GPT disk under in SaveGPTData()
1309 << "MIGHT be harmless, or the disk might be damaged! Checking it is advisable.\n"; in SaveGPTData()
1346 // MBR write closed disk, so re-open and seek to end.... in SaveGPTBackup()
1373 // Should be passed an architecture-appropriate header (DO NOT call
1376 int GPTData::SaveHeader(struct GPTHeader *header, DiskIO & disk, uint64_t sector) { in SaveHeader() argument
1382 if (disk.Seek(sector)) { in SaveHeader()
1383 if (disk.Write(header, 512) == -1) in SaveHeader()
1385 } else allOK = 0; // if (disk.Seek()...) in SaveHeader()
1393 // Should be passed an architecture-appropriate header (DO NOT call
1396 int GPTData::SavePartitionTable(DiskIO & disk, uint64_t sector) { in SavePartitionTable() argument
1400 if (disk.Seek(sector)) { in SavePartitionTable()
1403 if (disk.Write(partitions, mainHeader.sizeOfPartitionEntries * numParts) == -1) in SavePartitionTable()
1429 // table; if other size, treat it like a GPT fdisk-generated backup in LoadGPTBackup()
1452 if (secondHeader.currentLBA != diskSize - UINT64_C(1)) { in LoadGPTBackup()
1453 cout << "Warning! Current disk size doesn't match that of the backup!\n" in LoadGPTBackup()
1458 if (!LoadPartitionTable(mainHeader, backupFile, (uint64_t) (3 - shortBackup))) in LoadGPTBackup()
1482 // This function destroys the on-disk GPT structures, but NOT the on-disk
1536 cout << "GPT data structures destroyed! You may now partition the disk using fdisk or\n" in DestroyGPT()
1541 } // if/else (fd != -1) in DestroyGPT()
1545 // Wipe MBR data from the disk (zero it out completely)
1581 cout << "\a GPT: unknown -- bug!\n"; in ShowGPTState()
1591 cout << "Disk " << device << ": " << diskSize << " sectors, " in DisplayGPTData()
1599 cout << "Disk identifier (GUID): " << mainHeader.diskGUID << "\n"; in DisplayGPTData()
1602 … << " and ends at sector " << mainHeader.partitionEntriesLBA + GetTableSizeInSectors() - 1 << "\n"; in DisplayGPTData()
1606 cout << "Partitions will be aligned on " << sectorAlignment << "-sector boundaries\n"; in DisplayGPTData()
1690 << "Caution: Found protective or hybrid MBR and corrupt GPT. Using GPT, but disk\n" in UseWhichPartitions()
1696 } // if/else MBR says disk is GPT in UseWhichPartitions()
1722 // null (non-existent) partitions in XFormPartitions()
1732 // when doing a disk verification in XFormPartitions()
1773 // Transform the partitions on an already-loaded BSD disklabel...
1777 if (disklabel->IsDisklabel()) { in XFormDisklabel()
1778 for (i = 0; i < disklabel->GetNumParts(); i++) { in XFormDisklabel()
1781 partitions[partNum] = disklabel->AsGPT(i); in XFormDisklabel()
1786 if (partNum == -1) in XFormDisklabel()
1791 // when doing a disk verification in XFormDisklabel()
1820 cout << "Caution: Partition end point past 32-bit pointer boundary;" in OnePartToMBR()
1827 if (allOK) // Display only if "else" triggered by out-of-bounds condition in OnePartToMBR()
1828 cout << "Partition " << gptPart + 1 << " begins beyond the 32-bit pointer limit of MBR " in OnePartToMBR()
1873 cout << "The highest-numbered partition is " << high + 1 in SetGPTSize()
1934 mainHeader.lastUsableLBA = secondHeader.partitionEntriesLBA - UINT64_C(1); in MoveSecondTable()
1976 // Non-interactively create a partition.
1986 << "-sector boundaries.\n"; in CreatePartition()
2030 // program was launched on an MBR disk, and those may need to be
2057 // Now some semi-static items (computed based on end of disk) in ClearGPTData()
2058 mainHeader.backupLBA = diskSize - UINT64_C(1); in ClearGPTData()
2059 mainHeader.lastUsableLBA = diskSize - mainHeader.firstUsableLBA; in ClearGPTData()
2061 // Set a unique GUID for the disk, based on random numbers in ClearGPTData()
2079 // Set the location of the second GPT header data to the end of the disk.
2080 // If the disk size has actually changed, this also adjusts the protective
2083 // transformation menu, to help users of RAID arrays who add disk space
2085 // involving unequal-sized disks.
2087 mainHeader.backupLBA = secondHeader.currentLBA = diskSize - UINT64_C(1); in MoveSecondHeaderToEnd()
2088 if (mainHeader.lastUsableLBA != diskSize - mainHeader.firstUsableLBA) { in MoveSecondHeaderToEnd()
2096 mainHeader.lastUsableLBA = secondHeader.lastUsableLBA = diskSize - mainHeader.firstUsableLBA; in MoveSecondHeaderToEnd()
2114 // Set the disk GUID to the specified value. Note that the header CRCs must
2136 // Set new random GUIDs for the disk and all partitions. Intended to be used
2137 // after disk cloning or similar operations that don't randomize the GUIDs.
2148 // Change partition type code non-interactively. Returns 1 if
2172 // technology from other companies, which use 4096-byte sectors
2173 // internally although they translate to 512-byte sectors for the
2205 sectorOK = IsFree(testSector--); in Align()
2251 // Returns the value of the first free partition, or -1 if none is
2260 i = -1; in FindFirstFreePart()
2261 } else i = -1; in FindFirstFreePart()
2278 * Functions that return data about disk free space *
2316 // Returns the LBA of the start of the first partition on the disk (by
2330 // Returns the LBA of the end of the last partition on the disk (by
2345 // space on the disk. Returns 0 if there are no available blocks left
2354 segmentSize = lastBlock - firstBlock + UINT32_C(1); in FindFirstInLargest()
2365 // Find the last available block on the disk.
2384 last = partitions[i].GetFirstLBA() - 1; in FindLastAvailable()
2407 nearestEnd = partitions[i].GetFirstLBA() - 1; in FindLastInFree()
2412 if (Align(&endPlus) && IsFree(endPlus - 1) && (endPlus > start)) { in FindLastInFree()
2413 nearestEnd = endPlus - 1; in FindLastInFree()
2435 segmentSize = lastBlock - firstBlock + UINT64_C(1); in FindFreeBlocks()
2451 // in partNum, if that variable is non-NULL. (A value of UINT32_MAX is
2495 // (In sgdisk, end-alignment is done only if the '-I' command-line option
2501 cout << "Warning: Setting alignment to a value that does not match the disk's\n" in SetAlignment()
2513 // partition's starting LBA is examined, and if it's divisible by a power-of-2
2515 // sector size), but not by the previously-located alignment value, then the
2517 // and the disk is bigger than SMALLEST_ADVANCED_FORMAT, resets it to 8. This
2521 // drives are aligned to 2048-sector multiples but the program won't complain
2522 // about other alignments on existing disks unless a smaller-than-8 alignment
2540 exponent--; in ComputeAlignment()
2558 ReverseBytes(&header->signature, 8); in ReverseHeaderBytes()
2559 ReverseBytes(&header->revision, 4); in ReverseHeaderBytes()
2560 ReverseBytes(&header->headerSize, 4); in ReverseHeaderBytes()
2561 ReverseBytes(&header->headerCRC, 4); in ReverseHeaderBytes()
2562 ReverseBytes(&header->reserved, 4); in ReverseHeaderBytes()
2563 ReverseBytes(&header->currentLBA, 8); in ReverseHeaderBytes()
2564 ReverseBytes(&header->backupLBA, 8); in ReverseHeaderBytes()
2565 ReverseBytes(&header->firstUsableLBA, 8); in ReverseHeaderBytes()
2566 ReverseBytes(&header->lastUsableLBA, 8); in ReverseHeaderBytes()
2567 ReverseBytes(&header->partitionEntriesLBA, 8); in ReverseHeaderBytes()
2568 ReverseBytes(&header->numParts, 4); in ReverseHeaderBytes()
2569 ReverseBytes(&header->sizeOfPartitionEntries, 4); in ReverseHeaderBytes()
2570 ReverseBytes(&header->partitionEntriesCRC, 4); in ReverseHeaderBytes()
2571 ReverseBytes(header->reserved2, GPT_RESERVED); in ReverseHeaderBytes()
2607 // Return (not for modification!) the disk's GUID value
2613 // (Function is non-interactive.)
2615 // modified data, and -1 if a modification command failed.
2622 retval = -1; in ManageAttributes()
2634 retval = -1; in ManageAttributes()
2657 * Additional non-class support functions *
2663 // Specifically, the -fpack-struct option to gcc may be required to ensure proper structure