【问题标题】:Unable to find MBR type找不到 MBR 类型
【发布时间】:2012-03-13 06:25:01
【问题描述】:

我有这个代码,它是项目源代码的一部分。 此代码查找 MBR 类型:GRUB 或 LILO,并相应地设置一个标志。

令人惊讶的是,在 SLES 10-SP1 (SUSE Linux Enterprise Server) 中,它无法确定。 /dev/sda1 是我的交换。 /dev/sda2 是整个 / 所在的位置,包括 MBR。

相同的代码适用于 SLES11 和其他。 这里MBR_SIZE#defined0x1be

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 格式化的。

【问题讨论】:

  • @sarnold:不,它正在使用 VMware 和单独的虚拟磁盘进行测试。
  • @sarnold:不,我们没有使用 GPT,它是 MBR。刚刚得到团队确认。
  • @sarnold: vmware4 磁盘映像 :)
  • 我将我们对话的结果移到了问题中,并删除了我的 cmets 以使其看起来简单。祝你好运。 :)
  • MBR 不应该位于/dev/sda 的开头(在您的设置中)吗?

标签: c linux mbr


【解决方案1】:

当你说它不起作用时,我不确定你的意思。如果您的意思是您的代码返回 -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  

【讨论】:

  • /dev/sda1/dev/sda 上的第一个分区,通常没有有 MBR(除非磁盘映像被虚拟化到一个分区中)。
  • 我的 MBR 确实在 /dev/sda2 上,因为我已经在第一个分区上进行了分区并创建了交换空间。另外,感谢更正的代码,执行后很快就会恢复。但奇怪的是,这个问题只出现在 SLES 10-SP1 和 SP2 上。在 SP3 上它工作正常
猜你喜欢
  • 2017-11-09
  • 1970-01-01
  • 2018-08-28
  • 2019-05-09
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多