首页 > 编程语言 >s-sgdisk源码分析 “--set-alignment=value分区对齐参数”

s-sgdisk源码分析 “--set-alignment=value分区对齐参数”

时间:2022-11-04 11:39:25浏览次数:76  
标签:sector set -- 分区 扇区 sgdisk 源码 startSector 对齐


文章目录

  • ​​边界对齐子命令使用​​
  • ​​源码分析​​
  • ​​sgdisk.cc main函数入口​​
  • ​​gptcl.cc DoOptions解析并执行具体命令函数​​
  • ​​gpt.cc CreatePartition创建分区函数,设置起始扇区对齐​​
  • ​​gpt.cc Align分区对齐函数,设置起始扇区对齐​​


​sgdisk​​命令是由

​gdisk-0.8.6-4.el7.x86_64​​程序包安装

​sgdisk源码路径​​ https://github.com/Shihta/gdisk

边界对齐子命令使用

本节主要描述sgdisk源码中关于命令​​-a --set-alignment=value​​​的边界对齐逻辑描述,借此各位可以看到​​sgdisk命令集​​​的其他参数源码白编写的逻辑
该参数使用方式一般是在创建分区过程中使用
​​​sgdisk --set-alignment=8 --new=1:0:2G --mbrtogpt -- /dev/sdb​​​ 这个命令是在/dev/sdb上创建一个编号为1,大小为2G的gpt分区,且start_sector是4K对齐的。​​sgdisk​​底层做分区是以扇区为单位,同时设置边界对齐时单位是扇区,默认以1M(2048个扇区)为单位进行对齐,最小只能设置8个扇区对齐

源码分析

