diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c index 154e68725a8e..482a9cd87874 100644 --- a/lib/libdisk/disk.c +++ b/lib/libdisk/disk.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: disk.c,v 1.2 1995/04/29 01:55:21 phk Exp $ + * $Id: disk.c,v 1.3 1995/04/29 04:00:55 phk Exp $ * */ @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -64,9 +65,11 @@ Int_Open_Disk(char *name, u_long size) if (!size) size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size; - Add_Chunk(d, 0, size, name,whole,0,0); + if (Add_Chunk(d, 0, size, name,whole,0,0)) + warn("Failed to add 'whole' chunk"); if (ds.dss_slices[COMPATIBILITY_SLICE].ds_offset) - Add_Chunk(d, 0, 1, "-",reserved,0,0); + if (Add_Chunk(d, 0, 1, "-",reserved,0,0)) + warn("Failed to add MBR chunk"); for(i=BASE_SLICE;id_npartitions; j++) { - char pname[20]; sprintf(pname,"%s%c",sname,j+'a'); - if (j == 2) + if (j == 2 || j == 3) continue; if (!dl->d_partitions[j].p_size) continue; - Add_Chunk(d, + if (Add_Chunk(d, dl->d_partitions[j].p_offset, dl->d_partitions[j].p_size, - pname,part,0,0); + pname,part,0,0)) + warn("Failed to add chunk for partition %c",j + 'a'); } + sprintf(pname,"%sd",sname); + if (!dl->d_partitions[3].p_size) + continue; + Add_Chunk(d, + dl->d_partitions[3].p_offset, + dl->d_partitions[3].p_size, + pname,part,0,0); } free(dl); } @@ -138,10 +151,11 @@ Debug_Disk(struct disk *d) void Free_Disk(struct disk *d) { - if(d->chunks) - Free_Chunk(d->chunks); - if(d->name) - free(d->name); + if(d->chunks) Free_Chunk(d->chunks); + if(d->name) free(d->name); + if(d->bootmgr) free(d->bootmgr); + if(d->boot1) free(d->boot1); + if(d->boot2) free(d->boot2); free(d); } @@ -155,6 +169,18 @@ Clone_Disk(struct disk *d) *d2 = *d; d2->name = strdup(d2->name); d2->chunks = Clone_Chunk(d2->chunks); + if(d2->bootmgr) { + d2->bootmgr = malloc(DOSPARTOFF); + memcpy(d2->bootmgr,d->bootmgr,DOSPARTOFF); + } + if(d2->boot1) { + d2->boot1 = malloc(512); + memcpy(d2->boot1,d->boot1,512); + } + if(d2->boot2) { + d2->boot2 = malloc(512*7); + memcpy(d2->boot2,d->boot2,512*7); + } return d2; } @@ -165,3 +191,62 @@ Collapse_Disk(struct disk *d) while(Collapse_Chunk(d,d->chunks)) ; } + +static char * device_list[] = {"wd","sd",0}; + +char ** +Disk_Names() +{ + int i,j,k; + char disk[25]; + char diskname[25]; + struct stat st; + struct diskslices ds; + int fd; + static char **disks; + + disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS)); + memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS)); + k = 0; + for (j = 0; device_list[j]; j++) { + for (i = 0; i < 10; i++) { + sprintf(diskname, "%s%d", device_list[j], i); + sprintf(disk, "/dev/r%s", diskname); + if (stat(disk, &st) || !(st.st_mode & S_IFCHR)) + continue; + if ((fd = open(disk, O_RDWR)) == -1) + continue; + if (ioctl(fd, DIOCGSLICEINFO, &ds) == -1) { + close(fd); + continue; + } + disks[k++] = strdup(diskname); + if(k == MAX_NO_DISKS) + return disks; + } + } + return disks; +} + +void +Set_Boot_Mgr(struct disk *d, u_char *b) +{ + if (d->bootmgr) + free(d->bootmgr); + d->bootmgr = malloc(DOSPARTOFF); + if(!d->bootmgr) err(1,"malloc failed"); + memcpy(d->bootmgr,b,DOSPARTOFF); +} + +void +Set_Boot_Blocks(struct disk *d, u_char *b1, u_char *b2) +{ + if (d->boot1) free(d->boot1); + d->boot1 = malloc(512); + if(!d->boot1) err(1,"malloc failed"); + memcpy(d->boot1,b1,512); + if (d->boot2) free(d->boot2); + d->boot2 = malloc(7*512); + if(!d->boot2) err(1,"malloc failed"); + memcpy(d->boot2,b2,7*512); +} diff --git a/lib/libdisk/libdisk.h b/lib/libdisk/libdisk.h index e4412cf1ebdc..8561bf04320f 100644 --- a/lib/libdisk/libdisk.h +++ b/lib/libdisk/libdisk.h @@ -6,10 +6,13 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: libdisk.h,v 1.2 1995/04/29 01:55:23 phk Exp $ + * $Id: libdisk.h,v 1.3 1995/04/29 04:00:55 phk Exp $ * */ +#define MAX_NO_DISKS 20 + /* Max # of disks Disk_Names() will return */ + typedef enum {whole, foo, fat, freebsd, extended, part, unused, reserved} chunk_e; #define CHAR_N static char *chunk_n[] = { \ @@ -26,6 +29,9 @@ struct disk { u_long bios_cyl; u_long bios_hd; u_long bios_sect; + u_char *bootmgr; + u_char *boot1; + u_char *boot2; struct chunk *chunks; }; @@ -113,12 +119,28 @@ CheckRules(struct disk *); /* Return char* to warnings about broken design rules in this disklayout */ +char ** +Disk_Names(); + /* Return char** with all disk's names (wd0, wd1 ...). You must free + * each pointer, as well as the array by hand + */ + +void +Set_Boot_Mgr(struct disk *d, u_char *bootmgr); + /* Use this boot-manager on this disk. Gets written when Write_Disk() + * is called + */ + +void +Set_Boot_Blocks(struct disk *d, u_char *boot1, u_char *boot2); + /* Use these boot-blocks on this disk. Gets written when Write_Disk() + * is called + */ + /* * Implementation details >>> DO NOT USE <<< */ -struct disk *Int_Open_Disk(char *devname, u_long maxsize); - void Debug_Chunk(struct chunk *); void Free_Chunk(struct chunk *); struct chunk * Clone_Chunk(struct chunk *); @@ -131,5 +153,81 @@ int Aligned(struct disk *d, u_long offset); u_long Next_Aligned(struct disk *d, u_long offset); u_long Prev_Aligned(struct disk *d, u_long offset); struct chunk * Find_Mother_Chunk(struct chunk *, u_long , u_long , chunk_e); +struct disk * Int_Open_Disk(char *name, u_long size); #define dprintf printf + +/* TODO + * + * Need a error string mechanism from the functions instead of warn() + * + * Make sure only FreeBSD start at offset==0 + * + * Make sure all MBR+extended children are aligned at create. + * + * Collapse must align. + * + * Make Write_Disk(struct disk*) + * + * Consider booting from OnTrack'ed disks. + * + * Get Bios-geom, ST506 & OnTrack from driver (or otherwise) + * + * Make Create_DWIM(). + * + * + *Sample output from tst01: + * + * Debug_Disk(wd0) flags=0 real_geom=0/0/0 bios_geom=0/0/0 + * >> 0x3d040 0 1411200 1411199 wd0 0 whole 0 0 + * >>>> 0x3d080 0 960120 960119 wd0s1 3 freebsd 0 8 + * >>>>>> 0x3d100 0 40960 40959 wd0s1a 5 part 0 0 + * >>>>>> 0x3d180 40960 131072 172031 wd0s1b 5 part 0 0 + * >>>>>> 0x3d1c0 172032 409600 581631 wd0s1e 5 part 0 0 + * >>>>>> 0x3d200 581632 378488 960119 wd0s1f 5 part 0 0 + * >>>> 0x3d140 960120 5670 965789 wd0s2 4 extended 0 8 + * >>>>>> 0x3d240 960120 1 960120 - 7 reserved 0 8 + * >>>>>> 0x3d2c0 960121 62 960182 - 6 unused 0 0 + * >>>>>> 0x3d0c0 960183 5607 965789 wd0s5 2 fat 0 8 + * >>>> 0x3d280 965790 1890 967679 wd0s3 1 foo -2 8 + * >>>> 0x3d300 967680 443520 1411199 wd0s4 3 freebsd 0 8 + * >>>>>> 0x3d340 967680 443520 1411199 wd0s4a 5 part 0 0 + * + * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + * level chunkptr start size end name type subtype flags + * + * Underlying data structure: + * + * Legend: + * --> part + * | + * v next + * + * --> --> + * | | + * | v + * | + * | | + * | v + * | + * | | + * | v + * | + * | + * v + * --> + * | | + * | v + * | + * | | + * | v + * | + * | + * v + * + * | + * v + * --> + * + * + */ diff --git a/lib/libdisk/tst01.c b/lib/libdisk/tst01.c index 8ed705a614ad..887c4ea54a16 100644 --- a/lib/libdisk/tst01.c +++ b/lib/libdisk/tst01.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: tst01.c,v 1.2 1995/04/29 01:55:25 phk Exp $ + * $Id: tst01.c,v 1.3 1995/04/29 04:00:57 phk Exp $ * */ @@ -24,7 +24,7 @@ CHAR_N; int main(int argc, char **argv) { - struct disk *d,*db; + struct disk *d; char myprompt[BUFSIZ]; char *p,*q=0; char **cp,*cmds[200]; @@ -95,18 +95,14 @@ main(int argc, char **argv) Collapse_Disk(d); continue; } - if (!strcasecmp(*cmds,"read")) { - db=d; - if (cmds[1]) - d = Open_Disk(cmds[1]); - else - d = Open_Disk(db->name); - if (!d) { - fprintf(stderr,"Failed to open %s\n",argv[1]); - d = db; - } else { - Free_Disk(db); - } + if (!strcasecmp(*cmds,"list")) { + cp = Disk_Names(); + printf("Disks:"); + for(i=0;cp[i];i++) { + printf(" %s",cp[i]); + free(cp[i]); + } + free(cp); continue; } if (!strcasecmp(*cmds,"create") && ncmd == 6) { @@ -128,6 +124,7 @@ main(int argc, char **argv) printf("\tcollapse [pointer]\n"); printf("\tcreate offset size enum subtype flags\n"); printf("\tdelete pointer\n"); + printf("\tlist\n"); printf("\tphys cyl hd sect\n"); printf("\tquit\n"); printf("\tread [disk]\n"); diff --git a/release/libdisk/disk.c b/release/libdisk/disk.c index 154e68725a8e..482a9cd87874 100644 --- a/release/libdisk/disk.c +++ b/release/libdisk/disk.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: disk.c,v 1.2 1995/04/29 01:55:21 phk Exp $ + * $Id: disk.c,v 1.3 1995/04/29 04:00:55 phk Exp $ * */ @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -64,9 +65,11 @@ Int_Open_Disk(char *name, u_long size) if (!size) size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size; - Add_Chunk(d, 0, size, name,whole,0,0); + if (Add_Chunk(d, 0, size, name,whole,0,0)) + warn("Failed to add 'whole' chunk"); if (ds.dss_slices[COMPATIBILITY_SLICE].ds_offset) - Add_Chunk(d, 0, 1, "-",reserved,0,0); + if (Add_Chunk(d, 0, 1, "-",reserved,0,0)) + warn("Failed to add MBR chunk"); for(i=BASE_SLICE;id_npartitions; j++) { - char pname[20]; sprintf(pname,"%s%c",sname,j+'a'); - if (j == 2) + if (j == 2 || j == 3) continue; if (!dl->d_partitions[j].p_size) continue; - Add_Chunk(d, + if (Add_Chunk(d, dl->d_partitions[j].p_offset, dl->d_partitions[j].p_size, - pname,part,0,0); + pname,part,0,0)) + warn("Failed to add chunk for partition %c",j + 'a'); } + sprintf(pname,"%sd",sname); + if (!dl->d_partitions[3].p_size) + continue; + Add_Chunk(d, + dl->d_partitions[3].p_offset, + dl->d_partitions[3].p_size, + pname,part,0,0); } free(dl); } @@ -138,10 +151,11 @@ Debug_Disk(struct disk *d) void Free_Disk(struct disk *d) { - if(d->chunks) - Free_Chunk(d->chunks); - if(d->name) - free(d->name); + if(d->chunks) Free_Chunk(d->chunks); + if(d->name) free(d->name); + if(d->bootmgr) free(d->bootmgr); + if(d->boot1) free(d->boot1); + if(d->boot2) free(d->boot2); free(d); } @@ -155,6 +169,18 @@ Clone_Disk(struct disk *d) *d2 = *d; d2->name = strdup(d2->name); d2->chunks = Clone_Chunk(d2->chunks); + if(d2->bootmgr) { + d2->bootmgr = malloc(DOSPARTOFF); + memcpy(d2->bootmgr,d->bootmgr,DOSPARTOFF); + } + if(d2->boot1) { + d2->boot1 = malloc(512); + memcpy(d2->boot1,d->boot1,512); + } + if(d2->boot2) { + d2->boot2 = malloc(512*7); + memcpy(d2->boot2,d->boot2,512*7); + } return d2; } @@ -165,3 +191,62 @@ Collapse_Disk(struct disk *d) while(Collapse_Chunk(d,d->chunks)) ; } + +static char * device_list[] = {"wd","sd",0}; + +char ** +Disk_Names() +{ + int i,j,k; + char disk[25]; + char diskname[25]; + struct stat st; + struct diskslices ds; + int fd; + static char **disks; + + disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS)); + memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS)); + k = 0; + for (j = 0; device_list[j]; j++) { + for (i = 0; i < 10; i++) { + sprintf(diskname, "%s%d", device_list[j], i); + sprintf(disk, "/dev/r%s", diskname); + if (stat(disk, &st) || !(st.st_mode & S_IFCHR)) + continue; + if ((fd = open(disk, O_RDWR)) == -1) + continue; + if (ioctl(fd, DIOCGSLICEINFO, &ds) == -1) { + close(fd); + continue; + } + disks[k++] = strdup(diskname); + if(k == MAX_NO_DISKS) + return disks; + } + } + return disks; +} + +void +Set_Boot_Mgr(struct disk *d, u_char *b) +{ + if (d->bootmgr) + free(d->bootmgr); + d->bootmgr = malloc(DOSPARTOFF); + if(!d->bootmgr) err(1,"malloc failed"); + memcpy(d->bootmgr,b,DOSPARTOFF); +} + +void +Set_Boot_Blocks(struct disk *d, u_char *b1, u_char *b2) +{ + if (d->boot1) free(d->boot1); + d->boot1 = malloc(512); + if(!d->boot1) err(1,"malloc failed"); + memcpy(d->boot1,b1,512); + if (d->boot2) free(d->boot2); + d->boot2 = malloc(7*512); + if(!d->boot2) err(1,"malloc failed"); + memcpy(d->boot2,b2,7*512); +} diff --git a/release/libdisk/libdisk.h b/release/libdisk/libdisk.h index e4412cf1ebdc..8561bf04320f 100644 --- a/release/libdisk/libdisk.h +++ b/release/libdisk/libdisk.h @@ -6,10 +6,13 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: libdisk.h,v 1.2 1995/04/29 01:55:23 phk Exp $ + * $Id: libdisk.h,v 1.3 1995/04/29 04:00:55 phk Exp $ * */ +#define MAX_NO_DISKS 20 + /* Max # of disks Disk_Names() will return */ + typedef enum {whole, foo, fat, freebsd, extended, part, unused, reserved} chunk_e; #define CHAR_N static char *chunk_n[] = { \ @@ -26,6 +29,9 @@ struct disk { u_long bios_cyl; u_long bios_hd; u_long bios_sect; + u_char *bootmgr; + u_char *boot1; + u_char *boot2; struct chunk *chunks; }; @@ -113,12 +119,28 @@ CheckRules(struct disk *); /* Return char* to warnings about broken design rules in this disklayout */ +char ** +Disk_Names(); + /* Return char** with all disk's names (wd0, wd1 ...). You must free + * each pointer, as well as the array by hand + */ + +void +Set_Boot_Mgr(struct disk *d, u_char *bootmgr); + /* Use this boot-manager on this disk. Gets written when Write_Disk() + * is called + */ + +void +Set_Boot_Blocks(struct disk *d, u_char *boot1, u_char *boot2); + /* Use these boot-blocks on this disk. Gets written when Write_Disk() + * is called + */ + /* * Implementation details >>> DO NOT USE <<< */ -struct disk *Int_Open_Disk(char *devname, u_long maxsize); - void Debug_Chunk(struct chunk *); void Free_Chunk(struct chunk *); struct chunk * Clone_Chunk(struct chunk *); @@ -131,5 +153,81 @@ int Aligned(struct disk *d, u_long offset); u_long Next_Aligned(struct disk *d, u_long offset); u_long Prev_Aligned(struct disk *d, u_long offset); struct chunk * Find_Mother_Chunk(struct chunk *, u_long , u_long , chunk_e); +struct disk * Int_Open_Disk(char *name, u_long size); #define dprintf printf + +/* TODO + * + * Need a error string mechanism from the functions instead of warn() + * + * Make sure only FreeBSD start at offset==0 + * + * Make sure all MBR+extended children are aligned at create. + * + * Collapse must align. + * + * Make Write_Disk(struct disk*) + * + * Consider booting from OnTrack'ed disks. + * + * Get Bios-geom, ST506 & OnTrack from driver (or otherwise) + * + * Make Create_DWIM(). + * + * + *Sample output from tst01: + * + * Debug_Disk(wd0) flags=0 real_geom=0/0/0 bios_geom=0/0/0 + * >> 0x3d040 0 1411200 1411199 wd0 0 whole 0 0 + * >>>> 0x3d080 0 960120 960119 wd0s1 3 freebsd 0 8 + * >>>>>> 0x3d100 0 40960 40959 wd0s1a 5 part 0 0 + * >>>>>> 0x3d180 40960 131072 172031 wd0s1b 5 part 0 0 + * >>>>>> 0x3d1c0 172032 409600 581631 wd0s1e 5 part 0 0 + * >>>>>> 0x3d200 581632 378488 960119 wd0s1f 5 part 0 0 + * >>>> 0x3d140 960120 5670 965789 wd0s2 4 extended 0 8 + * >>>>>> 0x3d240 960120 1 960120 - 7 reserved 0 8 + * >>>>>> 0x3d2c0 960121 62 960182 - 6 unused 0 0 + * >>>>>> 0x3d0c0 960183 5607 965789 wd0s5 2 fat 0 8 + * >>>> 0x3d280 965790 1890 967679 wd0s3 1 foo -2 8 + * >>>> 0x3d300 967680 443520 1411199 wd0s4 3 freebsd 0 8 + * >>>>>> 0x3d340 967680 443520 1411199 wd0s4a 5 part 0 0 + * + * ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ + * level chunkptr start size end name type subtype flags + * + * Underlying data structure: + * + * Legend: + * --> part + * | + * v next + * + * --> --> + * | | + * | v + * | + * | | + * | v + * | + * | | + * | v + * | + * | + * v + * --> + * | | + * | v + * | + * | | + * | v + * | + * | + * v + * + * | + * v + * --> + * + * + */ diff --git a/release/libdisk/tst01.c b/release/libdisk/tst01.c index 8ed705a614ad..887c4ea54a16 100644 --- a/release/libdisk/tst01.c +++ b/release/libdisk/tst01.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: tst01.c,v 1.2 1995/04/29 01:55:25 phk Exp $ + * $Id: tst01.c,v 1.3 1995/04/29 04:00:57 phk Exp $ * */ @@ -24,7 +24,7 @@ CHAR_N; int main(int argc, char **argv) { - struct disk *d,*db; + struct disk *d; char myprompt[BUFSIZ]; char *p,*q=0; char **cp,*cmds[200]; @@ -95,18 +95,14 @@ main(int argc, char **argv) Collapse_Disk(d); continue; } - if (!strcasecmp(*cmds,"read")) { - db=d; - if (cmds[1]) - d = Open_Disk(cmds[1]); - else - d = Open_Disk(db->name); - if (!d) { - fprintf(stderr,"Failed to open %s\n",argv[1]); - d = db; - } else { - Free_Disk(db); - } + if (!strcasecmp(*cmds,"list")) { + cp = Disk_Names(); + printf("Disks:"); + for(i=0;cp[i];i++) { + printf(" %s",cp[i]); + free(cp[i]); + } + free(cp); continue; } if (!strcasecmp(*cmds,"create") && ncmd == 6) { @@ -128,6 +124,7 @@ main(int argc, char **argv) printf("\tcollapse [pointer]\n"); printf("\tcreate offset size enum subtype flags\n"); printf("\tdelete pointer\n"); + printf("\tlist\n"); printf("\tphys cyl hd sect\n"); printf("\tquit\n"); printf("\tread [disk]\n");