summaryrefslogtreecommitdiffstats
path: root/lib/libdisk/disk.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1995-04-28 23:57:04 +0000
committerphk <phk@FreeBSD.org>1995-04-28 23:57:04 +0000
commit773ad9f330436a3c7484840bf3a542958fd14c96 (patch)
tree52b9513433e8fa4d94139f8ec002668ef2560b11 /lib/libdisk/disk.c
parente31775a1086bdadc2cd01b0eed72cb217fb1e9e8 (diff)
downloadFreeBSD-src-773ad9f330436a3c7484840bf3a542958fd14c96.zip
FreeBSD-src-773ad9f330436a3c7484840bf3a542958fd14c96.tar.gz
This is a revision 0.00 of the backend stuff for the fdisk/disklabel stuff
in the new sysinstall. If you want to give a helping hand, then send email to phk@FreeBSD.ORG. DO NOT COMMIT TO THIS DIRECTORY!
Diffstat (limited to 'lib/libdisk/disk.c')
-rw-r--r--lib/libdisk/disk.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/lib/libdisk/disk.c b/lib/libdisk/disk.c
new file mode 100644
index 0000000..5ff2a21
--- /dev/null
+++ b/lib/libdisk/disk.c
@@ -0,0 +1,183 @@
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * $Id$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <err.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/disklabel.h>
+#include <sys/diskslice.h>
+#include <sys/queue.h>
+#include "libdisk.h"
+
+#define DOSPTYP_EXTENDED 5
+#define DOSPTYP_ONTRACK 84
+
+struct disk *
+Open_Disk(char *name)
+{
+ return Int_Open_Disk(name,0);
+}
+
+struct disk *
+Int_Open_Disk(char *name, u_long size)
+{
+ int i,fd;
+ struct diskslices ds;
+ char device[64];
+ struct disk *d;
+
+ strcpy(device,"/dev/r");
+ strcat(device,name);
+
+ fd = open(device,O_RDONLY);
+ if (fd < 0) {
+ warn("open(%s) failed",device);
+ return 0;
+ }
+ i = ioctl(fd,DIOCGSLICEINFO,&ds);
+ if (i < 0) {
+ warn("DIOCSLICEINFO(%s) failed",device);
+ close(fd);
+ return 0;
+ }
+
+ d = (struct disk *)malloc(sizeof *d);
+ if(!d) err(1,"malloc failed");
+
+ memset(d,0,sizeof *d);
+
+ d->name = strdup(name);
+
+ if (!size)
+ size = ds.dss_slices[WHOLE_DISK_SLICE].ds_size;
+
+ Add_Chunk(d, 0, size, name,whole,0,0);
+
+ for(i=2;i<ds.dss_nslices;i++) {
+ char sname[20];
+ chunk_e ce;
+ u_long flags=0;
+ int subtype=0;
+ if (! ds.dss_slices[i].ds_size)
+ continue;
+ sprintf(sname,"%ss%d",name,i-1);
+ switch (ds.dss_slices[i].ds_type) {
+ case 0xa5:
+ ce = freebsd;
+ break;
+ case 0x1:
+ case 0x6:
+ ce = fat;
+ break;
+ case DOSPTYP_EXTENDED:
+ ce = extended;
+ break;
+ default:
+ ce = foo;
+ subtype = -ds.dss_slices[i].ds_type;
+ break;
+ }
+ flags |= CHUNK_ALIGN;
+ Add_Chunk(d,ds.dss_slices[i].ds_offset,
+ ds.dss_slices[i].ds_size, sname,ce,subtype,flags);
+ if (ds.dss_slices[i].ds_type == 0xa5) {
+ struct disklabel *dl;
+ int j;
+
+ dl = read_disklabel(fd,
+ ds.dss_slices[i].ds_offset + LABELSECTOR);
+ if(dl) {
+ for(j=0; j < dl->d_npartitions; j++) {
+ char pname[20];
+ sprintf(pname,"%s%c",sname,j+'a');
+ if (j == 2)
+ continue;
+ if (!dl->d_partitions[j].p_size)
+ continue;
+ Add_Chunk(d,
+ dl->d_partitions[j].p_offset,
+ dl->d_partitions[j].p_size,
+ pname,part,0,0);
+ }
+ }
+ free(dl);
+ }
+ }
+ close(fd);
+ return d;
+}
+
+void
+Debug_Disk(struct disk *d)
+{
+ printf("Debug_Disk(%s)",d->name);
+ printf(" flags=%lx",d->flags);
+ printf(" real_geom=%lu/%lu/%lu",d->real_cyl,d->real_hd,d->real_sect);
+ printf(" bios_geom=%lu/%lu/%lu\n",d->bios_cyl,d->bios_hd,d->bios_sect);
+ Debug_Chunk(d->chunks);
+}
+
+void
+Free_Disk(struct disk *d)
+{
+ if(d->chunks)
+ Free_Chunk(d->chunks);
+ if(d->name)
+ free(d->name);
+ free(d);
+}
+
+struct disk *
+Clone_Disk(struct disk *d)
+{
+ struct disk *d2;
+
+ d2 = (struct disk*) malloc(sizeof *d2);
+ if(!d2) err(1,"malloc failed");
+ *d2 = *d;
+ d2->name = strdup(d2->name);
+ d2->chunks = Clone_Chunk(d2->chunks);
+ return d2;
+}
+
+void
+Collapse_Disk(struct disk *d)
+{
+
+ while(Collapse_Chunk(d,d->chunks))
+ ;
+}
+
+int
+Aligned(struct disk *d, u_long offset)
+{
+ if (offset % d->bios_sect)
+ return 0;
+ return 1;
+}
+
+u_long
+Prev_Aligned(struct disk *d, u_long offset)
+{
+ return (offset / d->bios_sect) * d->bios_sect;
+}
+
+u_long
+Next_Aligned(struct disk *d, u_long offset)
+{
+ return Prev_Aligned(d,offset + d->bios_sect);
+}
OpenPOWER on IntegriCloud