sgdisk.cc main函数入口
int main(int argc, char *argv[]) {
GPTDataCL theGPT;
#主要执行函数,对参数进行解析以及调用各个执行函数执行具体功能
return theGPT.DoOptions(argc, argv);
}
gptcl.cc DoOptions解析并执行具体命令函数
/*
该函数的返回值如下:
0 :执行命令成功
1:执行参数过少
2:读磁盘分区表错误
3:格式化磁盘分区格式为gpt时没有-g参数
4:无法保存sgdisk对磁盘的操作
8:备份磁盘分区表失败,-R参数failed
*/
int GPTDataCL::DoOptions(int argc, char* argv[]) {
...
#将参数长项和短项以及对应的描述封装为结构体
struct poptOption theOptions[] =
{
{"attributes", 'A', POPT_ARG_STRING, &attributeOperation, 'A', "operate on partition attributes",
"list|[partnum:show|or|nand|xor|=|set|clear|toggle|get[:bitnum|hexbitmask]]"},
{"set-alignment", 'a', POPT_ARG_INT, &alignment, 'a', "set sector alignment", "value"},
{"backup", 'b', POPT_ARG_STRING, &backupFile, 'b', "backup GPT to file", "file"},
{"change-name", 'c', POPT_ARG_STRING, &partName, 'c', "change partition's name", "partnum:name"},
{"recompute-chs", 'C', POPT_ARG_NONE, NULL, 'C', "recompute CHS values in protective/hybrid MBR", ""},
{"delete", 'd', POPT_ARG_INT, &deletePartNum, 'd', "delete a partition", "partnum"},
{"display-alignment", 'D', POPT_ARG_NONE, NULL, 'D', "show number of sectors per allocation block", ""},
{"move-second-header", 'e', POPT_ARG_NONE, NULL, 'e', "move second header to end of disk", ""},
{"end-of-largest", 'E', POPT_ARG_NONE, NULL, 'E', "show end of largest free block", ""},
{"first-in-largest", 'f', POPT_ARG_NONE, NULL, 'f', "show start of the largest free block", ""},
...
}
...
// 确保最后一个参数一定是设备名称(之前会做参数筛选)
device = (char*) poptGetArg(poptCon);
poptResetContext(poptCon);

//如果设备名称不为空的话开始进行具体的参数解析
if (device != NULL) {
JustLooking(); // reset as necessary
BeQuiet(); // Tell called functions to be less verbose & interactive
//加载磁盘分区表
if (LoadPartitions((string) device)) {
...
//开始进行具体的sgdisk参数解析
while ((opt = poptGetNextOpt(poptCon)) > 0) {
...
//设置分区边界对齐的短项参数 对应--set-alignment=value
case 'a':
//初始化分区边界对齐参数 ,会为全局变量 sectorAlignment 赋值
SetAlignment(alignment);
break;
...
//创建分区参数短项,对应--new=num:start_sector:end_sector
case 'n':
JustLooking(0);
//获取分区编号
newPartNum = (int) GetInt(newPartInfo, 1) - 1;
//如果分区编号小于零则选择第一个没有被使用的编号(最小的没有被使用的)
if (newPartNum < 0)
newPartNum = FindFirstFreePart();
//从磁盘的剩余空间中寻找最大的未被分配的块,取该块中的第一个可用的扇区作为起始扇区配置
low = FindFirstInLargest();
/*将该扇区调整为512字节,因为不通磁盘有自己的扇区大小设置,
这里会将这种类型的磁盘扇区大小设置为操作系统识别的512字节*/
Align(&low);
//依据该块空间的起始扇区位置寻找终止扇区位置
high = FindLastInFree(low);
//这里做一个转换,将我们创建分区在start和end处输入的IEEE-1541-2002 value(K,M,G,T,P,E)转换为扇区单位
startSector = IeeeToInt(GetString(newPartInfo, 2), sSize, low, high, low);
endSector = IeeeToInt(GetString(newPartInfo, 3), sSize, startSector, high, high);
//创建分区:成功返回1,失败返回0
if (CreatePartition(newPartNum, startSector, endSector)) {
saveData = 1;
} else {
cerr << "Could not create partition " << newPartNum + 1 << " from "
<< startSector << " to " << endSector << "\n";
neverSaveData = 1;
} // if/else
//释放存放参数列表的char *空间
free(newPartInfo);
break;
...
}
...
}
gpt.cc CreatePartition创建分区函数,设置起始扇区对齐
uint32_t GPTData::CreatePartition(uint32_t partNum, uint64_t startSector, uint64_t endSector) {
int retval = 1; // assume there'll be no problems
uint64_t origSector = startSector;

if (IsFreePartNum(partNum)) {
//确保起始扇区是能够被我们设置的边界对齐参数整除(全局变量sectorAlignment)
/*
Align(&startSector)函数操作如下
1. 如果startSector % sectorAlignment == 0那么直接返回成功
2. 否则 假设startSector=2049,sectorAlignment=8
该函数会定位两个区间[2048,2049]和[2049-2056],先从该第一个区间起始扇区++查看是否未被占用,如未被占用,则用作起始扇区
否则从第二个区间2056扇区--查看是否未被占用,如未被占用,则用作起始扇区
详细可查看如下Align(&startSector)实现
*/
if (Align(&startSector)) {
cout << "Information: Moved requested sector from " << origSector << " to "
<< startSector << " in\norder to align on " << sectorAlignment
<< "-sector boundaries.\n";
} // if
if (IsFree(startSector) && (startSector <= endSector)) {
if (FindLastInFree(startSector) >= endSector) {
partitions[partNum].SetFirstLBA(startSector);
partitions[partNum].SetLastLBA(endSector);
partitions[partNum].SetType(DEFAULT_GPT_TYPE);
partitions[partNum].RandomizeUniqueGUID();
} else retval = 0; // if free space until endSector
} else retval = 0; // if startSector is free
} else retval = 0; // if legal partition number
return retval;
}
gpt.cc Align分区对齐函数,设置起始扇区对齐
int GPTData::Align(uint64_t* sector) {
int retval = 0, sectorOK = 0;
uint64_t earlier, later, testSector;

if ((*sector % sectorAlignment) != 0) {
earlier = (*sector / sectorAlignment) * sectorAlignment;
later = earlier + (uint64_t) sectorAlignment;

// Check to see that every sector between the earlier one and the
// requested one is clear, and that it's not too early....
if (earlier >= mainHeader.firstUsableLBA) {
sectorOK = 1;
testSector = earlier;
do {
sectorOK = IsFree(testSector++);
} while ((sectorOK == 1) && (testSector < *sector));
if (sectorOK == 1) {
*sector = earlier;
retval = 1;
} // if
} // if firstUsableLBA check

// If couldn't move the sector earlier, try to move it later instead....
if ((sectorOK != 1) && (later <= mainHeader.lastUsableLBA)) {
sectorOK = 1;
testSector = later;
do {
sectorOK = IsFree(testSector--);
} while ((sectorOK == 1) && (testSector > *sector));
if (sectorOK == 1) {
*sector = later;
retval = 1;
} // if
} // if
} // if
return retval;
} // GPTData::Align()


标签:sector,set,--,分区,扇区,sgdisk,源码,startSector,对齐
From: https://blog.51cto.com/u_13456560/5823152

相关文章

  • ceph-bluestore-tool基本使用
    主要是在bluestore的实例上执行低级管理操作的使用程序,是cephbluestore的管理工具命令​​help​​显示帮助信息​​fsck[--deep]​​对bluestore元数据进行一致性检查......
  • Rocksdb auto tune -- compaction的自动调优策略
    文章目录​​优化背景​​​​优化演进思路​​​​Rocksdb的RateLimiter​​​​Rocksdb的autotune​​​​autotunedcompaction(rocskdb默认autotune基础上的优化)​......
  • pmdk -- libpmemlog 介绍
    文章目录​​1.libpmemlog应用背景​​​​2.libpmemlog使用方式​​​​2.1基本接口​​​​2.2接口使用​​​​3.Libpmemlog性能​​​​3.1writesyscall性......
  • git
    git操作命令初始化仓库gitinit克隆仓库gitclone地址暂存缓存区gitadd.提交备注gitcommit-m‘这是第几次提交’上传提交gitpushgit命令操作......
  • 案例2:JAVA GUI 简易计算器
    使用javaGUI实现计算器的基本功能,包含一个帮助说明页面,提示用户如何使用。包含一个计算器主界面,要实现基本的加法、减法、乘法、除法运算。1.帮助界面   Help.java......
  • Word内容一键发布
    ​ 官方网站:泽优文档助手 产品交流群:​ 扫码加群:​ 1.注册帐号。使用浏览器访问地址:泽优文档助手-注册帐号,注意这里的邮箱地址不要随便填写,因为需要通......
  • pprof搭配ceph tell命令分析ceph内存
    文章目录​​安装​​​​使用​​​​使用`cephtell`产生堆栈信息文​​​​使用`pprof`工具分析内存及`cephtell`释放内存​​​​火焰图`FlameGraph`可视化进程堆栈信......
  • 创建swap
    创建swapubuntu20.04中在本地计算机中我们可以使用一个分区格式化为swap,而服务器中硬盘有限,只能创建一个交换文件将其格式话为swap。创建swapfile文件sudofallocate......
  • Rocksdb 的优秀代码(二)-- 工业级 打点系统 实现分享
    文章目录​​前言​​​​数据结构选型​​​​打点代码设计​​​​耗时打点​​​​请求计数打点​​​​打点总结​​前言一个完善的分布式系统一定是需要完善的打点统计......
  • 第五章18
    【题目描述】 如果整数A的全部因子(包括1,不包括A本身)之和等于B;且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。输入一个正整数n,输出n以内的全......