diff -urpN lilo-22.8-alt-devmapper/boot.c lilo-22.8-alt-md-devmapper/boot.c --- lilo-22.8-alt-devmapper/boot.c 2013-08-11 01:15:44.000000000 +0300 +++ lilo-22.8-alt-md-devmapper/boot.c 2013-08-11 02:18:05.000000000 +0300 @@ -262,6 +262,9 @@ char *boot_mbr(const char *boot, int tab #else struct stat st; dev_t dev; +#ifdef LCF_DEVMAPPER + dev_t tdev; +#endif /* LCF_DEVMAPPER */ DEVICE d; int mask, k; char *npart = NULL; @@ -269,6 +272,10 @@ char *boot_mbr(const char *boot, int tab k = 0; if (stat(boot,&st) < 0) die("stat %s: %s",boot,strerror(errno)); dev = S_ISREG(st.st_mode) ? st.st_dev : st.st_rdev; +#ifdef LCF_DEVMAPPER + tdev = (dev_t)dm_get_target_device((int)dev); + if (dev == tdev) { +#endif /* LCF_DEVMAPPER */ if ( (mask = has_partitions(dev)) ) { k = dev & ~mask; k = !table ? 1 : k>=1 && k<=4; @@ -278,7 +285,14 @@ char *boot_mbr(const char *boot, int tab dev_close(&d); } } - +#ifdef LCF_DEVMAPPER + } else { + k = 1; + dev_open(&d, tdev, O_BYPASS); + npart = stralloc(d.name); + dev_close(&d); + } +#endif /* LCF_DEVMAPPER */ #endif if (verbose>=3) { diff -urpN lilo-22.8-alt-devmapper/geometry.c lilo-22.8-alt-md-devmapper/geometry.c --- lilo-22.8-alt-devmapper/geometry.c 2013-08-11 02:17:40.000000000 +0300 +++ lilo-22.8-alt-md-devmapper/geometry.c 2013-08-11 02:18:05.000000000 +0300 @@ -884,157 +884,191 @@ is_devmapper_device(int device) return 1; return 0; } -#endif /* LCF_DEVMAPPER */ -void geo_get(GEOMETRY *geo,int device,int user_device,int all) +static DM_TABLE * +dm_add_table(int device) { - DT_ENTRY *walk; - int inherited,keep_cyls,is_raid=0; -#ifdef LCF_DEVMAPPER - while (is_devmapper_device(device)) { DM_TABLE *dm_table; + struct dm_task *dmt; + struct dm_names *names = 0; + void *next = NULL; + char dmdev[PATH_MAX + 1]; + char buf[PATH_MAX + 1]; + char *slash = 0; + uint32_t nnext = 0; - for(dm_table = dmtab; dm_table; dm_table = dm_table->next) - if (dm_table->device == device) - break; - - if (dm_table) { - DM_TARGET *target; - - device = 0; - for(target = dm_table->target; target; target = target->next) - device = target->device; - } else { - struct dm_task *dmt; - struct dm_names *names = 0; - void *next = NULL; - char dmdev[PATH_MAX + 1]; - char buf[PATH_MAX + 1]; - char *slash = 0; - uint32_t nnext = 0; - - if (!(dmt = dm_task_create(DM_DEVICE_LIST))) + if (!(dmt = dm_task_create(DM_DEVICE_LIST))) die("device-mapper: dm_task_create(DM_DEVICE_LIST) failed"); - if (!dm_task_run(dmt)) + if (!dm_task_run(dmt)) die("device-mapper: dm_task_run(DM_DEVICE_LIST) failed"); - if (!(names = dm_task_get_names(dmt))) + if (!(names = dm_task_get_names(dmt))) die("device-mapper: dm_task_get_names() failed"); - if (!names->dev) + if (!names->dev) die("device-mapper: dm_task_get_names() names->dev"); - do { + do { names = (void *) names + nnext; - if (verbose > 3) { - printf("device-mapper: device: 0x%llx: name: [%s]\n", - names->dev, names->name); - } nnext = names->next; if (names->dev == device) { - strncpy(dmdev, names->name, PATH_MAX); - dmdev[PATH_MAX] = 0; - slash = dmdev; - break; + strncpy(dmdev, names->name, PATH_MAX); + dmdev[PATH_MAX] = 0; + slash = dmdev; + break; } - } while (nnext); - - if (!slash || !*slash) + } while (nnext); + + if (!slash || !*slash) die("device-mapper: name not found for device [%d]\n", device); - - dm_task_destroy(dmt); - - if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) + + dm_task_destroy(dmt); + + if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) die("device-mapper: dm_task_create(DM_DEVICE_TABLE) failed"); - if (!dm_task_set_name(dmt, slash)) + if (!dm_task_set_name(dmt, slash)) die("device-mapper: dm_task_set_name(\"%s\") failed",dmdev); - if (!dm_task_run(dmt)) + if (!dm_task_run(dmt)) die("device-mapper: dm_task_run(DM_DEVICE_TABLE) failed"); - - dm_table = alloc_t(DM_TABLE); - dm_table->device = device; - dm_table->target = NULL; - dm_table->next = dmtab; - dmtab = dm_table; - - device = 0; - - do { + + dm_table = alloc_t(DM_TABLE); + dm_table->device = device; + dm_table->target = NULL; + dm_table->next = dmtab; + dmtab = dm_table; + + do { DM_TARGET *target; uint64_t start,length; int major,minor; char *target_type,*params; char *p; - + next = dm_get_next_target(dmt, next, &start, &length, - &target_type, ¶ms); - + &target_type, ¶ms); + if (!target_type) continue; - if (strcmp(target_type, "linear") != 0) - die("device-mapper: only linear boot device supported"); - + die("device-mapper: only linear boot device supported"); + target = alloc_t(DM_TARGET); target->start = start; target->length = length; if (dm_version_nr < 4 && - isxdigit(params[0]) && - isxdigit(params[1]) && - params[2] == ':' && - isxdigit(params[3]) && - isxdigit(params[4])) { /* old 2.4 format */ - if (sscanf(params, "%02x:%02x %"PRIu64, &major, &minor, &target->offset) != 3) - die("device-mapper: parse error in linear params (\"%s\")", params); + isxdigit(params[0]) && + isxdigit(params[1]) && + params[2] == ':' && + isxdigit(params[3]) && + isxdigit(params[4])) { /* old 2.4 format */ + if (sscanf(params, "%02x:%02x %"PRIu64, &major, &minor, &target->offset) != 3) + die("device-mapper: parse error in linear params (\"%s\")", params); } else if (isdigit(params[0]) && - strchr(params, ':')) { /* dm_bdevname/format_dev_t (>= 2.6.0-test4?) format */ - if (sscanf(params, "%u:%u %"PRIu64, &major, &minor, &target->offset) != 3) - die("device-mapper: parse error in linear params (\"%s\")", params); + strchr(params, ':')) { /* dm_bdevname/format_dev_t (>= 2.6.0-test4?) format */ + if (sscanf(params, "%u:%u %"PRIu64, &major, &minor, &target->offset) != 3) + die("device-mapper: parse error in linear params (\"%s\")", params); } else { /* >= 2.5.69 format, this should go away soon */ - struct stat st; - FILE *file; - - p = strrchr(params, ' '); - if (p == NULL) - die("device-mapper: parse error in linear params (\"%s\")", params); - *p = 0; - snprintf(buf, sizeof buf, DEV_DIR "/%s", params); /* let's hope it's there */ - if (stat(buf, &st) == 0) { - if (!S_ISBLK(st.st_mode)) - die("device-mapper: %s is not a valid block device", buf); - major = MAJOR(st.st_rdev); - minor = MINOR(st.st_rdev); - } else { /* let's try sysfs */ - int dev; - snprintf(buf, sizeof buf, "/sys/block/%s/dev", params); - file = fopen(buf, "r"); - if (!file) - die("device-mapper: \"%s\" could not be opened. /sys mounted?", buf); - if (!fgets(buf, PATH_MAX, file)) - die("device-mapper: read error from \"/sys/block/%s/dev\"", params); - if (sscanf(buf, "%u:%u", &major, &minor) != 2) { - if (sscanf(buf, "%x", &dev) != 1) - die("device-mapper: error getting device from \"%s\"", buf); - major = MAJOR(dev); - minor = MINOR(dev); + struct stat st; + FILE *file; + + p = strrchr(params, ' '); + if (p == NULL) + die("device-mapper: parse error in linear params (\"%s\")", params); + *p = 0; + snprintf(buf, sizeof buf, DEV_DIR "/%s", params); /* let's hope it's there */ + if (stat(buf, &st) == 0) { + if (!S_ISBLK(st.st_mode)) + die("device-mapper: %s is not a valid block device", buf); + major = MAJOR(st.st_rdev); + minor = MINOR(st.st_rdev); + } else { /* let's try sysfs */ + int dev; + snprintf(buf, sizeof buf, "/sys/block/%s/dev", params); + file = fopen(buf, "r"); + if (!file) + die("device-mapper: \"%s\" could not be opened. /sys mounted?", buf); + if (!fgets(buf, PATH_MAX, file)) + die("device-mapper: read error from \"/sys/block/%s/dev\"", params); + if (sscanf(buf, "%u:%u", &major, &minor) != 2) { + if (sscanf(buf, "%x", &dev) != 1) + die("device-mapper: error getting device from \"%s\"", buf); + major = MAJOR(dev); + minor = MINOR(dev); + } + (void) fclose(file); } - (void) fclose(file); - } - *p = ' '; - if (sscanf(p+1, "%"PRIu64, &target->offset) != 1) - die("device-mapper: parse error in linear params (\"%s\")", params); + *p = ' '; + if (sscanf(p+1, "%"PRIu64, &target->offset) != 1) + die("device-mapper: parse error in linear params (\"%s\")", params); } target->device = (major << 8) | minor; - if (!device) - device = target->device; target->next = dm_table->target; dm_table->target = target; - } while(next); - dm_task_destroy(dmt); + } while(next); + + dm_task_destroy(dmt); + + return dmtab; +} + +static DM_TABLE * +dm_get_table(int device) +{ + DM_TABLE *dm_table = NULL; + DM_TARGET *target; + + while (is_devmapper_device(device)) { + for(dm_table = dmtab; dm_table; dm_table = dm_table->next) { + if (dm_table->device == device) + break; + } + + if (dm_table == NULL) + dm_table = dm_add_table(device); + + for(target = dm_table->target; target; target = target->next) { + device = target->device; + } } - if (!device) - die("device-mapper: Error finding real device"); - geo->base_dev = device; - } + return dm_table; +} + +uint64_t dm_get_target_offset(int device) +{ + DM_TABLE *dm_table = dm_get_table(device); + DM_TARGET *target; + uint64_t offset = 0; + + if (dm_table) { + for(target = dm_table->target; target; target = target->next) { + offset += target->offset; + } + } + + return offset; +} + +int dm_get_target_device(int device) +{ + DM_TABLE *dm_table = dm_get_table(device); + DM_TARGET *target; + + if (dm_table) { + for(target = dm_table->target; target; target = target->next) { + device = target->device; + } + } + + return device; +} + +#endif /* LCF_DEVMAPPER */ + +void geo_get(GEOMETRY *geo, int device, int user_device, int all) +{ + DT_ENTRY *walk; + int inherited, keep_cyls, is_raid=0; +#ifdef LCF_DEVMAPPER + geo->base_dev = device = dm_get_target_device(device); #endif /* LCF_DEVMAPPER */ if (verbose>=5) printf("geo_get: device %04X, all=%d\n", device, all); diff -urpN lilo-22.8-alt-devmapper/geometry.h lilo-22.8-alt-md-devmapper/geometry.h --- lilo-22.8-alt-devmapper/geometry.h 2013-08-11 01:15:44.000000000 +0300 +++ lilo-22.8-alt-md-devmapper/geometry.h 2013-08-11 02:30:27.000000000 +0300 @@ -11,6 +11,8 @@ source directory. #ifndef GEOMETRY_H #define GEOMETRY_H +#include + #define LINUX 1 #if LINUX @@ -173,5 +175,9 @@ int geo_devscan(int device); /* called to fill in a disktab with arbitrary BIOS codes */ #endif +#ifdef LCF_DEVMAPPER +uint64_t dm_get_target_offset(int device); +int dm_get_target_device(int device); +#endif #endif diff -urpN lilo-22.8-alt-devmapper/raid.c lilo-22.8-alt-md-devmapper/raid.c --- lilo-22.8-alt-devmapper/raid.c 2013-08-11 01:15:44.000000000 +0300 +++ lilo-22.8-alt-md-devmapper/raid.c 2013-08-11 02:18:05.000000000 +0300 @@ -56,7 +56,11 @@ static int is_primary(int device) { int mask; +#ifdef LCF_DEVMAPPER + mask = has_partitions(dm_get_target_device(device)); +#else mask = has_partitions(device); +#endif /* LCF_DEVMAPPER */ if (!mask) die("is_primary: Not a valid device 0x%04X", device); mask = device & ~mask; return (mask && mask<=PART_MAX); @@ -80,7 +84,11 @@ static int is_accessible(int device) { int mask; +#ifdef LCF_DEVMAPPER + mask = has_partitions(dm_get_target_device(device)); +#else mask = has_partitions(device); +#endif if (!mask) die("is_accessible: Not a valid device 0x%04X", device); mask = device & ~mask; return (mask<=PART_MAX); @@ -269,11 +277,21 @@ int raid_setup(void) disk->heads = geo.heads; disk->cylinders = geo.cylinders; disk->start = geo.start; +#ifdef LCF_DEVMAPPER + /* add offset of mapped device, =0 for real device */ + disk->start += dm_get_target_offset(device); +#endif if (ndisk==0) { raid_base = geo.start; +#ifdef LCF_DEVMAPPER + raid_base += dm_get_target_offset(device); +#endif raid_index = pass; } raid_offset[ndisk] = geo.start - raid_base; +#ifdef LCF_DEVMAPPER + raid_offset[ndisk] += dm_get_target_offset(device); +#endif raid_device[ndisk] = device; if (raid_offset[ndisk]) {