2012-03-13 2 views
2

이 코드는 프로젝트 소스의 일부입니다. 이 코드는 MBR 유형 (GRUB 또는 LILO)을 찾고 그에 따라 플래그를 설정합니다.MBR 유형을 찾을 수 없습니다.

놀랍게도 SLES 10-SP1 (SUSE Linux Enterprise Server)에서 확인할 수 없습니다. /dev/sda1은 제 스왑입니다. /dev/sda2은 MBR을 포함하여 전체가 / 인 곳입니다.

동일한 코드가 SLES11 및 다른 제품에서 작동합니다. 여기에서 MBR_SIZE#defined에서 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에서 다른 가상 디스크 이미지로 수행됩니다. 디스크가 GPR이 아닌 MBR로 포맷되었는지 확인했습니다.

+0

@sarnold : 아니오, VMware 및 개별 가상 디스크에서 테스트 중입니다. – kingsmasher1

+0

@sarnold : 아니요, GPT는 사용하지 않습니다. MBR입니다. 팀에서 확인했습니다. – kingsmasher1

+0

@sarnold : vmware4 디스크 이미지 :) – kingsmasher1

답변

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 
+0

'/ dev/sda1'은'/ dev/sda'의 첫 번째 파티션이며 디스크 이미지가 파티션으로 가상화되지 않는 한 일반적으로 MBR을 가지지 않습니다. – wallyk

+0

@wallyk : 네 말이 맞아. –

+0

나는 파티션을 만들고 첫 번째 파티션에 스왑 공간을 만들었 기 때문에 실제로/dev/sda2에 내 MBR을 가지고 있습니다. 또한 수정 된 코드에 대한 감사는 실행 후 곧 되돌아옵니다. 그러나 이상하게도이 문제는 SLES 10-SP1 및 SP2에서만 나타납니다. SP3에서 잘 작동합니다. – kingsmasher1

관련 문제