Changeset 146

Show
Ignore:
Timestamp:
06/12/06 18:00:40 (3 years ago)
Author:
ludo
Message:

lvm2 PV was not properly detected sometimes (from r3475)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/client/revimage/lvm.c

    r141 r146  
    3131extern unsigned long lvm_sect; 
    3232 
    33 /* check if it's and LVM partition */ 
     33/* compare two UUID strings  
     34 * 
     35 * return 1 if equal, else return 0 
     36 * '-' characters are ignored in s2 
     37 */ 
     38int uuid_compare(char *s1, char *s2) 
     39
     40    int i; 
     41 
     42    for (i = 0; i < 32; i++) { 
     43        if (*s2 == '-') 
     44            s2++; 
     45        if (*s1++ != *s2++) 
     46            return 0; 
     47    } 
     48    return 1; 
     49
     50 
     51 
     52/* check if it's a LVM partition */ 
    3453void lvm_check(char *device, long long *offset) 
    3554{ 
     
    4362        exit(1); 
    4463    } 
    45     fread(&buf[0], 256*4, 1, fi); 
     64    fread(&buf[0], 256 * 4, 1, fi); 
    4665 
    4766    *offset = 0; 
    4867    /* lvm1 checks */ 
    49      debug("LVM1 signature check: %08lx\n", buf[0]); 
    50      if (buf[0] == 0x00014d48)  
    51       { 
     68    debug("LVM1 signature check: %08lx\n", buf[0]); 
     69    if (buf[0] == 0x00014d48) { 
    5270        debug("LVM1 found\n"); 
    5371 
    5472        *offset = buf[9] + buf[10]; 
    5573        debug("LVM: Real part offset: %16llx\n", *offset); 
    56          
    57         debug("LVM: VG name : '%32s'\n", (char *)&buf[11+32]); 
    58         debug("LVM: PV Num  : %ld\n", buf[108]);     
    59         debug("LVM: PE Size : %ld\n", buf[113]/2); 
     74 
     75        debug("LVM: VG name : '%32s'\n", (char *) &buf[11 + 32]); 
     76        debug("LVM: PV Num  : %ld\n", buf[108]); 
     77        debug("LVM: PE Size : %ld\n", buf[113] / 2); 
    6078        debug("LVM: PE Total: %ld\n", buf[114]); 
    6179        debug("LVM: PE Alloc: %ld\n", buf[115]); 
    62          
    63         lvm_sect = buf[113]*buf[115]; 
     80 
     81        lvm_sect = buf[113] * buf[115]; 
    6482        debug("LVM: Total sectors: %ld\n", lvm_sect); 
    65          
     83 
    6684 
    6785        if (fseek(fi, buf[9], SEEK_SET) != 0) { 
    68           debug("Seek error\n"); 
    69           return; 
     86            debug("Seek error\n"); 
     87            return; 
    7088        } 
    71       } 
    72     else 
    73       { 
    74         __u64 off; 
    75         int state = 0, pe_count = 0, extent = 0; 
     89    } else { 
     90        __u64 off, mdh_offset; 
     91        int state = 0, pe_count = 0, extent = 0, lev = 0; 
    7692        __u64 *pv; 
     93        char *pvuuid; 
    7794 
    7895        /* lvm2 */ 
    7996        /* buf[128] = label_header */ 
    80         if (buf[128] != 0x4542414C || buf[129] != 0x454E4F4C)  
    81           { 
     97        if (buf[128] != 0x4542414C || buf[129] != 0x454E4F4C) { 
    8298            debug("LVM2 LABELONE not found\n"); 
    8399            return; 
    84          
     100       
    85101        debug("LVM2 LABELONE found\n"); 
    86         if (buf[134] != 0x324D564C || buf[135] != 0x31303020)  
    87           { 
     102        if (buf[134] != 0x324D564C || buf[135] != 0x31303020) { 
    88103            debug("LVM2 001 not found\n"); 
    89104            return; 
    90          
     105       
    91106        /* buf[133] = label_header.offset_xl */ 
    92107        /* pv_header */ 
    93         pv = (__u64 *)(((__u8 *)&buf[128]) + buf[133]); 
    94         debug("LVM2 pv UUID: %32s\n", (char *)pv); 
     108        pv = (__u64 *) (((__u8 *) & buf[128]) + buf[133]); 
     109        /* copy this PV uuid */ 
     110        pvuuid = pv; 
     111        debug("LVM2 pv UUID: %32s\n", (char *) pvuuid); 
    95112        /* skip data */ 
    96113        pv += 5; 
     
    99116        } 
    100117        pv += 2; 
    101         debug("LVM2: Mdh offset: 0x%llX\n", *pv)
    102         fseek(fi, *pv, SEEK_SET); 
    103         fread(buf, 128*4, 1, fi); 
    104         if (strncmp((char *)&buf[1], (char *)FMTT_MAGIC, 16)) 
    105        
     118        mdh_offset = *pv
     119        debug("LVM2: Mdh offset: 0x%llX\n", mdh_offset); 
     120        fseek(fi, mdh_offset, SEEK_SET); 
     121        fread(buf, 128 * 4, 1, fi); 
     122        if (strncmp((char *) &buf[1], (char *) FMTT_MAGIC, 16))
    106123            debug("LVM: FMTT_MAGIC not found\n"); 
    107124            return; 
    108          
     125       
    109126        debug("LVM2: FMTT v%ld\n", buf[5]); 
    110         off = buf[10] + ((__u64)buf[11] << 32); 
     127        off = buf[10] + ((__u64) buf[11] << 32); 
    111128        debug("LVM2: Meta offset: 0x%llX\n", off); 
    112         if (off == 0) return; 
    113         off += 0x800; 
     129        if (off == 0) 
     130            return; 
     131        off += mdh_offset; 
    114132        fseek(fi, off, SEEK_SET); 
    115133        *offset = 0; 
    116         while (1)  
    117           { 
    118             char b[128]; 
     134        /* Q&D parsing of meta data */ 
     135        state = 0; 
     136        while (1) { 
     137            char b[128], uuid[40]; 
    119138 
    120             fgets(b, 127 ,fi); 
    121             debug("LVM2: %s", b); 
     139            fgets(b, 127, fi); 
     140            debug("LVM2:%d %s", lev, b); 
     141            if (strstr(b, "{")) 
     142                lev++; 
     143            if (strstr(b, "}")) 
     144                lev--; 
    122145            switch (state) { 
    123146            case 0: 
    124               sscanf(b, "extent_size = %d", &extent); 
    125               if (strstr(b, "physical_volumes")) state = 1; 
    126               break; 
     147                sscanf(b, "extent_size = %d", &extent); 
     148                if (strstr(b, "physical_volumes")) 
     149                    state = 1; 
     150                break; 
    127151            case 1: 
    128               if (sscanf(b, "pe_start = %lld", offset) == 1) state = -1; 
    129               break; 
     152                if (sscanf(b, "id = \"%38s", uuid) == 1) { 
     153                    if (uuid_compare(pvuuid, uuid)) 
     154                        state = 2; 
     155                } 
     156                break; 
     157            case 2: 
     158                if (sscanf(b, "pe_start = %lld", offset) == 1) 
     159                    state = -1; 
     160                break; 
     161            case -1: 
     162                sscanf(b, "pe_count = %d", &pe_count); 
     163                break; 
    130164            } 
    131             sscanf(b, "pe_count = %d", &pe_count); 
    132             if (strstr(b, "}")) break; 
    133           } 
    134         if (state != -1)  
    135           { 
     165            if (strstr(b, "}") && lev == 2 && state == -1) 
     166                break; 
     167        } 
     168        if (state != -1) { 
    136169            debug("LVM2 pe_start not found!\n"); 
    137170            *offset = 0; 
    138171            return; 
    139          
     172       
    140173        debug("LVM: Saving %lld sectors\n", *offset); 
    141174        *offset *= 512; 
    142175        lvm_sect = extent * pe_count; 
    143      
    144     
     176   
     177 
    145178 
    146179    fclose(fi);