简体   繁体   中英

Unable to find MBR type

I have this code which is part of a project source. This code finds the MBR type: GRUB or LILO, and accordingly sets a flag.

Surprisingly in SLES 10-SP1 (SUSE Linux Enterprise Server), it is unable to determine. /dev/sda1 is my swap. /dev/sda2 is where the whole / is there, including the MBR.

Same code works for SLES11 and others. Here MBR_SIZE is #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 */

The testing is being done with different virtual disk images under VMWare. I've confirmed the disks are formatted with MBR and not GPT.

I'm not sure what you mean when you say it doesn't work. If your point is that your code returns -1, could you show us a copy of the MBR? You can use this command to capture it:

sudo dd if=/dev/sda bs=512 count=1 | xxd

You mention that your MBR is on /dev/sda2 . That is very unusual indeed. If you mean that that is where the boot code is installed, that's a totally different thing. The MBR is always held on the first sector of the disk (assuming it is a DOS-format MBR).

I suppose it's possible that the problem in some of the failure cases is a seek failure or a short read. I've made some tweaks to add error handling and simplify a bit.

#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  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM