我有这段代码,它是项目源代码的一部分。下面的代码查找MBR类型: GRUB或LILO,并相应地设置一个标志。
令人惊讶的是,在SLES10-SP1 (SUSE Linux Enterprise Server)中,它无法确定。/dev/sda1是我的交换。/dev/sda2是包括/在内的整个MBR的位置。
同样的代码也适用于SLES11和其他应用程序。这里的MBR_SIZE是#defined to 0x1be。
int lnxfsGetBootType(int pNumber)
{
int i, retval = -1, ccode;
PartInfo *p = &cpuParts[pNumber];
char buffer[SECTOR_SIZE];
var64 offset = 0;
isdLogFileOut(ZISD_LOG_DEVELOPER,"[lnxGBT]\n");
if (getenv("ZENDEVICE") || gUtilPart == 1) {
offset = p->pOffset; // look at the partition BPB
}
//Now try to find the installed boot loader...
lseek64(p->handle, (var64)offset, SEEK_SET); // either MBR or BPB
ccode = read(p->handle, buffer, SECTOR_SIZE);
for (i=0; i<MBR_SIZE-4;i++) {
if (strncmp(&buffer[i], "LILO", 4) == 0) {
if (offset == 0){
retval = FLAG_LNXFS_LILO;
isdLogFileOut(ZISD_LOG_WARNING,"\tLILO MBR found on %s\n",p->header.deviceName);
} else {
retval = FLAG_LNXFS_LILO; // 10.31.06 _BPB;
isdLogFileOut(ZISD_LOG_WARNING,"\tLILO BPB found on %s\n",p->header.deviceName);
}
}
if (strncmp(&buffer[i], "GRUB", 4) == 0) {
if (offset == 0){
retval = FLAG_LNXFS_GRUB;
isdLogFileOut(ZISD_LOG_WARNING,"\tGRUB MBR found on %s\n",p->header.deviceName);
} else {
retval = FLAG_LNXFS_GRUB; // 10.31.06 _BPB;
isdLogFileOut(ZISD_LOG_WARNING,"\tGRUB BPB found on %s\n",p->header.deviceName);
}
}
}
if (retval == -1) {
isdLogFileOut(ZISD_LOG_WARNING,"\tLILO or GRUB mbr/bpb not found on %s\n",p->header.deviceName);
}
return retval;
} // lnxfsGetBootType
Here partinfo, is a struct of partition type:
//Data structure used internally by the image engine to store information about the
//partitions. It encapsulates the PartHeader struct, whcih is used to store partition
//information in image archives
typedef struct _PartInfo
{
PartHeader header;
int handle; //file handle for reading/writing physical device
var32 flags; //Various flags as needed. Defined above.
var64 pOffset; //offset to partition from start of physical device
int deviceNumber; //index into 'devices' where this partition's
// physical device is located
int archIndex; //for restoring only. Index into imgParts of the
// archive partition this physical partition is
// mapped to
int bytesWritten; //track number of sectors written so the device-level
// cache can be flushed
void *info; //partition-type-specific info struct
/* snip */测试是在VMWare下使用不同的虚拟磁盘映像进行的。我已经确认磁盘是用MBR而不是GPT格式化的。
发布于 2012-03-16 06:29:21
我不知道你说它不起作用是什么意思。如果你的观点是你的代码返回-1,你能给我们看一份MBR的副本吗?您可以使用以下命令来捕获它:
sudo dd if=/dev/sda bs=512 count=1 | xxd你提到你的MBR在/dev/sda2上。这确实是非常不寻常的。如果你的意思是那是安装引导代码的地方,那是完全不同的事情。MBR始终保存在磁盘的第一个扇区上(假设它是DOS格式的MBR)。
我认为一些失败案例中的问题可能是查找失败或短读。我做了一些调整,增加了错误处理,并简化了一些。
#define MBR_SIZE 0x1be
int lnxfsGetBootType(int pNumber)
{
int retval = -1, ccode;
PartInfo *p = &cpuParts[pNumber];
char buffer[SECTOR_SIZE];
off64_t offset = 0;
void *plilo, *pgrub;
const char *what = "MBR";
isdLogFileOut(ZISD_LOG_DEVELOPER,"[lnxGBT]\n");
if (getenv("ZENDEVICE") || gUtilPart == 1) {
offset = p->pOffset; // look at the partition BPB
what = "BPB";
}
// Now try to find the installed boot loader...
if (lseek64(p->handle, offset, SEEK_SET) == -1) {
isdLogFileOut(ZISD_LOG_ERROR,"\tFailed to seek to %s: %s\n", what, strerror(errno));
return -1;
}
ccode = read(p->handle, buffer, SECTOR_SIZE);
if (ccode != SECTOR_SIZE) {
isdLogFileOut(ZISD_LOG_ERROR,"\tFailed to read BPB/MBR: %s\n",
strerror(errno));
return -1;
}
plilo = memmem(buffer, ccode, "LILO", 4);
pgrub = memmem(buffer, ccode, "GRUB", 4);
if (plilo) {
retval = FLAG_LNXFS_LILO;
if (pgrub && pgrub < plilo)
retval = FLAG_LNXFS_GRUB;
}
} else if (pgrub) {
retval = FLAG_LNXFS_GRUB;
}
if (-1 == retval) {
isdLogFileOut(ZISD_LOG_WARNING,"\tLILO or GRUB %s not found on %s\n", what, p->header.deviceName);
} else {
isdLogFileOut(ZISD_LOG_WARNING,"\t%s %s not found on %s\n",
(retval == FLAG_LNXFS_GRUB ? "GRUB" : "LILO"),
what, p->header.deviceName);
}
return retval;
} // lnxfsGetBootType https://stackoverflow.com/questions/9679284
复制相似问题