With the old sade removed, libdisk is no longer used by anything in HEAD
and uses a number of problematic pre-gpart interfaces. Since it has been entirely obsoleted by interfaces in geom, remove it.
This commit is contained in:
parent
7bc5e60204
commit
1e6b48e616
@ -38,6 +38,9 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20121230: libdisk removed
|
||||
OLD_FILES+=usr/share/man/man3/libdisk.3.gz usr/include/libdisk.h
|
||||
OLD_FILES+=usr/lib/libdisk.a usr/lib32/libdisk.a
|
||||
# 20121230: remove wrongly created directories for auditdistd
|
||||
OLD_DIRS+=var/dist
|
||||
OLD_DIRS+=var/remote
|
||||
|
@ -69,7 +69,6 @@ SUBDIR= ${SUBDIR_ORDERED} \
|
||||
libcompat \
|
||||
libdevinfo \
|
||||
libdevstat \
|
||||
libdisk \
|
||||
libdwarf \
|
||||
libedit \
|
||||
${_libefi} \
|
||||
|
@ -1,43 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "ia64"
|
||||
_open_disk= open_ia64_disk.c
|
||||
.else
|
||||
_change = change.c
|
||||
_open_disk= open_disk.c
|
||||
.endif
|
||||
|
||||
LIB= disk
|
||||
SRCS= blocks.c ${_change} chunk.c create_chunk.c disk.c ${_open_disk} \
|
||||
rules.c write_disk.c
|
||||
SRCS+= write_${MACHINE}_disk.c
|
||||
|
||||
INCS= libdisk.h
|
||||
|
||||
WARNS?= 2
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../../sys/geom
|
||||
|
||||
.if ${MACHINE} == "pc98"
|
||||
CFLAGS+= -DPC98
|
||||
.endif
|
||||
|
||||
CLEANFILES+= tmp.c tst01 tst01.o
|
||||
NO_PROFILE=
|
||||
NO_PIC=
|
||||
|
||||
MAN= libdisk.3
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
||||
tst01: tst01.o libdisk.a
|
||||
cc ${CFLAGS} -static tst01.o -o tst01 libdisk.a
|
||||
|
||||
ad0: all install tst01
|
||||
./tst01 ad0
|
||||
|
||||
da0: all install tst01
|
||||
./tst01 da0
|
||||
|
||||
da1: all install tst01
|
||||
./tst01 da1
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
void *
|
||||
read_block(int fd, daddr_t block, u_long sector_size)
|
||||
{
|
||||
void *foo;
|
||||
int i;
|
||||
|
||||
foo = malloc(sector_size);
|
||||
if (foo == NULL)
|
||||
return (NULL);
|
||||
if (-1 == lseek(fd, (off_t)block * sector_size, SEEK_SET)) {
|
||||
free (foo);
|
||||
return (NULL);
|
||||
}
|
||||
i = read(fd, foo, sector_size);
|
||||
if ((int)sector_size != i) {
|
||||
free (foo);
|
||||
return (NULL);
|
||||
}
|
||||
return foo;
|
||||
}
|
||||
|
||||
int
|
||||
write_block(int fd, daddr_t block, const void *foo, u_long sector_size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (-1 == lseek(fd, (off_t)block * sector_size, SEEK_SET))
|
||||
return (-1);
|
||||
i = write(fd, foo, sector_size);
|
||||
if ((int)sector_size != i)
|
||||
return (-1);
|
||||
return 0;
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
void
|
||||
Set_Bios_Geom(struct disk *disk, u_long cyl, u_long hd, u_long sect)
|
||||
{
|
||||
|
||||
disk->bios_cyl = cyl;
|
||||
disk->bios_hd = hd;
|
||||
disk->bios_sect = sect;
|
||||
}
|
||||
|
||||
void
|
||||
Sanitize_Bios_Geom(struct disk *disk)
|
||||
{
|
||||
int sane;
|
||||
|
||||
sane = 1;
|
||||
|
||||
if (disk->bios_cyl >= 65536)
|
||||
sane = 0;
|
||||
#ifdef PC98
|
||||
if (disk->bios_hd >= 256)
|
||||
sane = 0;
|
||||
if (disk->bios_sect >= 256)
|
||||
sane = 0;
|
||||
#else
|
||||
if (disk->bios_hd > 256)
|
||||
sane = 0;
|
||||
if (disk->bios_sect > 63)
|
||||
sane = 0;
|
||||
#endif
|
||||
#if 0 /* Disable a check on a disk size. It's too strict. */
|
||||
if (disk->bios_cyl * disk->bios_hd * disk->bios_sect !=
|
||||
disk->chunks->size)
|
||||
sane = 0;
|
||||
#endif
|
||||
if (sane)
|
||||
return;
|
||||
|
||||
/* First try something that IDE can handle */
|
||||
disk->bios_sect = 63;
|
||||
disk->bios_hd = 16;
|
||||
disk->bios_cyl = disk->chunks->size /
|
||||
(disk->bios_sect * disk->bios_hd);
|
||||
|
||||
#ifdef PC98
|
||||
if (disk->bios_cyl < 65536)
|
||||
#else
|
||||
if (disk->bios_cyl < 1024)
|
||||
#endif
|
||||
return;
|
||||
|
||||
/* Hmm, try harder... */
|
||||
/* Assume standard SCSI parameter */
|
||||
#ifdef PC98
|
||||
disk->bios_sect = 128;
|
||||
disk->bios_hd = 8;
|
||||
#else
|
||||
disk->bios_hd = 255;
|
||||
#endif
|
||||
disk->bios_cyl = disk->chunks->size /
|
||||
(disk->bios_sect * disk->bios_hd);
|
||||
|
||||
#ifdef PC98
|
||||
if (disk->bios_cyl < 65536)
|
||||
return;
|
||||
|
||||
/* Assume UIDE-133/98-A Challenger BIOS 0.9821C parameter */
|
||||
disk->bios_sect = 255;
|
||||
disk->bios_hd = 16;
|
||||
disk->bios_cyl = disk->chunks->size /
|
||||
(disk->bios_sect * disk->bios_hd);
|
||||
|
||||
if (disk->bios_cyl < 65536)
|
||||
return;
|
||||
|
||||
/* BIG-na-Drive? */
|
||||
disk->bios_hd = 255;
|
||||
disk->bios_cyl = disk->chunks->size /
|
||||
(disk->bios_sect * disk->bios_hd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
All_FreeBSD(struct disk *d, int force_all)
|
||||
{
|
||||
struct chunk *c;
|
||||
int type;
|
||||
|
||||
#ifdef PC98
|
||||
type = 0xc494;
|
||||
#else
|
||||
type = 0xa5;
|
||||
#endif
|
||||
|
||||
again:
|
||||
for (c = d->chunks->part; c; c = c->next)
|
||||
if (c->type != unused) {
|
||||
Delete_Chunk(d, c);
|
||||
goto again;
|
||||
}
|
||||
c = d->chunks;
|
||||
if (force_all) {
|
||||
Sanitize_Bios_Geom(d);
|
||||
Create_Chunk(d, c->offset, c->size, freebsd, type,
|
||||
CHUNK_FORCE_ALL, "FreeBSD");
|
||||
} else {
|
||||
Create_Chunk(d, c->offset, c->size, freebsd, type, 0,
|
||||
"FreeBSD");
|
||||
}
|
||||
}
|
@ -1,595 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
struct chunk *
|
||||
New_Chunk(void)
|
||||
{
|
||||
struct chunk *c;
|
||||
|
||||
c = malloc(sizeof *c);
|
||||
if (c != NULL)
|
||||
memset(c, 0, sizeof *c);
|
||||
return (c);
|
||||
}
|
||||
|
||||
/* Is c2 completely inside c1 ? */
|
||||
|
||||
static int
|
||||
Chunk_Inside(const struct chunk *c1, const struct chunk *c2)
|
||||
{
|
||||
/* if c1 ends before c2 do */
|
||||
if (c1->end < c2->end)
|
||||
return 0;
|
||||
/* if c1 starts after c2 do */
|
||||
if (c1->offset > c2->offset)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct chunk *
|
||||
Find_Mother_Chunk(struct chunk *chunks, daddr_t offset, daddr_t end,
|
||||
chunk_e type)
|
||||
{
|
||||
struct chunk *c1, *c2, ct;
|
||||
|
||||
ct.offset = offset;
|
||||
ct.end = end;
|
||||
switch (type) {
|
||||
case whole:
|
||||
if (Chunk_Inside(chunks, &ct))
|
||||
return chunks;
|
||||
case extended:
|
||||
for (c1 = chunks->part; c1; c1 = c1->next) {
|
||||
if (c1->type != type)
|
||||
continue;
|
||||
if (Chunk_Inside(c1, &ct))
|
||||
return c1;
|
||||
}
|
||||
return 0;
|
||||
case freebsd:
|
||||
for (c1 = chunks->part; c1; c1 = c1->next) {
|
||||
if (c1->type == type)
|
||||
if (Chunk_Inside(c1, &ct))
|
||||
return c1;
|
||||
if (c1->type != extended)
|
||||
continue;
|
||||
for (c2 = c1->part; c2; c2 = c2->next)
|
||||
if (c2->type == type && Chunk_Inside(c2, &ct))
|
||||
return c2;
|
||||
}
|
||||
return 0;
|
||||
#ifdef __powerpc__
|
||||
case apple:
|
||||
for (c1 = chunks->part; c1; c1 = c1->next) {
|
||||
if (c1->type == type)
|
||||
if (Chunk_Inside(c1, &ct))
|
||||
return c1;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
default:
|
||||
warn("Unsupported mother type in Find_Mother_Chunk");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Free_Chunk(struct chunk *c1)
|
||||
{
|
||||
if(c1 == NULL)
|
||||
return;
|
||||
if(c1->private_data && c1->private_free)
|
||||
(*c1->private_free)(c1->private_data);
|
||||
if(c1->part != NULL)
|
||||
Free_Chunk(c1->part);
|
||||
if(c1->next != NULL)
|
||||
Free_Chunk(c1->next);
|
||||
if (c1->name != NULL)
|
||||
free(c1->name);
|
||||
if (c1->sname != NULL)
|
||||
free(c1->sname);
|
||||
free(c1);
|
||||
}
|
||||
|
||||
struct chunk *
|
||||
Clone_Chunk(const struct chunk *c1)
|
||||
{
|
||||
struct chunk *c2;
|
||||
|
||||
if(!c1)
|
||||
return NULL;
|
||||
c2 = New_Chunk();
|
||||
if (c2 == NULL)
|
||||
return NULL;
|
||||
*c2 = *c1;
|
||||
if (c1->private_data && c1->private_clone)
|
||||
c2->private_data = c2->private_clone(c2->private_data);
|
||||
c2->name = strdup(c2->name);
|
||||
if (c2->sname != NULL)
|
||||
c2->sname = strdup(c2->sname);
|
||||
c2->next = Clone_Chunk(c2->next);
|
||||
c2->part = Clone_Chunk(c2->part);
|
||||
return c2;
|
||||
}
|
||||
|
||||
int
|
||||
Insert_Chunk(struct chunk *c2, daddr_t offset, daddr_t size, const char *name,
|
||||
chunk_e type, int subtype, u_long flags, const char *sname)
|
||||
{
|
||||
struct chunk *ct,*cs;
|
||||
|
||||
/* We will only insert into empty spaces */
|
||||
if (c2->type != unused)
|
||||
return __LINE__;
|
||||
|
||||
ct = New_Chunk();
|
||||
if (ct == NULL)
|
||||
return __LINE__;
|
||||
ct->disk = c2->disk;
|
||||
ct->offset = offset;
|
||||
ct->size = size;
|
||||
ct->end = offset + size - 1;
|
||||
ct->type = type;
|
||||
if (sname != NULL)
|
||||
ct->sname = strdup(sname);
|
||||
ct->name = strdup(name);
|
||||
ct->subtype = subtype;
|
||||
ct->flags = flags;
|
||||
|
||||
if (!Chunk_Inside(c2, ct)) {
|
||||
Free_Chunk(ct);
|
||||
return __LINE__;
|
||||
}
|
||||
|
||||
if ((type == freebsd || type == extended || type == apple)) {
|
||||
cs = New_Chunk();
|
||||
if (cs == NULL)
|
||||
return __LINE__;
|
||||
cs->disk = c2->disk;
|
||||
cs->offset = offset;
|
||||
cs->size = size;
|
||||
cs->end = offset + size - 1;
|
||||
cs->type = unused;
|
||||
if (sname != NULL)
|
||||
cs->sname = strdup(sname);
|
||||
cs->name = strdup("-");
|
||||
ct->part = cs;
|
||||
}
|
||||
|
||||
/* Make a new chunk for any trailing unused space */
|
||||
if (c2->end > ct->end) {
|
||||
cs = New_Chunk();
|
||||
if (cs == NULL)
|
||||
return __LINE__;
|
||||
*cs = *c2;
|
||||
cs->disk = c2->disk;
|
||||
cs->offset = ct->end + 1;
|
||||
cs->size = c2->end - ct->end;
|
||||
if (c2->sname != NULL)
|
||||
cs->sname = strdup(c2->sname);
|
||||
if (c2->name)
|
||||
cs->name = strdup(c2->name);
|
||||
c2->next = cs;
|
||||
c2->size -= c2->end - ct->end;
|
||||
c2->end = ct->end;
|
||||
}
|
||||
/* If no leading unused space just occupy the old chunk */
|
||||
if (c2->offset == ct->offset) {
|
||||
c2->sname = ct->sname;
|
||||
c2->name = ct->name;
|
||||
c2->type = ct->type;
|
||||
c2->part = ct->part;
|
||||
c2->subtype = ct->subtype;
|
||||
c2->flags = ct->flags;
|
||||
ct->sname = NULL;
|
||||
ct->name = NULL;
|
||||
ct->part = 0;
|
||||
Free_Chunk(ct);
|
||||
return 0;
|
||||
}
|
||||
/* else insert new chunk and adjust old one */
|
||||
c2->end = ct->offset - 1;
|
||||
c2->size -= ct->size;
|
||||
ct->next = c2->next;
|
||||
c2->next = ct;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Add_Chunk(struct disk *d, daddr_t offset, daddr_t size, const char *name,
|
||||
chunk_e type, int subtype, u_long flags, const char *sname)
|
||||
{
|
||||
struct chunk *c1, *c2, ct;
|
||||
daddr_t end = offset + size - 1;
|
||||
ct.offset = offset;
|
||||
ct.end = end;
|
||||
ct.size = size;
|
||||
|
||||
if (type == whole) {
|
||||
d->chunks = c1 = New_Chunk();
|
||||
if (c1 == NULL)
|
||||
return __LINE__;
|
||||
c2 = c1->part = New_Chunk();
|
||||
if (c2 == NULL)
|
||||
return __LINE__;
|
||||
c2->disk = c1->disk = d;
|
||||
c2->offset = c1->offset = offset;
|
||||
c2->size = c1->size = size;
|
||||
c2->end = c1->end = end;
|
||||
c1->sname = strdup(sname);
|
||||
c2->sname = strdup("-");
|
||||
c1->name = strdup(name);
|
||||
c2->name = strdup("-");
|
||||
c1->type = type;
|
||||
c2->type = unused;
|
||||
c1->flags = flags;
|
||||
c1->subtype = subtype;
|
||||
return 0;
|
||||
}
|
||||
|
||||
c1 = 0;
|
||||
/* PLATFORM POLICY BEGIN ------------------------------------- */
|
||||
switch(platform) {
|
||||
case p_i386:
|
||||
case p_amd64:
|
||||
switch (type) {
|
||||
case fat:
|
||||
case gpt:
|
||||
case mbr:
|
||||
case extended:
|
||||
case freebsd:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
|
||||
break;
|
||||
case part:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
|
||||
break;
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
case p_ia64:
|
||||
switch (type) {
|
||||
case freebsd:
|
||||
subtype = 0xa5;
|
||||
/* FALL THROUGH */
|
||||
case fat:
|
||||
case efi:
|
||||
case mbr:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
|
||||
break;
|
||||
case part:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end,
|
||||
freebsd);
|
||||
if (!c1)
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end,
|
||||
whole);
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
case p_pc98:
|
||||
switch (type) {
|
||||
case fat:
|
||||
case pc98:
|
||||
case freebsd:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
|
||||
break;
|
||||
case part:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
|
||||
break;
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
case p_sparc64:
|
||||
case p_alpha:
|
||||
switch (type) {
|
||||
case freebsd:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
|
||||
break;
|
||||
case part:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, freebsd);
|
||||
break;
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
case p_ppc:
|
||||
switch (type) {
|
||||
case apple:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, whole);
|
||||
break;
|
||||
case part:
|
||||
c1 = Find_Mother_Chunk(d->chunks, offset, end, apple);
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
/* PLATFORM POLICY END ---------------------------------------- */
|
||||
|
||||
if(!c1)
|
||||
return __LINE__;
|
||||
for(c2 = c1->part; c2; c2 = c2->next) {
|
||||
if (c2->type != unused)
|
||||
continue;
|
||||
if(!Chunk_Inside(c2, &ct))
|
||||
continue;
|
||||
/* PLATFORM POLICY BEGIN ------------------------------------- */
|
||||
if (platform == p_sparc64) {
|
||||
offset = Prev_Cyl_Aligned(d, offset);
|
||||
size = Next_Cyl_Aligned(d, size);
|
||||
} else if (platform == p_i386 || platform == p_pc98 ||
|
||||
platform == p_amd64) {
|
||||
if (type != freebsd)
|
||||
break;
|
||||
if (!(flags & CHUNK_ALIGN))
|
||||
break;
|
||||
if (offset == d->chunks->offset &&
|
||||
end == d->chunks->end)
|
||||
break;
|
||||
|
||||
/* Round down to prev cylinder */
|
||||
offset = Prev_Cyl_Aligned(d,offset);
|
||||
/* Stay inside the parent */
|
||||
if (offset < c2->offset)
|
||||
offset = c2->offset;
|
||||
/* Round up to next cylinder */
|
||||
offset = Next_Cyl_Aligned(d, offset);
|
||||
/* Keep one track clear in front of parent */
|
||||
if (offset == c1->offset)
|
||||
offset = Next_Track_Aligned(d, offset + 1);
|
||||
/* Work on the (end+1) */
|
||||
size += offset;
|
||||
/* Round up to cylinder */
|
||||
size = Next_Cyl_Aligned(d, size);
|
||||
/* Stay inside parent */
|
||||
if ((size-1) > c2->end)
|
||||
size = c2->end + 1;
|
||||
/* Round down to cylinder */
|
||||
size = Prev_Cyl_Aligned(d, size);
|
||||
|
||||
/* Convert back to size */
|
||||
size -= offset;
|
||||
}
|
||||
break;
|
||||
|
||||
/* PLATFORM POLICY END ------------------------------------- */
|
||||
}
|
||||
if (c2 == NULL)
|
||||
return (__LINE__);
|
||||
return Insert_Chunk(c2, offset, size, name, type, subtype, flags,
|
||||
sname);
|
||||
}
|
||||
|
||||
char *
|
||||
ShowChunkFlags(struct chunk *c)
|
||||
{
|
||||
static char ret[10];
|
||||
int i = 0;
|
||||
|
||||
if (c->flags & CHUNK_ACTIVE)
|
||||
ret[i++] = 'A';
|
||||
if (c->flags & CHUNK_ALIGN)
|
||||
ret[i++] = '=';
|
||||
if (c->flags & CHUNK_IS_ROOT)
|
||||
ret[i++] = 'R';
|
||||
ret[i++] = '\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
Print_Chunk(struct chunk *c1, int offset)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!c1)
|
||||
return;
|
||||
for (i = 0; i < offset - 2; i++)
|
||||
putchar(' ');
|
||||
for (; i < offset; i++)
|
||||
putchar('-');
|
||||
putchar('>');
|
||||
for (; i < 10; i++)
|
||||
putchar(' ');
|
||||
#ifndef __ia64__
|
||||
printf("%p ", c1);
|
||||
#endif
|
||||
printf("%8jd %8jd %8jd %-8s %-16s %-8s 0x%02x %s",
|
||||
(intmax_t)c1->offset, (intmax_t)c1->size, (intmax_t)c1->end,
|
||||
c1->name, c1->sname, chunk_name(c1->type), c1->subtype,
|
||||
ShowChunkFlags(c1));
|
||||
putchar('\n');
|
||||
Print_Chunk(c1->part, offset + 2);
|
||||
Print_Chunk(c1->next, offset);
|
||||
}
|
||||
|
||||
void
|
||||
Debug_Chunk(struct chunk *c1)
|
||||
{
|
||||
|
||||
Print_Chunk(c1, 2);
|
||||
}
|
||||
|
||||
int
|
||||
Delete_Chunk(struct disk *d, struct chunk *c)
|
||||
{
|
||||
|
||||
return (Delete_Chunk2(d, c, 0));
|
||||
}
|
||||
|
||||
int
|
||||
Delete_Chunk2(struct disk *d, struct chunk *c, int rflags)
|
||||
{
|
||||
struct chunk *c1, *c2, *c3;
|
||||
daddr_t offset = c->offset;
|
||||
|
||||
switch (c->type) {
|
||||
case whole:
|
||||
case unused:
|
||||
return 1;
|
||||
case extended:
|
||||
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, whole);
|
||||
break;
|
||||
case part:
|
||||
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, freebsd);
|
||||
#ifdef __ia64__
|
||||
if (c1 == NULL)
|
||||
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
|
||||
whole);
|
||||
#endif
|
||||
#ifdef __powerpc__
|
||||
if (c1 == NULL)
|
||||
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
|
||||
apple);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end, extended);
|
||||
if (c1 == NULL)
|
||||
c1 = Find_Mother_Chunk(d->chunks, c->offset, c->end,
|
||||
whole);
|
||||
break;
|
||||
}
|
||||
if (c1 == NULL)
|
||||
return 1;
|
||||
for (c2 = c1->part; c2; c2 = c2->next) {
|
||||
if (c2 == c) {
|
||||
c2->type = unused;
|
||||
c2->subtype = 0;
|
||||
c2->flags = 0;
|
||||
if (c2->sname != NULL)
|
||||
free(c2->sname);
|
||||
c2->sname = strdup("-");
|
||||
free(c2->name);
|
||||
c2->name = strdup("-");
|
||||
Free_Chunk(c2->part);
|
||||
c2->part =0;
|
||||
goto scan;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
scan:
|
||||
/*
|
||||
* Collapse multiple unused elements together, and attempt
|
||||
* to extend the previous chunk into the freed chunk.
|
||||
*
|
||||
* We only extend non-unused elements which are marked
|
||||
* for newfs (we can't extend working filesystems), and
|
||||
* only if we are called with DELCHUNK_RECOVER.
|
||||
*/
|
||||
for (c2 = c1->part; c2; c2 = c2->next) {
|
||||
if (c2->type != unused) {
|
||||
if (c2->offset + c2->size != offset ||
|
||||
(rflags & DELCHUNK_RECOVER) == 0 ||
|
||||
(c2->flags & CHUNK_NEWFS) == 0) {
|
||||
continue;
|
||||
}
|
||||
/* else extend into free area */
|
||||
}
|
||||
if (!c2->next)
|
||||
continue;
|
||||
if (c2->next->type != unused)
|
||||
continue;
|
||||
c3 = c2->next;
|
||||
c2->size += c3->size;
|
||||
c2->end = c3->end;
|
||||
c2->next = c3->next;
|
||||
c3->next = 0;
|
||||
Free_Chunk(c3);
|
||||
goto scan;
|
||||
}
|
||||
Fixup_Names(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
Collapse_Chunk(struct disk *d, struct chunk *c1)
|
||||
{
|
||||
struct chunk *c2, *c3;
|
||||
|
||||
if (c1->next && Collapse_Chunk(d, c1->next))
|
||||
return 1;
|
||||
|
||||
if (c1->type == unused && c1->next && c1->next->type == unused) {
|
||||
c3 = c1->next;
|
||||
c1->size += c3->size;
|
||||
c1->end = c3->end;
|
||||
c1->next = c3->next;
|
||||
c3->next = 0;
|
||||
Free_Chunk(c3);
|
||||
return 1;
|
||||
}
|
||||
c3 = c1->part;
|
||||
if (!c3)
|
||||
return 0;
|
||||
if (Collapse_Chunk(d, c1->part))
|
||||
return 1;
|
||||
|
||||
if (c1->type == whole)
|
||||
return 0;
|
||||
|
||||
if (c3->type == unused && c3->size == c1->size) {
|
||||
Delete_Chunk(d, c1);
|
||||
return 1;
|
||||
}
|
||||
if (c3->type == unused) {
|
||||
c2 = New_Chunk();
|
||||
if (c2 == NULL)
|
||||
barfout(1, "malloc failed");
|
||||
*c2 = *c1;
|
||||
c1->next = c2;
|
||||
c1->disk = d;
|
||||
c1->sname = strdup("-");
|
||||
c1->name = strdup("-");
|
||||
c1->part = 0;
|
||||
c1->type = unused;
|
||||
c1->flags = 0;
|
||||
c1->subtype = 0;
|
||||
c1->size = c3->size;
|
||||
c1->end = c3->end;
|
||||
c2->offset += c1->size;
|
||||
c2->size -= c1->size;
|
||||
c2->part = c3->next;
|
||||
c3->next = 0;
|
||||
Free_Chunk(c3);
|
||||
return 1;
|
||||
}
|
||||
for (c2 = c3; c2->next; c2 = c2->next)
|
||||
c3 = c2;
|
||||
if (c2 && c2->type == unused) {
|
||||
c3->next = 0;
|
||||
c2->next = c1->next;
|
||||
c1->next = c2;
|
||||
c1->size -= c2->size;
|
||||
c1->end -= c2->size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1,296 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/disklabel.h>
|
||||
#ifdef PC98
|
||||
#include <sys/diskpc98.h>
|
||||
#else
|
||||
#include <sys/diskmbr.h>
|
||||
#endif
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <grp.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
static int
|
||||
Fixup_FreeBSD_Names(struct chunk *c)
|
||||
{
|
||||
struct chunk *c1, *c3;
|
||||
uint j;
|
||||
|
||||
if (!strcmp(c->name, "X"))
|
||||
return 0;
|
||||
|
||||
/* reset all names to "X" */
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
c1->oname = c1->name;
|
||||
c1->name = malloc(12);
|
||||
if (!c1->name)
|
||||
return -1;
|
||||
strcpy(c1->name,"X");
|
||||
}
|
||||
|
||||
/* Allocate the first swap-partition we find */
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
if (c1->subtype != FS_SWAP)
|
||||
continue;
|
||||
sprintf(c1->name, "%s%c", c->name, SWAP_PART + 'a');
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allocate the first root-partition we find */
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
if (!(c1->flags & CHUNK_IS_ROOT))
|
||||
continue;
|
||||
sprintf(c1->name, "%s%c", c->name, 0 + 'a');
|
||||
break;
|
||||
}
|
||||
|
||||
/* Try to give them the same as they had before */
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
if (strcmp(c1->name, "X"))
|
||||
continue;
|
||||
for (c3 = c->part; c3 ; c3 = c3->next)
|
||||
if (c1 != c3 && !strcmp(c3->name, c1->oname))
|
||||
goto newname;
|
||||
strcpy(c1->name, c1->oname);
|
||||
newname:
|
||||
;
|
||||
}
|
||||
|
||||
/* Allocate the rest sequentially */
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
const char order[] = "defghab";
|
||||
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
if (strcmp("X", c1->name))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < strlen(order); j++) {
|
||||
sprintf(c1->name, "%s%c", c->name, order[j]);
|
||||
for (c3 = c->part; c3 ; c3 = c3->next)
|
||||
if (c1 != c3 && !strcmp(c3->name, c1->name))
|
||||
goto match;
|
||||
break;
|
||||
match:
|
||||
strcpy(c1->name, "X");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
free(c1->oname);
|
||||
c1->oname = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef PC98
|
||||
static int
|
||||
Fixup_Extended_Names(struct chunk *c)
|
||||
{
|
||||
struct chunk *c1;
|
||||
int j = 5;
|
||||
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
free(c1->name);
|
||||
c1->name = malloc(12);
|
||||
if (!c1->name)
|
||||
return -1;
|
||||
sprintf(c1->name, "%ss%d", c->disk->chunks->name, j++);
|
||||
if (c1->type == freebsd)
|
||||
if (Fixup_FreeBSD_Names(c1) != 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __powerpc__
|
||||
static int
|
||||
Fixup_Apple_Names(struct chunk *c)
|
||||
{
|
||||
struct chunk *c1;
|
||||
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
free(c1->name);
|
||||
c1->name = strdup(c->name);
|
||||
if (!c1->name)
|
||||
return (-1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
Fixup_Names(struct disk *d)
|
||||
{
|
||||
struct chunk *c1, *c2;
|
||||
#if defined(__i386__) || defined(__ia64__) || defined(__amd64__)
|
||||
struct chunk *c3;
|
||||
int j, max;
|
||||
#endif
|
||||
|
||||
c1 = d->chunks;
|
||||
for (c2 = c1->part; c2 ; c2 = c2->next) {
|
||||
if (c2->type == unused)
|
||||
continue;
|
||||
if (strcmp(c2->name, "X"))
|
||||
continue;
|
||||
#if defined(__i386__) || defined(__ia64__) || defined(__amd64__)
|
||||
c2->oname = malloc(12);
|
||||
if (!c2->oname)
|
||||
return -1;
|
||||
#ifdef __ia64__
|
||||
max = d->gpt_size;
|
||||
#else
|
||||
max = NDOSPART;
|
||||
#endif
|
||||
for (j = 1; j <= max; j++) {
|
||||
#ifdef __ia64__
|
||||
sprintf(c2->oname, "%s%c%d", c1->name,
|
||||
(c1->type == whole) ? 'p' : 's', j);
|
||||
#else
|
||||
sprintf(c2->oname, "%ss%d", c1->name, j);
|
||||
#endif
|
||||
for (c3 = c1->part; c3; c3 = c3->next)
|
||||
if (c3 != c2 && !strcmp(c3->name, c2->oname))
|
||||
goto match;
|
||||
free(c2->name);
|
||||
c2->name = c2->oname;
|
||||
c2->oname = 0;
|
||||
break;
|
||||
match:
|
||||
continue;
|
||||
}
|
||||
if (c2->oname)
|
||||
free(c2->oname);
|
||||
#else
|
||||
free(c2->name);
|
||||
c2->name = strdup(c1->name);
|
||||
#endif /*__i386__*/
|
||||
}
|
||||
for (c2 = c1->part; c2; c2 = c2->next) {
|
||||
if (c2->type == freebsd)
|
||||
Fixup_FreeBSD_Names(c2);
|
||||
#ifdef __powerpc__
|
||||
else if (c2->type == apple)
|
||||
Fixup_Apple_Names(c2);
|
||||
#endif
|
||||
#ifndef PC98
|
||||
else if (c2->type == extended)
|
||||
Fixup_Extended_Names(c2);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Create_Chunk(struct disk *d, daddr_t offset, daddr_t size, chunk_e type,
|
||||
int subtype, u_long flags, const char *sname)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifndef __ia64__
|
||||
if (!(flags & CHUNK_FORCE_ALL)) {
|
||||
daddr_t l;
|
||||
#ifdef PC98
|
||||
/* Never use the first cylinder */
|
||||
if (!offset) {
|
||||
offset += (d->bios_sect * d->bios_hd);
|
||||
size -= (d->bios_sect * d->bios_hd);
|
||||
}
|
||||
#else
|
||||
/* Never use the first track */
|
||||
if (!offset) {
|
||||
offset += d->bios_sect;
|
||||
size -= d->bios_sect;
|
||||
}
|
||||
#endif /* PC98 */
|
||||
|
||||
/* Always end on cylinder boundary */
|
||||
l = (offset + size) % (d->bios_sect * d->bios_hd);
|
||||
size -= l;
|
||||
}
|
||||
#endif
|
||||
|
||||
i = Add_Chunk(d, offset, size, "X", type, subtype, flags, sname);
|
||||
Fixup_Names(d);
|
||||
return i;
|
||||
}
|
||||
|
||||
struct chunk *
|
||||
Create_Chunk_DWIM(struct disk *d, struct chunk *parent, daddr_t size,
|
||||
chunk_e type, int subtype, u_long flags)
|
||||
{
|
||||
int i;
|
||||
struct chunk *c1;
|
||||
daddr_t offset;
|
||||
|
||||
if (!parent)
|
||||
parent = d->chunks;
|
||||
|
||||
if ((parent->type == freebsd && type == part && parent->part == NULL)
|
||||
|| (parent->type == apple && type == part && parent->part == NULL)) {
|
||||
c1 = New_Chunk();
|
||||
if (c1 == NULL)
|
||||
return (NULL);
|
||||
c1->disk = parent->disk;
|
||||
c1->offset = parent->offset;
|
||||
c1->size = parent->size;
|
||||
c1->end = parent->offset + parent->size - 1;
|
||||
c1->type = unused;
|
||||
if (parent->sname != NULL)
|
||||
c1->sname = strdup(parent->sname);
|
||||
c1->name = strdup("-");
|
||||
parent->part = c1;
|
||||
}
|
||||
|
||||
for (c1 = parent->part; c1; c1 = c1->next) {
|
||||
if (c1->type != unused)
|
||||
continue;
|
||||
if (c1->size < size)
|
||||
continue;
|
||||
offset = c1->offset;
|
||||
goto found;
|
||||
}
|
||||
return 0;
|
||||
found:
|
||||
i = Add_Chunk(d, offset, size, "X", type, subtype, flags, "-");
|
||||
if (i)
|
||||
return 0;
|
||||
Fixup_Names(d);
|
||||
for (c1 = parent->part; c1; c1 = c1->next)
|
||||
if (c1->offset == offset)
|
||||
return c1;
|
||||
/* barfout(1, "Serious internal trouble"); */
|
||||
return 0;
|
||||
}
|
@ -1,411 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <err.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/uuid.h>
|
||||
#include <sys/gpt.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <uuid.h>
|
||||
|
||||
const enum platform platform =
|
||||
#if defined (P_DEBUG)
|
||||
P_DEBUG
|
||||
#elif defined (PC98)
|
||||
p_pc98
|
||||
#elif defined(__i386__)
|
||||
p_i386
|
||||
#elif defined(__alpha__)
|
||||
p_alpha
|
||||
#elif defined(__sparc64__)
|
||||
p_sparc64
|
||||
#elif defined(__ia64__)
|
||||
p_ia64
|
||||
#elif defined(__ppc__)
|
||||
p_ppc
|
||||
#elif defined(__amd64__)
|
||||
p_amd64
|
||||
#elif defined(__arm__)
|
||||
p_arm
|
||||
#elif defined(__mips__)
|
||||
p_mips
|
||||
#else
|
||||
IHAVENOIDEA
|
||||
#endif
|
||||
;
|
||||
|
||||
const char *
|
||||
chunk_name(chunk_e type)
|
||||
{
|
||||
switch(type) {
|
||||
case unused: return ("unused");
|
||||
case mbr: return ("mbr");
|
||||
case part: return ("part");
|
||||
case gpt: return ("gpt");
|
||||
case pc98: return ("pc98");
|
||||
case sun: return ("sun");
|
||||
case freebsd: return ("freebsd");
|
||||
case fat: return ("fat");
|
||||
case spare: return ("spare");
|
||||
case efi: return ("efi");
|
||||
case apple: return ("apple");
|
||||
default: return ("??");
|
||||
}
|
||||
}
|
||||
|
||||
struct disk *
|
||||
Open_Disk(const char *name)
|
||||
{
|
||||
struct disk *d;
|
||||
char *conftxt;
|
||||
size_t txtsize;
|
||||
int error;
|
||||
|
||||
error = sysctlbyname("kern.geom.conftxt", NULL, &txtsize, NULL, 0);
|
||||
if (error) {
|
||||
warn("kern.geom.conftxt sysctl not available, giving up!");
|
||||
return (NULL);
|
||||
}
|
||||
conftxt = malloc(txtsize+1);
|
||||
if (conftxt == NULL) {
|
||||
warn("cannot malloc memory for conftxt");
|
||||
return (NULL);
|
||||
}
|
||||
error = sysctlbyname("kern.geom.conftxt", conftxt, &txtsize, NULL, 0);
|
||||
if (error) {
|
||||
warn("error reading kern.geom.conftxt from the system");
|
||||
free(conftxt);
|
||||
return (NULL);
|
||||
}
|
||||
conftxt[txtsize] = '\0'; /* in case kernel bug is still there */
|
||||
d = Int_Open_Disk(name, conftxt);
|
||||
free(conftxt);
|
||||
|
||||
return (d);
|
||||
}
|
||||
|
||||
void
|
||||
Debug_Disk(struct disk *d)
|
||||
{
|
||||
|
||||
printf("Debug_Disk(%s)", d->name);
|
||||
|
||||
#ifndef __ia64__
|
||||
printf(" bios_geom=%lu/%lu/%lu = %lu\n",
|
||||
d->bios_cyl, d->bios_hd, d->bios_sect,
|
||||
d->bios_cyl * d->bios_hd * d->bios_sect);
|
||||
#if defined(PC98)
|
||||
printf(" boot1=%p, boot2=%p, bootipl=%p, bootmenu=%p\n",
|
||||
d->boot1, d->boot2, d->bootipl, d->bootmenu);
|
||||
#elif defined(__i386__) || defined(__amd64__)
|
||||
printf(" boot1=%p, boot2=%p, bootmgr=%p\n",
|
||||
d->boot1, d->boot2, d->bootmgr);
|
||||
#elif defined(__alpha__)
|
||||
printf(" boot1=%p, bootmgr=%p\n",
|
||||
d->boot1, d->bootmgr);
|
||||
#else
|
||||
/* Should be: error "Debug_Disk: unknown arch"; */
|
||||
#endif
|
||||
#else /* __ia64__ */
|
||||
printf(" media size=%lu, sector size=%lu\n", d->media_size,
|
||||
d->sector_size);
|
||||
#endif
|
||||
|
||||
Debug_Chunk(d->chunks);
|
||||
}
|
||||
|
||||
void
|
||||
Free_Disk(struct disk *d)
|
||||
{
|
||||
if (d->chunks)
|
||||
Free_Chunk(d->chunks);
|
||||
if (d->name)
|
||||
free(d->name);
|
||||
#ifdef PC98
|
||||
if (d->bootipl)
|
||||
free(d->bootipl);
|
||||
if (d->bootmenu)
|
||||
free(d->bootmenu);
|
||||
#else
|
||||
#if !defined(__ia64__)
|
||||
if (d->bootmgr)
|
||||
free(d->bootmgr);
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(__ia64__)
|
||||
if (d->boot1)
|
||||
free(d->boot1);
|
||||
#endif
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
if (d->boot2)
|
||||
free(d->boot2);
|
||||
#endif
|
||||
free(d);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
Collapse_Disk(struct disk *d)
|
||||
{
|
||||
|
||||
while (Collapse_Chunk(d, d->chunks))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
qstrcmp(const void* a, const void* b)
|
||||
{
|
||||
const char *str1 = *(char* const*)a;
|
||||
const char *str2 = *(char* const*)b;
|
||||
|
||||
return strcmp(str1, str2);
|
||||
}
|
||||
|
||||
char **
|
||||
Disk_Names()
|
||||
{
|
||||
int disk_cnt;
|
||||
char **disks;
|
||||
int error;
|
||||
size_t listsize;
|
||||
char *disklist, *disk1, *disk2;
|
||||
|
||||
error = sysctlbyname("kern.disks", NULL, &listsize, NULL, 0);
|
||||
if (error) {
|
||||
warn("kern.disks sysctl not available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (listsize == 0)
|
||||
return (NULL);
|
||||
|
||||
disks = malloc(sizeof *disks * (1 + MAX_NO_DISKS));
|
||||
if (disks == NULL)
|
||||
return NULL;
|
||||
disk1 = disklist = (char *)malloc(listsize + 1);
|
||||
if (disklist == NULL) {
|
||||
free(disks);
|
||||
return NULL;
|
||||
}
|
||||
memset(disks,0,sizeof *disks * (1 + MAX_NO_DISKS));
|
||||
memset(disklist, 0, listsize + 1);
|
||||
error = sysctlbyname("kern.disks", disklist, &listsize, NULL, 0);
|
||||
if (error || disklist[0] == 0) {
|
||||
free(disklist);
|
||||
free(disks);
|
||||
return NULL;
|
||||
}
|
||||
for (disk_cnt = 0; disk_cnt < MAX_NO_DISKS; disk_cnt++) {
|
||||
disk2 = strsep(&disk1, " ");
|
||||
if (disk2 == NULL)
|
||||
break;
|
||||
disks[disk_cnt] = strdup(disk2);
|
||||
if (disks[disk_cnt] == NULL) {
|
||||
for (disk_cnt--; disk_cnt >= 0; disk_cnt--)
|
||||
free(disks[disk_cnt]);
|
||||
free(disklist);
|
||||
free(disks);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
qsort(disks, disk_cnt, sizeof(char*), qstrcmp);
|
||||
free(disklist);
|
||||
return disks;
|
||||
}
|
||||
|
||||
#ifdef PC98
|
||||
void
|
||||
Set_Boot_Mgr(struct disk *d, const u_char *bootipl, const size_t bootipl_size,
|
||||
const u_char *bootmenu, const size_t bootmenu_size)
|
||||
#else
|
||||
void
|
||||
Set_Boot_Mgr(struct disk *d, const u_char *b, const size_t s)
|
||||
#endif
|
||||
{
|
||||
#if !defined(__ia64__)
|
||||
#ifdef PC98
|
||||
if (d->sector_size == 0)
|
||||
return;
|
||||
if (bootipl_size % d->sector_size != 0)
|
||||
return;
|
||||
if (d->bootipl)
|
||||
free(d->bootipl);
|
||||
if (!bootipl) {
|
||||
d->bootipl = NULL;
|
||||
} else {
|
||||
d->bootipl_size = bootipl_size;
|
||||
d->bootipl = malloc(bootipl_size);
|
||||
if (!d->bootipl)
|
||||
return;
|
||||
memcpy(d->bootipl, bootipl, bootipl_size);
|
||||
}
|
||||
|
||||
if (bootmenu_size % d->sector_size != 0)
|
||||
return;
|
||||
if (d->bootmenu)
|
||||
free(d->bootmenu);
|
||||
if (!bootmenu) {
|
||||
d->bootmenu = NULL;
|
||||
} else {
|
||||
d->bootmenu_size = bootmenu_size;
|
||||
d->bootmenu = malloc(bootmenu_size);
|
||||
if (!d->bootmenu)
|
||||
return;
|
||||
memcpy(d->bootmenu, bootmenu, bootmenu_size);
|
||||
}
|
||||
#else
|
||||
if (d->sector_size == 0)
|
||||
return;
|
||||
if (s % d->sector_size != 0)
|
||||
return;
|
||||
if (d->bootmgr)
|
||||
free(d->bootmgr);
|
||||
if (!b) {
|
||||
d->bootmgr = NULL;
|
||||
} else {
|
||||
d->bootmgr_size = s;
|
||||
d->bootmgr = malloc(s);
|
||||
if (!d->bootmgr)
|
||||
return;
|
||||
memcpy(d->bootmgr, b, s);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
Set_Boot_Blocks(struct disk *d, const u_char *b1, const u_char *b2)
|
||||
{
|
||||
#if defined(__i386__) || defined(__amd64__)
|
||||
if (d->boot1)
|
||||
free(d->boot1);
|
||||
d->boot1 = malloc(512);
|
||||
if (!d->boot1)
|
||||
return -1;
|
||||
memcpy(d->boot1, b1, 512);
|
||||
if (d->boot2)
|
||||
free(d->boot2);
|
||||
d->boot2 = malloc(15 * 512);
|
||||
if (!d->boot2)
|
||||
return -1;
|
||||
memcpy(d->boot2, b2, 15 * 512);
|
||||
#elif defined(__alpha__)
|
||||
if (d->boot1)
|
||||
free(d->boot1);
|
||||
d->boot1 = malloc(15 * 512);
|
||||
if (!d->boot1)
|
||||
return -1;
|
||||
memcpy(d->boot1, b1, 15 * 512);
|
||||
#elif defined(__sparc64__)
|
||||
if (d->boot1 != NULL)
|
||||
free(d->boot1);
|
||||
d->boot1 = malloc(16 * 512);
|
||||
if (d->boot1 == NULL)
|
||||
return (-1);
|
||||
memcpy(d->boot1, b1, 16 * 512);
|
||||
#elif defined(__ia64__)
|
||||
/* nothing */
|
||||
#else
|
||||
/* Should be: #error "Set_Boot_Blocks: unknown arch"; */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
slice_type_name( int type, int subtype )
|
||||
{
|
||||
|
||||
switch (type) {
|
||||
case whole:
|
||||
return "whole";
|
||||
case mbr:
|
||||
switch (subtype) {
|
||||
case 1: return "fat (12-bit)";
|
||||
case 2: return "XENIX /";
|
||||
case 3: return "XENIX /usr";
|
||||
case 4: return "fat (16-bit,<=32Mb)";
|
||||
case 5: return "extended DOS";
|
||||
case 6: return "fat (16-bit,>32Mb)";
|
||||
case 7: return "NTFS/HPFS/QNX";
|
||||
case 8: return "AIX bootable";
|
||||
case 9: return "AIX data";
|
||||
case 10: return "OS/2 bootmgr";
|
||||
case 11: return "fat (32-bit)";
|
||||
case 12: return "fat (32-bit,LBA)";
|
||||
case 14: return "fat (16-bit,>32Mb,LBA)";
|
||||
case 15: return "extended DOS, LBA";
|
||||
case 18: return "Compaq Diagnostic";
|
||||
case 57: return "Plan 9";
|
||||
case 77: return "QNX 4.X";
|
||||
case 78: return "QNX 4.X 2nd part";
|
||||
case 79: return "QNX 4.X 3rd part";
|
||||
case 84: return "OnTrack diskmgr";
|
||||
case 100: return "Netware 2.x";
|
||||
case 101: return "Netware 3.x";
|
||||
case 115: return "SCO UnixWare";
|
||||
case 128: return "Minix 1.1";
|
||||
case 129: return "Minix 1.5";
|
||||
case 130: return "linux_swap";
|
||||
case 131: return "ext2fs";
|
||||
case 133: return "linux extended";
|
||||
case 166: return "OpenBSD FFS"; /* 0xA6 */
|
||||
case 168: return "Mac OS-X";
|
||||
case 169: return "NetBSD FFS"; /* 0xA9 */
|
||||
case 171: return "Mac OS-X Boot";
|
||||
case 182: return "OpenBSD"; /* dedicated */
|
||||
case 183: return "bsd/os";
|
||||
case 184: return "bsd/os swap";
|
||||
case 191: return "Solaris (new)";
|
||||
case 238: return "EFI GPT";
|
||||
case 239: return "EFI Sys. Part.";
|
||||
default: return "unknown";
|
||||
}
|
||||
case fat:
|
||||
return "fat";
|
||||
case freebsd:
|
||||
switch (subtype) {
|
||||
#ifdef PC98
|
||||
case 0xc494: return "freebsd";
|
||||
#else
|
||||
case 165: return "freebsd";
|
||||
#endif
|
||||
default: return "unknown";
|
||||
}
|
||||
case extended:
|
||||
return "extended";
|
||||
case part:
|
||||
return "part";
|
||||
case efi:
|
||||
return "efi";
|
||||
case unused:
|
||||
return "unused";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
@ -1,341 +0,0 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1996 Joerg Wunsch
|
||||
.\"
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This program is free software.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\" "
|
||||
.Dd January 30, 2006
|
||||
.Dt LIBDISK 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm Open_Disk ,
|
||||
.Nm Free_Disk ,
|
||||
.Nm Debug_Disk ,
|
||||
.Nm Set_Bios_Geom ,
|
||||
.Nm Delete_Chunk ,
|
||||
.Nm Collapse_Disk ,
|
||||
.Nm Collapse_Chunk ,
|
||||
.Nm Create_Chunk ,
|
||||
.Nm All_FreeBSD ,
|
||||
.Nm CheckRules ,
|
||||
.Nm Disk_Names ,
|
||||
.Nm Set_Boot_Mgr ,
|
||||
.Nm Set_Boot_Blocks ,
|
||||
.Nm Write_Disk ,
|
||||
.Nm Cyl_Aligned ,
|
||||
.Nm Next_Cyl_Aligned ,
|
||||
.Nm Prev_Cyl_Aligned ,
|
||||
.Nm Track_Aligned ,
|
||||
.Nm Next_Track_Aligned ,
|
||||
.Nm Prev_Track_Aligned ,
|
||||
.Nm Create_Chunk_DWIM ,
|
||||
.Nm MakeDev ,
|
||||
.Nm MakeDevDisk ,
|
||||
.Nm ShowChunkFlags ,
|
||||
.Nm chunk_name ,
|
||||
.Nm slice_type_name
|
||||
.Nd library interface to slice and partition labels
|
||||
.Sh LIBRARY
|
||||
.Lb libdisk
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In libdisk.h
|
||||
.Pp
|
||||
.Ft struct disk *
|
||||
.Fn Open_Disk "const char *devname"
|
||||
.Ft void
|
||||
.Fn Free_Disk "struct disk *disk"
|
||||
.Ft void
|
||||
.Fn Debug_Disk "struct disk *disk"
|
||||
.Ft void
|
||||
.Fn Set_Bios_Geom "struct disk *disk" "u_long cyl" "u_long heads" "u_long sects"
|
||||
.Ft int
|
||||
.Fn Delete_Chunk "struct disk *disk" "struct chunk *"
|
||||
.Ft void
|
||||
.Fn Collapse_Disk "struct disk *disk"
|
||||
.Ft int
|
||||
.Fn Collapse_Chunk "struct disk *disk" "struct chunk *chunk"
|
||||
.Ft int
|
||||
.Fn Create_Chunk "struct disk *disk" "daddr_t offset" "daddr_t size" "chunk_e type" "int subtype" "u_long flags" "const char *sname"
|
||||
.Ft void
|
||||
.Fn All_FreeBSD "struct disk *d" "int force_all"
|
||||
.Ft char *
|
||||
.Fn CheckRules "const struct disk *"
|
||||
.Ft char **
|
||||
.Fn Disk_Names "void"
|
||||
.Ft void
|
||||
.Fn Set_Boot_Mgr "struct disk *d" "const u_char *bootmgr" "const size_t bootmgr_size"
|
||||
.Ft int
|
||||
.Fn Set_Boot_Blocks "struct disk *d" "const u_char *boot1" "const u_char *boot2"
|
||||
.Ft int
|
||||
.Fn Write_Disk "const struct disk *d"
|
||||
.Ft int
|
||||
.Fn Cyl_Aligned "struct disk *d" "daddr_t offset"
|
||||
.Ft daddr_t
|
||||
.Fn Next_Cyl_Aligned "const struct disk *d" "daddr_t offset"
|
||||
.Ft daddr_t
|
||||
.Fn Prev_Cyl_Aligned "const struct disk *d" "daddr_t offset"
|
||||
.Ft int
|
||||
.Fn Track_Aligned "const struct disk *d" "daddr_t offset"
|
||||
.Ft daddr_t
|
||||
.Fn Next_Track_Aligned "const struct disk *d" "daddr_t offset"
|
||||
.Ft daddr_t
|
||||
.Fn Prev_Track_Aligned "const struct disk *d" "daddr_t offset"
|
||||
.Ft struct chunk *
|
||||
.Fn Create_Chunk_DWIM "struct disk *d" "struct chunk *parent" "daddr_t size" "chunk_e type" "int subtype" "u_long flags"
|
||||
.Ft int
|
||||
.Fn MakeDev "struct chunk *c" "const char *path"
|
||||
.Ft int
|
||||
.Fn MakeDevDisk "struct disk *d" "const char *path"
|
||||
.Ft char *
|
||||
.Fn ShowChunkFlags "struct chunk *c"
|
||||
.Ft const char *
|
||||
.Fn chunk_name "chunk_e type"
|
||||
.Ft const char *
|
||||
.Fn slice_type_name "int type" "int subtype"
|
||||
.Sh DESCRIPTION
|
||||
.Bf Sy
|
||||
.Nm libdisk
|
||||
is just for the use of
|
||||
.Xr sysinstall 8 .
|
||||
You should consider using
|
||||
.Xr libgeom 3
|
||||
instead.
|
||||
.Ef
|
||||
.Pp
|
||||
The
|
||||
.Nm libdisk
|
||||
library provides an interface to the low-level disk slice and partition labels.
|
||||
Most functions operate with arguments of the types
|
||||
.Ql struct disk ,
|
||||
or
|
||||
.Ql struct chunk .
|
||||
.Pp
|
||||
While both types are mostly opaque to the programmer, the internal
|
||||
structure is mentioned below for the sake of completeness.
|
||||
.Bd -literal -offset indent
|
||||
struct disk {
|
||||
char *name;
|
||||
u_long flags;
|
||||
u_long bios_cyl;
|
||||
u_long bios_hd;
|
||||
u_long bios_sect;
|
||||
u_char *bootmgr;
|
||||
u_char *boot1;
|
||||
u_char *boot2;
|
||||
struct chunk *chunks;
|
||||
u_long sector_size;
|
||||
};
|
||||
.Ed
|
||||
The only flag value by now is
|
||||
.Ql DISK_ON_TRACK ,
|
||||
meaning that this disk is handled by the On-Track Disk Manager.
|
||||
.Bd -literal -offset indent
|
||||
struct chunk {
|
||||
struct chunk *next;
|
||||
struct chunk *part;
|
||||
struct disk *disk;
|
||||
daddr_t offset;
|
||||
daddr_t size;
|
||||
daddr_t end;
|
||||
char *name;
|
||||
char *oname;
|
||||
chunk_e type;
|
||||
int subtype;
|
||||
u_long flags;
|
||||
void (*private_free)(void*);
|
||||
void *(*private_clone)(void*);
|
||||
void *private_data;
|
||||
};
|
||||
.Ed
|
||||
The
|
||||
.Ql type
|
||||
field can be one of the following values:
|
||||
.Ql whole, unknown, fat, freebsd, extended, part, unused .
|
||||
.Pp
|
||||
These are the valid
|
||||
.Ql flags
|
||||
values for a
|
||||
.Ql struct chunk .
|
||||
.Bl -tag -offset indent -width CHUNK_AUTO_SIZEXX
|
||||
.It CHUNK_ALIGN
|
||||
This chunk should be aligned.
|
||||
.It CHUNK_IS_ROOT
|
||||
This
|
||||
.Ql part
|
||||
is a rootfs, allocate partition
|
||||
.Sq a .
|
||||
.It CHUNK_ACTIVE
|
||||
This is the active slice in the MBR.
|
||||
.It CHUNK_FORCE_ALL
|
||||
Force a dedicated disk for
|
||||
.Fx ,
|
||||
bypassing all BIOS geometry considerations.
|
||||
.It CHUNK_AUTO_SIZE
|
||||
This chunk was auto-sized and can fill out any deleted following chunks.
|
||||
.It CHUNK_NEWFS
|
||||
newfs pending, used to enable auto-resizing on delete (along with AUTO_SIZE).
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ql private_data ,
|
||||
.Ql private_free ,
|
||||
and
|
||||
.Ql private_clone
|
||||
fields are for data private to the application, and the management
|
||||
thereof.
|
||||
If the functions are not provided, no storage management is
|
||||
done, cloning will just copy the pointer and freeing will just forget
|
||||
it.
|
||||
.Pp
|
||||
.Fn Open_Disk
|
||||
will open the named disk, and return populated tree.
|
||||
.Pp
|
||||
.Fn Free_Disk
|
||||
frees a tree made with
|
||||
.Fn Open_Disk
|
||||
or
|
||||
.Fn Clone_Disk .
|
||||
.Pp
|
||||
.Fn Debug_Disk
|
||||
prints the content of the tree to
|
||||
.Dv stdout .
|
||||
.Pp
|
||||
.Fn Set_Bios_Geom
|
||||
sets the geometry the bios uses.
|
||||
.Pp
|
||||
.Fn Delete_Chunk
|
||||
frees a chunk of disk_space.
|
||||
.Pp
|
||||
.Fn Collapse_Disk
|
||||
and
|
||||
.Fn Collapse_Chunk
|
||||
are experimental, do not use.
|
||||
.Pp
|
||||
.Fn Create_Chunk
|
||||
creates a chunk with the specified parameters.
|
||||
.Pp
|
||||
.Fn All_FreeBSD
|
||||
makes one
|
||||
.Fx
|
||||
chunk covering the entire disk; if
|
||||
.Ql force_all
|
||||
is set, bypass all BIOS geometry considerations.
|
||||
.Pp
|
||||
.Fn CheckRules
|
||||
returns
|
||||
.Ql char*
|
||||
to warnings about broken design rules in this disklayout.
|
||||
.Pp
|
||||
.Fn Disk_Names
|
||||
returns
|
||||
.Ql char**
|
||||
with all disk's names (wd0, wd1 ...).
|
||||
You must free each pointer, as
|
||||
well as the array by hand.
|
||||
.Pp
|
||||
.Fn Set_Boot_Mgr
|
||||
sets this boot-manager for use on this disk.
|
||||
Gets written when
|
||||
.Fn Write_Disk
|
||||
is called.
|
||||
.Pp
|
||||
.Fn Set_Boot_Blocks
|
||||
sets the boot-blocks for use on this disk.
|
||||
Gets written when
|
||||
.Fn Write_Disk
|
||||
is called.
|
||||
.Pp
|
||||
.Fn Write_Disk
|
||||
writes all the MBRs, disklabels, bootblocks and boot managers.
|
||||
.Pp
|
||||
.Fn Cyl_Aligned
|
||||
checks if
|
||||
.Ql offset
|
||||
is aligned on a cylinder according to the BIOS geometry.
|
||||
.Pp
|
||||
.Fn Next_Cyl_Aligned
|
||||
rounds
|
||||
.Ql offset
|
||||
up to next cylinder according to the BIOS geometry.
|
||||
.Pp
|
||||
.Fn Prev_Cyl_Aligned
|
||||
rounds
|
||||
.Ql offset
|
||||
down to previous cylinder according to the BIOS geometry.
|
||||
.Pp
|
||||
.Fn Track_Aligned
|
||||
checks if
|
||||
.Ql offset
|
||||
is aligned on a track according to the BIOS geometry.
|
||||
.Pp
|
||||
.Fn Next_Track_Aligned
|
||||
rounds
|
||||
.Ql offset
|
||||
up to next track according to the BIOS geometry.
|
||||
.Pp
|
||||
.Fn Prev_Track_Aligned
|
||||
rounds
|
||||
.Ql offset
|
||||
up to previous track according to the BIOS geometry.
|
||||
.Pp
|
||||
.Fn Create_Chunk_DWIM
|
||||
creates a partition inside the given parent of the given size, and
|
||||
returns a pointer to it.
|
||||
The first unused chunk big enough is used.
|
||||
.Pp
|
||||
.Fn MakeDev
|
||||
makes the device nodes for this chunk.
|
||||
.Pp
|
||||
.Fn MakeDevDisk
|
||||
makes the device nodes for all chunks on this disk.
|
||||
.Pp
|
||||
.Fn ShowChunkFlags
|
||||
returns a string to show flags.
|
||||
.Pp
|
||||
The
|
||||
.Fn chunk_name
|
||||
function takes the enumerated chunk type and returns its name.
|
||||
.Fn chunk_name
|
||||
replaces the old external array
|
||||
.Va chunk_n .
|
||||
.Pp
|
||||
.Fn slice_type_name
|
||||
returns the name strings associated with the specified
|
||||
.Ql type .
|
||||
.Ql subtype .
|
||||
If
|
||||
.Fn slice_type_name
|
||||
returns "unknown" for slices it is not familiar with.
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm libdisk
|
||||
library was written by
|
||||
.An Poul-Henning Kamp .
|
||||
.Pp
|
||||
This manual page was written by
|
||||
.An J\(:org Wunsch .
|
@ -1,368 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LIBDISK_H_
|
||||
#define _LIBDISK_H_
|
||||
|
||||
/* #define DEBUG 1 */
|
||||
/* You can define a particular architecture here if you are debugging. */
|
||||
/* #define P_DEBUG p_sparc64 */
|
||||
|
||||
#define MAX_NO_DISKS 32
|
||||
/* Max # of disks Disk_Names() will return */
|
||||
|
||||
#define MAX_SEC_SIZE 2048 /* maximum sector size that is supported */
|
||||
#define MIN_SEC_SIZE 512 /* the sector size to end sensing at */
|
||||
|
||||
enum platform {
|
||||
p_any, /* for debugging ! */
|
||||
p_alpha,
|
||||
p_i386,
|
||||
p_pc98,
|
||||
p_sparc64,
|
||||
p_ia64,
|
||||
p_ppc,
|
||||
p_amd64,
|
||||
p_arm,
|
||||
p_mips
|
||||
};
|
||||
extern const enum platform platform;
|
||||
|
||||
typedef enum {
|
||||
whole,
|
||||
unknown,
|
||||
|
||||
sun,
|
||||
pc98,
|
||||
mbr,
|
||||
gpt,
|
||||
|
||||
efi,
|
||||
fat,
|
||||
freebsd,
|
||||
extended,
|
||||
part,
|
||||
spare,
|
||||
unused,
|
||||
|
||||
apple
|
||||
} chunk_e;
|
||||
|
||||
__BEGIN_DECLS
|
||||
#ifndef __ia64__
|
||||
struct disk {
|
||||
char *name;
|
||||
u_long bios_cyl;
|
||||
u_long bios_hd;
|
||||
u_long bios_sect;
|
||||
#ifdef PC98
|
||||
u_char *bootipl;
|
||||
size_t bootipl_size;
|
||||
u_char *bootmenu;
|
||||
size_t bootmenu_size;
|
||||
#else
|
||||
u_char *bootmgr;
|
||||
size_t bootmgr_size;
|
||||
#endif
|
||||
u_char *boot1;
|
||||
#if defined(__i386__) || defined(__amd64__) /* the i386 needs extra help... */
|
||||
u_char *boot2;
|
||||
#endif
|
||||
struct chunk *chunks;
|
||||
u_long sector_size; /* media sector size, a power of 2 */
|
||||
};
|
||||
#else /* !__ia64__ */
|
||||
struct disk {
|
||||
char *name;
|
||||
struct chunk *chunks;
|
||||
u_long media_size;
|
||||
u_long sector_size;
|
||||
u_long lba_start;
|
||||
u_long lba_end;
|
||||
u_int gpt_size; /* Number of entries */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct chunk {
|
||||
struct chunk *next;
|
||||
struct chunk *part;
|
||||
struct disk *disk;
|
||||
daddr_t offset;
|
||||
daddr_t size;
|
||||
daddr_t end;
|
||||
char *sname; /* PC98 field */
|
||||
char *name;
|
||||
char *oname;
|
||||
/* Used during Fixup_Names() to avoid renaming more than
|
||||
* absolutely needed.
|
||||
*/
|
||||
chunk_e type;
|
||||
int subtype;
|
||||
u_long flags;
|
||||
void (*private_free)(void*);
|
||||
void *(*private_clone)(void*);
|
||||
void *private_data;
|
||||
/* For data private to the application, and the management
|
||||
* thereof. If the functions are not provided, no storage
|
||||
* management is done, Cloning will just copy the pointer
|
||||
* and freeing will just forget it.
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
* flags:
|
||||
*
|
||||
* ALIGN - This chunk should be aligned
|
||||
* IS_ROOT - This 'part' is a rootfs, allocate 'a'
|
||||
* ACTIVE - This is the active slice in the MBR
|
||||
* FORCE_ALL - Force a dedicated disk for FreeBSD, bypassing
|
||||
* all BIOS geometry considerations
|
||||
* AUTO_SIZE - This chunk was auto-sized and can fill-out a
|
||||
* following chunk if the following chunk is deleted.
|
||||
* NEWFS - newfs pending, used to enable auto-resizing on
|
||||
* delete (along with AUTO_SIZE).
|
||||
*/
|
||||
|
||||
#define CHUNK_ALIGN 0x0008
|
||||
#define CHUNK_IS_ROOT 0x0010
|
||||
#define CHUNK_ACTIVE 0x0020
|
||||
#define CHUNK_FORCE_ALL 0x0040
|
||||
#define CHUNK_AUTO_SIZE 0x0080
|
||||
#define CHUNK_NEWFS 0x0100
|
||||
#define CHUNK_HAS_INDEX 0x0200
|
||||
#define CHUNK_ITOF(i) ((i & 0xFFFF) << 16)
|
||||
#define CHUNK_FTOI(f) ((f >> 16) & 0xFFFF)
|
||||
|
||||
#define DELCHUNK_NORMAL 0x0000
|
||||
#define DELCHUNK_RECOVER 0x0001
|
||||
|
||||
const char *chunk_name(chunk_e);
|
||||
|
||||
const char *
|
||||
slice_type_name(int, int);
|
||||
/* "chunk_n" for subtypes too */
|
||||
|
||||
struct disk *
|
||||
Open_Disk(const char *);
|
||||
/* Will open the named disk, and return populated tree. */
|
||||
|
||||
void
|
||||
Free_Disk(struct disk *);
|
||||
/* Free a tree made with Open_Disk() or Clone_Disk() */
|
||||
|
||||
void
|
||||
Debug_Disk(struct disk *);
|
||||
/* Print the content of the tree to stdout */
|
||||
|
||||
void
|
||||
Set_Bios_Geom(struct disk *, u_long, u_long, u_long);
|
||||
/* Set the geometry the bios uses. */
|
||||
|
||||
void
|
||||
Sanitize_Bios_Geom(struct disk *);
|
||||
/* Set the bios geometry to something sane */
|
||||
|
||||
int
|
||||
Insert_Chunk(struct chunk *, daddr_t, daddr_t, const char *, chunk_e, int,
|
||||
u_long, const char *);
|
||||
|
||||
int
|
||||
Delete_Chunk2(struct disk *, struct chunk *, int);
|
||||
/* Free a chunk of disk_space modified by the passed flags. */
|
||||
|
||||
int
|
||||
Delete_Chunk(struct disk *, struct chunk *);
|
||||
/* Free a chunk of disk_space */
|
||||
|
||||
void
|
||||
Collapse_Disk(struct disk *);
|
||||
/* Experimental, do not use. */
|
||||
|
||||
int
|
||||
Collapse_Chunk(struct disk *, struct chunk *);
|
||||
/* Experimental, do not use. */
|
||||
|
||||
int
|
||||
Create_Chunk(struct disk *, daddr_t, daddr_t, chunk_e, int, u_long, const char *);
|
||||
/* Create a chunk with the specified paramters */
|
||||
|
||||
void
|
||||
All_FreeBSD(struct disk *, int);
|
||||
/*
|
||||
* Make one FreeBSD chunk covering the entire disk;
|
||||
* if force_all is set, bypass all BIOS geometry
|
||||
* considerations.
|
||||
*/
|
||||
|
||||
char *
|
||||
CheckRules(const struct disk *);
|
||||
/* Return char* to warnings about broken design rules in this disklayout */
|
||||
|
||||
char **
|
||||
Disk_Names(void);
|
||||
/*
|
||||
* Return char** with all disk's names (wd0, wd1 ...). You must free
|
||||
* each pointer, as well as the array by hand
|
||||
*/
|
||||
|
||||
#ifdef PC98
|
||||
void
|
||||
Set_Boot_Mgr(struct disk *, const u_char *, const size_t, const u_char *,
|
||||
const size_t);
|
||||
#else
|
||||
void
|
||||
Set_Boot_Mgr(struct disk *, const u_char *, const size_t);
|
||||
#endif
|
||||
/*
|
||||
* Use this boot-manager on this disk. Gets written when Write_Disk()
|
||||
* is called
|
||||
*/
|
||||
|
||||
int
|
||||
Set_Boot_Blocks(struct disk *, const u_char *, const u_char *);
|
||||
/*
|
||||
* Use these boot-blocks on this disk. Gets written when Write_Disk()
|
||||
* is called. Returns nonzero upon failure.
|
||||
*/
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *);
|
||||
/* Write all the MBRs, disklabels, bootblocks and boot managers */
|
||||
|
||||
daddr_t
|
||||
Next_Cyl_Aligned(const struct disk *, daddr_t);
|
||||
/* Round offset up to next cylinder according to the bios-geometry */
|
||||
|
||||
daddr_t
|
||||
Prev_Cyl_Aligned(const struct disk *, daddr_t);
|
||||
/* Round offset down to previous cylinder according to the bios-geometry */
|
||||
|
||||
int
|
||||
Track_Aligned(const struct disk *, daddr_t);
|
||||
/* Check if offset is aligned on a track according to the bios geometry */
|
||||
|
||||
daddr_t
|
||||
Next_Track_Aligned(const struct disk *, daddr_t);
|
||||
/* Round offset up to next track according to the bios-geometry */
|
||||
|
||||
daddr_t
|
||||
Prev_Track_Aligned(const struct disk *, daddr_t);
|
||||
/* Check if offset is aligned on a track according to the bios geometry */
|
||||
|
||||
struct chunk *
|
||||
Create_Chunk_DWIM(struct disk *, struct chunk *, daddr_t, chunk_e, int,
|
||||
u_long);
|
||||
/*
|
||||
* This one creates a partition inside the given parent of the given
|
||||
* size, and returns a pointer to it. The first unused chunk big
|
||||
* enough is used.
|
||||
*/
|
||||
|
||||
char *
|
||||
ShowChunkFlags(struct chunk *);
|
||||
/* Return string to show flags. */
|
||||
|
||||
/*
|
||||
* Implementation details >>> DO NOT USE <<<
|
||||
*/
|
||||
|
||||
struct disklabel;
|
||||
|
||||
void Fill_Disklabel(struct disklabel *, const struct disk *,
|
||||
const struct chunk *);
|
||||
void Debug_Chunk(struct chunk *);
|
||||
struct chunk *New_Chunk(void);
|
||||
void Free_Chunk(struct chunk *);
|
||||
struct chunk *Clone_Chunk(const struct chunk *);
|
||||
int Add_Chunk(struct disk *, daddr_t, daddr_t, const char *, chunk_e, int,
|
||||
u_long, const char *);
|
||||
void *read_block(int, daddr_t, u_long);
|
||||
int write_block(int, daddr_t, const void *, u_long);
|
||||
struct disklabel *read_disklabel(int, daddr_t, u_long);
|
||||
struct disk *Int_Open_Disk(const char *, char *);
|
||||
int Fixup_Names(struct disk *);
|
||||
int MakeDevChunk(const struct chunk *, const char *);
|
||||
__END_DECLS
|
||||
|
||||
/* TODO
|
||||
*
|
||||
* Need an error string mechanism from the functions instead of warn()
|
||||
*
|
||||
* Make sure only FreeBSD start at offset==0
|
||||
*
|
||||
* 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().
|
||||
*
|
||||
* Make Is_Unchanged(struct disk *d1, struct chunk *c1)
|
||||
*
|
||||
* don't rename slices unless we have to
|
||||
*
|
||||
*Sample output from tst01:
|
||||
*
|
||||
* Debug_Disk(wd0) flags=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
|
||||
* >>>>>> 0x3d2c0 960120 63 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:
|
||||
* <struct chunk> --> part
|
||||
* |
|
||||
* v next
|
||||
*
|
||||
* <wd0> --> <wd0s1> --> <wd0s1a>
|
||||
* | |
|
||||
* | v
|
||||
* | <wd0s1b>
|
||||
* | |
|
||||
* | v
|
||||
* | <wd0s1e>
|
||||
* | |
|
||||
* | v
|
||||
* | <wd0s1f>
|
||||
* |
|
||||
* v
|
||||
* <wd0s2> --> <unused>
|
||||
* | |
|
||||
* | v
|
||||
* | <wd0s5>
|
||||
* |
|
||||
* v
|
||||
* <wd0s3>
|
||||
* |
|
||||
* v
|
||||
* <wd0s4> --> <wd0s4a>
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#endif /* _LIBDISK_H_ */
|
@ -1,311 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <err.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/gpt.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINT(x) warn x
|
||||
#define DPRINTX(x) warnx x
|
||||
#else
|
||||
#define DPRINT(x)
|
||||
#define DPRINTX(x)
|
||||
#endif
|
||||
|
||||
struct disk *
|
||||
Int_Open_Disk(const char *name, char *conftxt)
|
||||
{
|
||||
struct disk *d;
|
||||
int i, line = 1;
|
||||
char *p, *q, *r, *a, *b, *n, *t, *sn;
|
||||
daddr_t o, len, off;
|
||||
u_int l, s, ty, sc, hd, alt;
|
||||
daddr_t lo[10];
|
||||
|
||||
/*
|
||||
* Locate the disk (by name) in our sysctl output
|
||||
*/
|
||||
for (p = conftxt; p != NULL && *p; p = strchr(p, '\n'), line++) {
|
||||
if (*p == '\n')
|
||||
p++;
|
||||
a = strsep(&p, " ");
|
||||
/* Skip anything not with index 0 */
|
||||
if (strcmp(a, "0"))
|
||||
continue;
|
||||
|
||||
/* Skip anything not a disk */
|
||||
a = strsep(&p, " ");
|
||||
if (strcmp(a, "DISK"))
|
||||
continue;
|
||||
|
||||
a = strsep(&p, " ");
|
||||
if (strcmp(a, name))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
q = strchr(p, '\n');
|
||||
if (q != NULL)
|
||||
*q++ = '\0';
|
||||
|
||||
d = (struct disk *)calloc(sizeof *d, 1);
|
||||
if(d == NULL)
|
||||
return NULL;
|
||||
|
||||
d->name = strdup(name);
|
||||
|
||||
a = strsep(&p, " "); /* length in bytes */
|
||||
len = strtoimax(a, &r, 0);
|
||||
if (*r) {
|
||||
printf("libdisk: Int_Open_Disk(%s): can't parse length in line %d (r='%s')\n",
|
||||
name, line, r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
a = strsep(&p, " "); /* sectorsize */
|
||||
s = strtoul(a, &r, 0);
|
||||
if (*r) {
|
||||
printf("libdisk: Int_Open_Disk(%s): can't parse sector size in line %d (r='%s')\n",
|
||||
name, line, r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (s == 0)
|
||||
return (NULL);
|
||||
d->sector_size = s;
|
||||
len /= s; /* media size in number of sectors. */
|
||||
|
||||
if (Add_Chunk(d, 0, len, name, whole, 0, 0, "-")) {
|
||||
DPRINT(("Failed to add 'whole' chunk"));
|
||||
}
|
||||
|
||||
/* Try to parse any fields after the sector size in the DISK entry line */
|
||||
for (;;) {
|
||||
a = strsep(&p, " ");
|
||||
if (a == NULL)
|
||||
break;
|
||||
b = strsep(&p, " ");
|
||||
o = strtoimax(b, &r, 0);
|
||||
if (*r) {
|
||||
printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
|
||||
name, a, line, r);
|
||||
return NULL;
|
||||
}
|
||||
if (!strcmp(a, "hd"))
|
||||
d->bios_hd = o;
|
||||
else if (!strcmp(a, "sc"))
|
||||
d->bios_sect = o;
|
||||
else
|
||||
printf("libdisk: Int_Open_Disk(%s): unknown parameter '%s' with value '%s' in line %d, ignored\n",
|
||||
name, a, b, line);
|
||||
}
|
||||
|
||||
/* Sanitize the parameters. */
|
||||
Sanitize_Bios_Geom(d);
|
||||
|
||||
/*
|
||||
* Calculate the number of cylinders this disk must have. If we have
|
||||
* an obvious insanity, we set the number of cylinders to zero.
|
||||
*/
|
||||
o = d->bios_hd * d->bios_sect;
|
||||
d->bios_cyl = (o != 0) ? len / o : 0;
|
||||
|
||||
p = q; line++; /* p is now the start of the line _after_ the DISK entry */
|
||||
lo[0] = 0;
|
||||
|
||||
for (; p != NULL && *p; p = q, line++) {
|
||||
sn = NULL;
|
||||
q = strchr(p, '\n');
|
||||
if (q != NULL)
|
||||
*q++ = '\0';
|
||||
a = strsep(&p, " "); /* Index */
|
||||
/*
|
||||
* If we find index 0 again, this means we've encountered another disk, so it's safe to assume this disk
|
||||
* has been processed.
|
||||
*/
|
||||
if (!strcmp(a, "0"))
|
||||
break;
|
||||
l = strtoimax(a, &r, 0);
|
||||
if (*r) {
|
||||
printf("libdisk: Int_Open_Disk(%s): can't parse depth '%s' in line %d (r='%s')\n",
|
||||
name, a, line, r);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
t = strsep(&p, " "); /* Type {SUN, BSD, MBR, PC98, GPT} */
|
||||
n = strsep(&p, " "); /* name */
|
||||
a = strsep(&p, " "); /* len */
|
||||
len = strtoimax(a, &r, 0);
|
||||
if (*r) {
|
||||
printf("libdisk: Int_Open_Disk(%s): can't parse length '%s' in line %d (r='%s')\n",
|
||||
name, a, line, r);
|
||||
continue;
|
||||
}
|
||||
a = strsep(&p, " "); /* secsize */
|
||||
s = strtoimax(a, &r, 0);
|
||||
if (*r) {
|
||||
printf("libdisk: Int_Open_Disk(%s): can't parse sector size '%s' in line %d (r='%s')\n",
|
||||
name, a, line, r);
|
||||
continue;
|
||||
}
|
||||
for (;;) {
|
||||
a = strsep(&p, " ");
|
||||
if (a == NULL)
|
||||
break;
|
||||
/* XXX: Slice name may include a space. */
|
||||
if (!strcmp(a, "sn")) {
|
||||
sn = p;
|
||||
break;
|
||||
}
|
||||
b = strsep(&p, " ");
|
||||
o = strtoimax(b, &r, 0);
|
||||
/* APPLE have ty as a string */
|
||||
if ((*r) && strcmp(t, "APPLE") &&
|
||||
strcmp(t, "GPT") && strcmp(t, "PART")) {
|
||||
printf("libdisk: Int_Open_Disk(%s): can't parse parameter '%s' in line %d (r='%s')\n",
|
||||
name, a, line, r);
|
||||
break;
|
||||
}
|
||||
if (!strcmp(a, "o"))
|
||||
off = o;
|
||||
else if (!strcmp(a, "i"))
|
||||
i = (!strcmp(t, "PART")) ? o - 1 : o;
|
||||
else if (!strcmp(a, "ty"))
|
||||
ty = o;
|
||||
else if (!strcmp(a, "sc"))
|
||||
sc = o;
|
||||
else if (!strcmp(a, "hd"))
|
||||
hd = o;
|
||||
else if (!strcmp(a, "alt"))
|
||||
alt = o;
|
||||
else if (!strcmp(a, "xs"))
|
||||
t = b;
|
||||
else if (!strcmp(a, "xt")) {
|
||||
if (*r)
|
||||
sn = b;
|
||||
else
|
||||
ty = o;
|
||||
}
|
||||
}
|
||||
|
||||
/* PLATFORM POLICY BEGIN ----------------------------------- */
|
||||
if (platform == p_sparc64 && !strcmp(t, "SUN") && i == 2)
|
||||
continue;
|
||||
if (platform == p_sparc64 && !strcmp(t, "SUN") &&
|
||||
d->chunks->part->part == NULL) {
|
||||
d->bios_hd = hd;
|
||||
d->bios_sect = sc;
|
||||
o = d->chunks->size / (hd * sc);
|
||||
o *= (hd * sc);
|
||||
o -= alt * hd * sc;
|
||||
if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) {
|
||||
DPRINT(("Failed to add 'freebsd' chunk"));
|
||||
}
|
||||
}
|
||||
if (platform == p_alpha && !strcmp(t, "BSD") &&
|
||||
d->chunks->part->part == NULL) {
|
||||
if (Add_Chunk(d, 0, d->chunks->size, name, freebsd,
|
||||
0, 0, "-")) {
|
||||
DPRINT(("Failed to add 'freebsd' chunk"));
|
||||
}
|
||||
}
|
||||
if (!strcmp(t, "BSD") && i == RAW_PART)
|
||||
continue;
|
||||
/* PLATFORM POLICY END ------------------------------------- */
|
||||
|
||||
off /= s;
|
||||
len /= s;
|
||||
off += lo[l - 1];
|
||||
lo[l] = off;
|
||||
if (!strcmp(t, "SUN"))
|
||||
i = Add_Chunk(d, off, len, n, part, 0, 0, 0);
|
||||
else if (!strncmp(t, "MBR", 3)) {
|
||||
switch (ty) {
|
||||
case 0xa5:
|
||||
i = Add_Chunk(d, off, len, n, freebsd, ty, 0, 0);
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x04:
|
||||
case 0x06:
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
case 0x0e:
|
||||
i = Add_Chunk(d, off, len, n, fat, ty, 0, 0);
|
||||
break;
|
||||
case 0xef: /* EFI */
|
||||
i = Add_Chunk(d, off, len, n, efi, ty, 0, 0);
|
||||
break;
|
||||
default:
|
||||
i = Add_Chunk(d, off, len, n, mbr, ty, 0, 0);
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(t, "BSD"))
|
||||
i = Add_Chunk(d, off, len, n, part, ty, 0, 0);
|
||||
else if (!strcmp(t, "PC98")) {
|
||||
switch (ty & 0x7f) {
|
||||
case 0x14:
|
||||
i = Add_Chunk(d, off, len, n, freebsd, ty, 0,
|
||||
sn);
|
||||
break;
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
case 0x23:
|
||||
case 0x24:
|
||||
i = Add_Chunk(d, off, len, n, fat, ty, 0, sn);
|
||||
break;
|
||||
default:
|
||||
i = Add_Chunk(d, off, len, n, pc98, ty, 0, sn);
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(t, "GPT"))
|
||||
i = Add_Chunk(d, off, len, n, gpt, 0, 0, b);
|
||||
else if (!strcmp(t, "APPLE"))
|
||||
i = Add_Chunk(d, off, len, n, apple, 0, 0, sn);
|
||||
else
|
||||
; /* Ignore unknown classes. */
|
||||
}
|
||||
/* PLATFORM POLICY BEGIN ------------------------------------- */
|
||||
/* We have a chance to do things on a blank disk here */
|
||||
if (platform == p_sparc64 && d->chunks->part->part == NULL) {
|
||||
hd = d->bios_hd;
|
||||
sc = d->bios_sect;
|
||||
o = d->chunks->size / (hd * sc);
|
||||
o *= (hd * sc);
|
||||
o -= 2 * hd * sc;
|
||||
if (Add_Chunk(d, 0, o, name, freebsd, 0, 0, "-")) {
|
||||
DPRINT(("Failed to add 'freebsd' chunk"));
|
||||
}
|
||||
}
|
||||
/* PLATFORM POLICY END --------------------------------------- */
|
||||
|
||||
return (d);
|
||||
i = 0;
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskmbr.h>
|
||||
#include <sys/gpt.h>
|
||||
#include <sys/uuid.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libdisk.h"
|
||||
|
||||
static struct disk *
|
||||
parse_disk(char *conftxt, const char *name)
|
||||
{
|
||||
char devname[64];
|
||||
struct disk *disk;
|
||||
struct dos_partition *part;
|
||||
struct gpt_hdr *gpt;
|
||||
char *buffer, *p, *q;
|
||||
int fd, i;
|
||||
|
||||
disk = (struct disk *)calloc(sizeof *disk, 1);
|
||||
if (disk == NULL)
|
||||
return (NULL);
|
||||
|
||||
disk->name = strdup(name);
|
||||
p = strsep(&conftxt, " "); /* media size */
|
||||
disk->media_size = strtoimax(p, &q, 0);
|
||||
if (*q)
|
||||
goto fail;
|
||||
|
||||
p = strsep(&conftxt, " "); /* sector size */
|
||||
disk->sector_size = strtoul(p, &q, 0);
|
||||
if (*q)
|
||||
goto fail;
|
||||
|
||||
if (disk->sector_size == 0)
|
||||
disk->sector_size = 512;
|
||||
|
||||
if (disk->media_size % disk->sector_size)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* We need to read the disk to get GPT specific information.
|
||||
*/
|
||||
|
||||
snprintf(devname, sizeof(devname), "%s%s", _PATH_DEV, name);
|
||||
fd = open(devname, O_RDONLY);
|
||||
if (fd == -1)
|
||||
goto fail;
|
||||
buffer = malloc(2 * disk->sector_size);
|
||||
if (buffer == NULL) {
|
||||
close (fd);
|
||||
goto fail;
|
||||
}
|
||||
if (read(fd, buffer, 2 * disk->sector_size) == -1) {
|
||||
free(buffer);
|
||||
close(fd);
|
||||
goto fail;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
gpt = (struct gpt_hdr *)(buffer + disk->sector_size);
|
||||
if (memcmp(gpt->hdr_sig, GPT_HDR_SIG, sizeof(gpt->hdr_sig))) {
|
||||
/*
|
||||
* No GPT present. Check if the MBR is empty (if present)
|
||||
* or is a PMBR before declaring this disk as empty. If
|
||||
* the MBR isn't empty, bail out. Let's not risk nuking a
|
||||
* disk.
|
||||
*/
|
||||
if (*(u_short *)(buffer + DOSMAGICOFFSET) == DOSMAGIC) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
part = (struct dos_partition *)
|
||||
(buffer + DOSPARTOFF + i * DOSPARTSIZE);
|
||||
if (part->dp_typ != 0 &&
|
||||
part->dp_typ != DOSPTYP_PMBR)
|
||||
break;
|
||||
}
|
||||
if (i < 4) {
|
||||
free(buffer);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
disk->gpt_size = 128;
|
||||
disk->lba_start = (disk->gpt_size * sizeof(struct gpt_ent)) /
|
||||
disk->sector_size + 2;
|
||||
disk->lba_end = (disk->media_size / disk->sector_size) -
|
||||
disk->lba_start;
|
||||
} else {
|
||||
disk->lba_start = gpt->hdr_lba_start;
|
||||
disk->lba_end = gpt->hdr_lba_end;
|
||||
disk->gpt_size = gpt->hdr_entries;
|
||||
}
|
||||
free(buffer);
|
||||
Add_Chunk(disk, disk->lba_start, disk->lba_end - disk->lba_start + 1,
|
||||
name, whole, 0, 0, "-");
|
||||
return (disk);
|
||||
|
||||
fail:
|
||||
free(disk->name);
|
||||
free(disk);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct disk *
|
||||
Int_Open_Disk(const char *name, char *conftxt)
|
||||
{
|
||||
struct chunk chunk;
|
||||
struct disk *disk;
|
||||
char *p, *q, *r, *s, *sd;
|
||||
u_long i;
|
||||
|
||||
p = conftxt;
|
||||
while (p != NULL && *p != 0) {
|
||||
q = strsep(&p, " ");
|
||||
if (strcmp(q, "0") == 0) {
|
||||
q = strsep(&p, " ");
|
||||
if (strcmp(q, "DISK") == 0) {
|
||||
q = strsep(&p, " ");
|
||||
if (strcmp(q, name) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
p = strchr(p, '\n');
|
||||
if (p != NULL && *p == '\n')
|
||||
p++;
|
||||
conftxt = p;
|
||||
}
|
||||
if (p == NULL || *p == 0)
|
||||
return (NULL);
|
||||
|
||||
conftxt = strchr(p, '\n');
|
||||
if (conftxt != NULL)
|
||||
*conftxt++ = '\0';
|
||||
|
||||
disk = parse_disk(p, name);
|
||||
if (disk == NULL)
|
||||
return (NULL);
|
||||
|
||||
while (conftxt != NULL && *conftxt != 0) {
|
||||
p = conftxt;
|
||||
conftxt = strchr(p, '\n');
|
||||
if (conftxt != NULL)
|
||||
*conftxt++ = '\0';
|
||||
|
||||
/*
|
||||
* 1 PART da0p4 34359738368 512
|
||||
* i 4 o 52063912960 ty freebsd-ufs
|
||||
* xs GPT xt 516e7cb6-6ecf-11d6-8ff8-00022d09712b
|
||||
*/
|
||||
sd = strsep(&p, " "); /* depth */
|
||||
if (strcmp(sd, "0") == 0)
|
||||
break;
|
||||
|
||||
q = strsep(&p, " "); /* type */
|
||||
if (strcmp(q, "PART") != 0)
|
||||
continue;
|
||||
|
||||
chunk.name = strsep(&p, " "); /* name */
|
||||
|
||||
q = strsep(&p, " "); /* length */
|
||||
i = strtoimax(q, &r, 0);
|
||||
if (*r)
|
||||
abort();
|
||||
chunk.end = i / disk->sector_size;
|
||||
|
||||
q = strsep(&p, " "); /* sector size */
|
||||
|
||||
for (;;) {
|
||||
q = strsep(&p, " ");
|
||||
if (q == NULL)
|
||||
break;
|
||||
r = strsep(&p, " ");
|
||||
i = strtoimax(r, &s, 0);
|
||||
if (strcmp(q, "ty") == 0 && *s != '\0') {
|
||||
if (!strcmp(r, "efi"))
|
||||
chunk.type = efi;
|
||||
else if (!strcmp(r, "freebsd")) {
|
||||
chunk.type = freebsd;
|
||||
chunk.subtype = 0xa5;
|
||||
} else if (!strcmp(r, "freebsd-swap")) {
|
||||
chunk.type = part;
|
||||
chunk.subtype = FS_SWAP;
|
||||
} else if (!strcmp(r, "freebsd-ufs")) {
|
||||
chunk.type = part;
|
||||
chunk.subtype = FS_BSDFFS;
|
||||
} else {
|
||||
chunk.type = part;
|
||||
chunk.subtype = FS_OTHER;
|
||||
}
|
||||
} else {
|
||||
if (!strcmp(q, "o"))
|
||||
chunk.offset = i / disk->sector_size;
|
||||
else if (!strcmp(q, "i"))
|
||||
chunk.flags = CHUNK_ITOF(i) |
|
||||
CHUNK_HAS_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
Add_Chunk(disk, chunk.offset, chunk.end, chunk.name,
|
||||
chunk.type, chunk.subtype, chunk.flags, 0);
|
||||
}
|
||||
|
||||
return (disk);
|
||||
}
|
@ -1,296 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stdint.h>
|
||||
#include <sys/disklabel.h>
|
||||
#ifdef PC98
|
||||
#include <sys/diskpc98.h>
|
||||
#else
|
||||
#include <sys/diskmbr.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
int
|
||||
Track_Aligned(const struct disk *d, daddr_t offset)
|
||||
{
|
||||
#ifndef __ia64__
|
||||
if (!d->bios_sect)
|
||||
return 1;
|
||||
if (offset % d->bios_sect)
|
||||
return 0;
|
||||
#endif /* __ia64__ */
|
||||
return 1;
|
||||
}
|
||||
|
||||
daddr_t
|
||||
Prev_Track_Aligned(const struct disk *d, daddr_t offset)
|
||||
{
|
||||
#ifndef __ia64__
|
||||
if (!d->bios_sect)
|
||||
return offset;
|
||||
return (offset / d->bios_sect) * d->bios_sect;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
daddr_t
|
||||
Next_Track_Aligned(const struct disk *d, daddr_t offset)
|
||||
{
|
||||
#ifndef __ia64__
|
||||
if (!d->bios_sect)
|
||||
return offset;
|
||||
return Prev_Track_Aligned(d, offset + d->bios_sect-1);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
Cyl_Aligned(const struct disk *d, daddr_t offset)
|
||||
{
|
||||
#ifndef __ia64__
|
||||
if (!d->bios_sect || !d->bios_hd)
|
||||
return 1;
|
||||
if (offset % (d->bios_sect * d->bios_hd))
|
||||
return 0;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
daddr_t
|
||||
Prev_Cyl_Aligned(const struct disk *d, daddr_t offset)
|
||||
{
|
||||
#ifndef __ia64__
|
||||
if (!d->bios_sect || !d->bios_hd)
|
||||
return offset;
|
||||
return (offset / (d->bios_sect * d->bios_hd)) * d->bios_sect *
|
||||
d->bios_hd;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
daddr_t
|
||||
Next_Cyl_Aligned(const struct disk *d, daddr_t offset)
|
||||
{
|
||||
#ifndef __ia64__
|
||||
if (!d->bios_sect || !d->bios_hd)
|
||||
return offset;
|
||||
return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd) - 1);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#0:
|
||||
* Chunks of type 'whole' can have max NDOSPART children.
|
||||
* Only one of them can have the "active" flag
|
||||
*/
|
||||
static void
|
||||
Rule_000(__unused const struct disk *d, const struct chunk *c, char *msg)
|
||||
{
|
||||
#ifdef PC98
|
||||
int i = 0;
|
||||
#else
|
||||
int i = 0, j = 0;
|
||||
#endif
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != whole)
|
||||
return;
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type != unused)
|
||||
continue;
|
||||
#ifndef PC98
|
||||
if (c1->flags & CHUNK_ACTIVE)
|
||||
j++;
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
if (i > NDOSPART)
|
||||
sprintf(msg + strlen(msg),
|
||||
"%d is too many children of the 'whole' chunk."
|
||||
" Max is %d\n", i, NDOSPART);
|
||||
#ifndef PC98
|
||||
if (j > 1)
|
||||
sprintf(msg + strlen(msg),
|
||||
"Too many active children of 'whole'");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#1:
|
||||
* All children of 'whole' and 'extended' must be track-aligned.
|
||||
* Exception: the end can be unaligned if it matches the end of 'whole'
|
||||
*/
|
||||
static void
|
||||
Rule_001(const struct disk *d, const struct chunk *c, char *msg)
|
||||
{
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != whole && c->type != extended)
|
||||
return;
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
c1->flags |= CHUNK_ALIGN;
|
||||
#ifdef PC98
|
||||
if (!Cyl_Aligned(d, c1->offset))
|
||||
#else
|
||||
if (!Track_Aligned(d, c1->offset))
|
||||
#endif
|
||||
sprintf(msg + strlen(msg),
|
||||
#ifdef PC98
|
||||
"chunk '%s' [%jd..%jd] does not start"
|
||||
" on a cylinder boundary\n",
|
||||
#else
|
||||
"chunk '%s' [%jd..%jd] does not start"
|
||||
" on a track boundary\n",
|
||||
#endif
|
||||
c1->name, (intmax_t)c1->offset, (intmax_t)c1->end);
|
||||
if ((c->type == whole || c->end == c1->end)
|
||||
|| Cyl_Aligned(d, c1->end + 1))
|
||||
;
|
||||
else
|
||||
sprintf(msg + strlen(msg),
|
||||
"chunk '%s' [%jd..%jd] does not end"
|
||||
" on a cylinder boundary\n",
|
||||
c1->name, (intmax_t)c1->offset, (intmax_t)c1->end);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#2:
|
||||
* Max one 'fat' as child of 'whole'
|
||||
*/
|
||||
static void
|
||||
Rule_002(__unused const struct disk *d, const struct chunk *c, char *msg)
|
||||
{
|
||||
int i;
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != whole)
|
||||
return;
|
||||
for (i = 0, c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type != fat)
|
||||
continue;
|
||||
i++;
|
||||
}
|
||||
if (i > 1) {
|
||||
sprintf(msg + strlen(msg),
|
||||
"Max one 'fat' allowed as child of 'whole'\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#3:
|
||||
* Max one extended as child of 'whole'
|
||||
*/
|
||||
static void
|
||||
Rule_003(__unused const struct disk *d, const struct chunk *c, char *msg)
|
||||
{
|
||||
int i;
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != whole)
|
||||
return;
|
||||
for (i = 0, c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type != extended)
|
||||
continue;
|
||||
i++;
|
||||
}
|
||||
if (i > 1) {
|
||||
sprintf(msg + strlen(msg),
|
||||
"Max one 'extended' allowed as child of 'whole'\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule#4:
|
||||
* Max seven 'part' as children of 'freebsd'
|
||||
* Max one CHUNK_IS_ROOT child per 'freebsd'
|
||||
*/
|
||||
static void
|
||||
Rule_004(__unused const struct disk *d, const struct chunk *c, char *msg)
|
||||
{
|
||||
int i = 0, k = 0;
|
||||
struct chunk *c1;
|
||||
|
||||
if (c->type != freebsd)
|
||||
return;
|
||||
|
||||
for (c1 = c->part; c1; c1 = c1->next) {
|
||||
if (c1->type != part)
|
||||
continue;
|
||||
if (c1->flags & CHUNK_IS_ROOT)
|
||||
k++;
|
||||
i++;
|
||||
}
|
||||
if (i > 7) {
|
||||
sprintf(msg + strlen(msg),
|
||||
"Max seven partitions per freebsd slice\n");
|
||||
}
|
||||
if (k > 1) {
|
||||
sprintf(msg + strlen(msg),
|
||||
"Max one root partition child per freebsd slice\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Check_Chunk(const struct disk *d, const struct chunk *c, char *msg)
|
||||
{
|
||||
|
||||
switch (platform) {
|
||||
case p_i386:
|
||||
case p_amd64:
|
||||
Rule_000(d, c, msg);
|
||||
Rule_001(d, c, msg);
|
||||
Rule_002(d, c, msg);
|
||||
Rule_003(d, c, msg);
|
||||
Rule_004(d, c, msg);
|
||||
if (c->part)
|
||||
Check_Chunk(d, c->part, msg);
|
||||
if (c->next)
|
||||
Check_Chunk(d, c->next, msg);
|
||||
break;
|
||||
case p_pc98:
|
||||
Rule_000(d, c, msg);
|
||||
Rule_001(d, c, msg);
|
||||
Rule_004(d, c, msg);
|
||||
if (c->part)
|
||||
Check_Chunk(d, c->part, msg);
|
||||
if (c->next)
|
||||
Check_Chunk(d, c->next, msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
CheckRules(const struct disk *d)
|
||||
{
|
||||
char msg[BUFSIZ];
|
||||
|
||||
*msg = '\0';
|
||||
Check_Chunk(d, d->chunks, msg);
|
||||
if (*msg)
|
||||
return strdup(msg);
|
||||
return 0;
|
||||
}
|
@ -1,323 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#ifdef READLINE
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
#ifndef PC98
|
||||
u_char mbrboot[] = {
|
||||
250,51,192,142,208,188,0,124,139,244,80,7,80,31,251,252,191,0,6,185,0,1,
|
||||
242,165,234,29,6,0,0,190,190,7,179,4,128,60,128,116,14,128,60,0,117,28,
|
||||
131,198,16,254,203,117,239,205,24,139,20,139,76,2,139,238,131,198,16,254,
|
||||
203,116,26,128,60,0,116,244,190,139,6,172,60,0,116,11,86,187,7,0,180,14,
|
||||
205,16,94,235,240,235,254,191,5,0,187,0,124,184,1,2,87,205,19,95,115,12,
|
||||
51,192,205,19,79,117,237,190,163,6,235,211,190,194,6,191,254,125,129,61,
|
||||
85,170,117,199,139,245,234,0,124,0,0,73,110,118,97,108,105,100,32,112,97,
|
||||
114,116,105,116,105,111,110,32,116,97,98,108,101,0,69,114,114,111,114,32,
|
||||
108,111,97,100,105,110,103,32,111,112,101,114,97,116,105,110,103,32,115,
|
||||
121,115,116,101,109,0,77,105,115,115,105,110,103,32,111,112,101,114,97,
|
||||
116,105,110,103,32,115,121,115,116,101,109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,
|
||||
1,1,0,4,15,63,60,63,0,0,0,241,239,0,0,0,0,1,61,5,15,63,243,48,240,0,0,144,
|
||||
208,2,0,0,0,1,244,165,15,63,170,192,192,3,0,144,208,2,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,85,170
|
||||
};
|
||||
|
||||
u_char bteasy17[] = {
|
||||
51,192,142,192,142,216,142,208,188,0,124,252,139,244,191,0,6,185,0,1,242,
|
||||
165,234,96,6,0,0,139,213,88,162,72,7,60,53,116,28,180,16,246,228,5,174,
|
||||
4,150,246,68,4,255,116,62,198,4,128,232,218,0,138,116,1,139,76,2,235,8,
|
||||
232,207,0,185,1,0,50,209,187,0,124,184,1,2,205,19,114,30,129,191,254,1,
|
||||
85,170,117,22,234,0,124,0,0,128,250,129,116,2,178,128,139,234,66,128,242,
|
||||
179,136,22,58,7,191,190,7,185,4,0,198,6,45,7,49,50,246,136,45,138,69,4,
|
||||
60,0,116,35,60,5,116,31,254,198,190,42,7,232,113,0,190,72,7,70,70,139,28,
|
||||
10,255,116,5,50,125,4,117,243,141,183,114,7,232,90,0,131,199,16,254,6,45,
|
||||
7,226,203,128,62,117,4,2,116,11,190,59,7,10,246,117,10,205,24,235,172,190,
|
||||
42,7,232,57,0,232,54,0,50,228,205,26,139,218,131,195,96,180,1,205,22,180,
|
||||
0,117,11,205,26,59,211,114,242,160,72,7,235,10,205,22,138,196,60,28,116,
|
||||
243,4,246,60,49,114,214,60,53,119,210,80,190,40,7,187,27,6,83,252,172,80,
|
||||
36,127,180,14,205,16,88,168,128,116,242,195,86,184,1,3,187,0,6,185,1,0,
|
||||
50,246,205,19,94,198,6,72,7,63,195,13,138,13,10,70,48,32,46,32,46,32,46,
|
||||
160,100,105,115,107,32,49,13,10,10,68,101,102,97,117,108,116,58,32,70,63,
|
||||
160,0,1,0,4,0,6,3,7,7,10,10,99,14,100,14,101,20,128,20,129,25,130,30,147,
|
||||
36,165,39,159,43,117,47,82,47,219,50,64,55,242,61,0,100,111,243,72,80,70,
|
||||
211,79,115,178,85,110,105,248,78,111,118,101,108,236,77,105,110,105,248,
|
||||
76,105,110,117,248,65,109,111,101,98,225,66,83,196,66,83,68,233,80,67,73,
|
||||
216,67,80,205,86,101,110,105,248,68,111,115,115,101,227,63,191,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,85,170
|
||||
};
|
||||
#endif
|
||||
|
||||
int
|
||||
scan_block(int fd, daddr_t block)
|
||||
{
|
||||
u_char foo[512];
|
||||
|
||||
if (-1 == lseek(fd, (off_t)block * 512, SEEK_SET))
|
||||
err(1, "lseek");
|
||||
if (512 != read(fd, foo, 512))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Scan_Disk(struct disk *d)
|
||||
{
|
||||
char device[64];
|
||||
u_long l;
|
||||
int i, j, fd;
|
||||
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, d->name);
|
||||
|
||||
fd = open(device, O_RDWR);
|
||||
if (fd < 0) {
|
||||
warn("open(%s) failed", device);
|
||||
return;
|
||||
}
|
||||
for (i = -1, l = 0; ; l++) {
|
||||
j = scan_block(fd, l);
|
||||
if (j != i) {
|
||||
if (i == -1) {
|
||||
printf("%c: %lu.",j ? 'B' : 'G', l);
|
||||
fflush(stdout);
|
||||
} else if (i == 0) {
|
||||
printf(".%lu\nB: %lu.", l - 1, l);
|
||||
fflush(stdout);
|
||||
} else {
|
||||
printf(".%lu\nG: %lu.", l - 1, l);
|
||||
fflush(stdout);
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct disk *d,*db;
|
||||
char myprompt[BUFSIZ];
|
||||
#ifndef READLINE
|
||||
char input[BUFSIZ];
|
||||
#endif
|
||||
char *p,*q = 0;
|
||||
char **cp, *cmds[200];
|
||||
int ncmd, i;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage:\n\t%s diskname\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
d = Open_Disk(argv[1]);
|
||||
if (!d)
|
||||
err(1, "Couldn't open disk %s", argv[1]);
|
||||
|
||||
sprintf(myprompt, "%s %s> ", argv[0], argv[1]);
|
||||
while (1) {
|
||||
printf("--==##==--\n");
|
||||
p = CheckRules(d);
|
||||
Debug_Disk(d);
|
||||
if (p) {
|
||||
printf("%s",p);
|
||||
free(p);
|
||||
}
|
||||
#ifdef READLINE
|
||||
if (q)
|
||||
free(q);
|
||||
q = p = readline(myprompt);
|
||||
#else
|
||||
printf("%s", myprompt);
|
||||
fflush(stdout);
|
||||
q = p = fgets(input, sizeof(input), stdin);
|
||||
#endif
|
||||
if(!p)
|
||||
break;
|
||||
for (cp = cmds; (*cp = strsep(&p, " \t\n")) != NULL;)
|
||||
if (**cp != '\0')
|
||||
cp++;
|
||||
ncmd = cp - cmds;
|
||||
if (!ncmd)
|
||||
continue;
|
||||
if (!strcasecmp(*cmds, "quit"))
|
||||
break;
|
||||
if (!strcasecmp(*cmds, "exit"))
|
||||
break;
|
||||
if (!strcasecmp(*cmds, "q"))
|
||||
break;
|
||||
if (!strcasecmp(*cmds, "x"))
|
||||
break;
|
||||
if (!strcasecmp(*cmds, "dwim") && ncmd == 6) {
|
||||
printf("dwim = %p\n",
|
||||
Create_Chunk_DWIM(d,
|
||||
(struct chunk *)strtol(cmds[1], 0, 0),
|
||||
strtol(cmds[2], 0, 0),
|
||||
strtol(cmds[3], 0, 0),
|
||||
strtol(cmds[4], 0, 0),
|
||||
strtol(cmds[5], 0, 0)));
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds, "delete") && ncmd == 2) {
|
||||
printf("delete = %d\n",
|
||||
Delete_Chunk(d,
|
||||
(struct chunk *)strtol(cmds[1], 0, 0)));
|
||||
continue;
|
||||
}
|
||||
#ifndef __ia64__
|
||||
if (!strcasecmp(*cmds, "allfreebsd")) {
|
||||
All_FreeBSD(d, 0);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds, "dedicate")) {
|
||||
All_FreeBSD(d, 1);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds, "sanitize")) {
|
||||
Sanitize_Bios_Geom(d);
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds, "bios") && ncmd == 4) {
|
||||
Set_Bios_Geom(d, strtol(cmds[1], 0, 0),
|
||||
strtol(cmds[2], 0, 0),
|
||||
strtol(cmds[3], 0, 0));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
#ifdef PC98
|
||||
if (!strcasecmp(*cmds, "create") && ncmd == 7) {
|
||||
#else
|
||||
if (!strcasecmp(*cmds,"create") && ncmd == 6) {
|
||||
#endif
|
||||
|
||||
printf("Create=%d\n",
|
||||
Create_Chunk(d,
|
||||
strtol(cmds[1], 0, 0),
|
||||
strtol(cmds[2], 0, 0),
|
||||
strtol(cmds[3], 0, 0),
|
||||
strtol(cmds[4], 0, 0),
|
||||
#ifdef PC98
|
||||
strtol(cmds[5], 0, 0), cmds[6]));
|
||||
#else
|
||||
strtol(cmds[5], 0, 0), NULL));
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"read")) {
|
||||
db = d;
|
||||
if (ncmd > 1)
|
||||
d = Open_Disk(cmds[1]);
|
||||
else
|
||||
d = Open_Disk(argv[1]);
|
||||
if (d)
|
||||
Free_Disk(db);
|
||||
else
|
||||
d = db;
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds,"scan")) {
|
||||
Scan_Disk(d);
|
||||
continue;
|
||||
}
|
||||
#ifndef PC98
|
||||
if (!strcasecmp(*cmds,"bteasy")) {
|
||||
Set_Boot_Mgr(d, bteasy17, sizeof (bteasy17));
|
||||
continue;
|
||||
}
|
||||
if (!strcasecmp(*cmds, "mbr")) {
|
||||
Set_Boot_Mgr(d, mbrboot, sizeof (mbrboot));
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
#if 0 /* XXX boot1 undefined, fix me */
|
||||
if (!strcasecmp(*cmds, "boot")) {
|
||||
Set_Boot_Blocks(d, boot1, boot2);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (!strcasecmp(*cmds, "write")) {
|
||||
printf("Write=%d\n",
|
||||
Write_Disk(d));
|
||||
Free_Disk(d);
|
||||
d = Open_Disk(argv[1]);
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(*cmds, "help"))
|
||||
printf("\007ERROR\n");
|
||||
printf("CMDS:\n");
|
||||
printf("\tallfreebsd\n");
|
||||
printf("\tdedicate\n");
|
||||
printf("\tbios cyl hd sect\n");
|
||||
printf("\tboot\n");
|
||||
#ifndef PC98
|
||||
printf("\tbteasy17\n");
|
||||
#endif
|
||||
#if 0
|
||||
printf("\tcollapse [pointer]\n");
|
||||
#endif
|
||||
#ifdef PC98
|
||||
printf("\tcreate offset size enum subtype flags name\n");
|
||||
#else
|
||||
printf("\tcreate offset size enum subtype flags\n");
|
||||
#endif
|
||||
printf("\t\tsubtype(part): swap=1, ffs=7\n");
|
||||
printf("\tdelete pointer\n");
|
||||
printf("\tlist\n");
|
||||
#ifndef PC98
|
||||
printf("\tmbr\n");
|
||||
#endif
|
||||
#if 0
|
||||
printf("\tphys cyl hd sect\n");
|
||||
#endif
|
||||
printf("\tquit\n");
|
||||
printf("\tread [disk]\n");
|
||||
printf("\tscan\n");
|
||||
printf("\twrite\n");
|
||||
printf("\nENUM:\n\t");
|
||||
#if 0
|
||||
for (i = 0; chunk_n[i]; i++)
|
||||
printf("%d = %s%s", i, chunk_n[i],
|
||||
i == 4 ? "\n\t" : " ");
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
exit (0);
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskmbr.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
/*
|
||||
* XXX: A lot of hardcoded 512s probably should be foo->sector_size;
|
||||
* I'm not sure which, so I leave it like it worked before. --schweikh
|
||||
*/
|
||||
static int
|
||||
Write_FreeBSD(int fd, const struct disk *new, const struct chunk *c1)
|
||||
{
|
||||
struct disklabel *dl;
|
||||
int i;
|
||||
void *p;
|
||||
u_char buf[BBSIZE];
|
||||
|
||||
for (i = 0; i < BBSIZE/512; i++) {
|
||||
if (!(p = read_block(fd, i + c1->offset, 512)))
|
||||
return (1);
|
||||
memcpy(buf + 512 * i, p, 512);
|
||||
free(p);
|
||||
}
|
||||
if (new->boot1)
|
||||
memcpy(buf, new->boot1, 512);
|
||||
|
||||
if (new->boot2)
|
||||
memcpy(buf + 512, new->boot2, BBSIZE - 512);
|
||||
|
||||
dl = (struct disklabel *)(buf + 512 * LABELSECTOR + LABELOFFSET);
|
||||
Fill_Disklabel(dl, new, c1);
|
||||
|
||||
for (i = 0; i < BBSIZE / 512; i++)
|
||||
write_block(fd, i + c1->offset, buf + 512 * i, 512);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Write_Int32(u_int32_t *p, u_int32_t v)
|
||||
{
|
||||
u_int8_t *bp = (u_int8_t *)p;
|
||||
|
||||
bp[0] = (v >> 0) & 0xff;
|
||||
bp[1] = (v >> 8) & 0xff;
|
||||
bp[2] = (v >> 16) & 0xff;
|
||||
bp[3] = (v >> 24) & 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special install-time configuration for the i386 boot0 boot manager.
|
||||
*/
|
||||
static void
|
||||
Cfg_Boot_Mgr(u_char *mbr, int edd)
|
||||
{
|
||||
|
||||
if (mbr[0x1b0] == 0x66 && mbr[0x1b1] == 0xbb) {
|
||||
if (edd)
|
||||
mbr[0x1bb] |= 0x80; /* Packet mode on */
|
||||
else
|
||||
mbr[0x1bb] &= 0x7f; /* Packet mode off */
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *d1)
|
||||
{
|
||||
int fd, j;
|
||||
uint i;
|
||||
struct chunk *c1;
|
||||
int ret = 0;
|
||||
char device[64];
|
||||
u_char *mbr;
|
||||
struct dos_partition *dp,work[NDOSPART];
|
||||
int s[4];
|
||||
int need_edd = 0; /* Need EDD (packet interface) */
|
||||
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, d1->name);
|
||||
|
||||
fd = open(device, O_RDWR);
|
||||
if (fd < 0)
|
||||
return 1;
|
||||
|
||||
memset(s, 0, sizeof s);
|
||||
if (!(mbr = read_block(fd, 0, d1->sector_size))) {
|
||||
close (fd);
|
||||
return (1);
|
||||
}
|
||||
dp = (struct dos_partition *)(mbr + DOSPARTOFF);
|
||||
memcpy(work, dp, sizeof work);
|
||||
dp = work;
|
||||
free(mbr);
|
||||
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
if (!strcmp(c1->name, "X"))
|
||||
continue;
|
||||
j = c1->name[strlen(d1->name) + 1] - '1';
|
||||
if (j < 0 || j > 3)
|
||||
continue;
|
||||
s[j]++;
|
||||
if (c1->type == freebsd)
|
||||
ret += Write_FreeBSD(fd, d1, c1);
|
||||
|
||||
Write_Int32(&dp[j].dp_start, c1->offset);
|
||||
Write_Int32(&dp[j].dp_size, c1->size);
|
||||
|
||||
i = c1->offset;
|
||||
if (i >= 1024 * d1->bios_sect * d1->bios_hd) {
|
||||
dp[j].dp_ssect = 0xff;
|
||||
dp[j].dp_shd = 0xff;
|
||||
dp[j].dp_scyl = 0xff;
|
||||
need_edd++;
|
||||
} else {
|
||||
dp[j].dp_ssect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_ssect++;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_shd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_shd;
|
||||
i /= d1->bios_hd;
|
||||
dp[j].dp_scyl = i;
|
||||
i -= dp[j].dp_scyl;
|
||||
dp[j].dp_ssect |= i >> 2;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("S:%lu = (%x/%x/%x)", c1->offset,
|
||||
dp[j].dp_scyl, dp[j].dp_shd, dp[j].dp_ssect);
|
||||
#endif
|
||||
|
||||
i = c1->end;
|
||||
dp[j].dp_esect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_esect++;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_ehd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_ehd;
|
||||
i /= d1->bios_hd;
|
||||
if (i > 1023)
|
||||
i = 1023;
|
||||
dp[j].dp_ecyl = i;
|
||||
i -= dp[j].dp_ecyl;
|
||||
dp[j].dp_esect |= i >> 2;
|
||||
#ifdef DEBUG
|
||||
printf(" E:%lu = (%x/%x/%x)\n", c1->end,
|
||||
dp[j].dp_ecyl, dp[j].dp_ehd, dp[j].dp_esect);
|
||||
#endif
|
||||
|
||||
dp[j].dp_typ = c1->subtype;
|
||||
if (c1->flags & CHUNK_ACTIVE)
|
||||
dp[j].dp_flag = 0x80;
|
||||
else
|
||||
dp[j].dp_flag = 0;
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; i < NDOSPART; i++) {
|
||||
if (!s[i])
|
||||
memset(dp + i, 0, sizeof *dp);
|
||||
if (dp[i].dp_flag)
|
||||
j++;
|
||||
}
|
||||
if (!j)
|
||||
for(i = 0; i < NDOSPART; i++)
|
||||
if (dp[i].dp_typ == 0xa5)
|
||||
dp[i].dp_flag = 0x80;
|
||||
|
||||
if (!(mbr = read_block(fd, 0, d1->sector_size))) {
|
||||
close (fd);
|
||||
return (1);
|
||||
}
|
||||
if (d1->bootmgr) {
|
||||
memcpy(mbr, d1->bootmgr, DOSPARTOFF);
|
||||
Cfg_Boot_Mgr(mbr, need_edd);
|
||||
}
|
||||
memcpy(mbr + DOSPARTOFF, dp, sizeof *dp * NDOSPART);
|
||||
mbr[512-2] = 0x55;
|
||||
mbr[512-1] = 0xaa;
|
||||
write_block(fd, 0, mbr, d1->sector_size);
|
||||
if (d1->bootmgr && d1->bootmgr_size > d1->sector_size)
|
||||
for (i = 1; i * d1->sector_size <= d1->bootmgr_size; i++)
|
||||
write_block(fd, i, &d1->bootmgr[i * d1->sector_size],
|
||||
d1->sector_size);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Olivier Houchard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *d1)
|
||||
{
|
||||
return (0);
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
void
|
||||
Fill_Disklabel(struct disklabel *dl, const struct disk *new,
|
||||
const struct chunk *c1)
|
||||
{
|
||||
struct chunk *c2;
|
||||
int j;
|
||||
|
||||
memset(dl, 0, sizeof *dl);
|
||||
|
||||
for (c2 = c1->part; c2; c2 = c2->next) {
|
||||
if (c2->type == unused)
|
||||
continue;
|
||||
if (!strcmp(c2->name, "X"))
|
||||
continue;
|
||||
j = c2->name[strlen(c2->name) - 1] - 'a';
|
||||
if (j < 0 || j >= MAXPARTITIONS || j == RAW_PART)
|
||||
continue;
|
||||
dl->d_partitions[j].p_size = c2->size;
|
||||
dl->d_partitions[j].p_offset = c2->offset;
|
||||
dl->d_partitions[j].p_fstype = c2->subtype;
|
||||
}
|
||||
|
||||
dl->d_bbsize = BBSIZE;
|
||||
/*
|
||||
* Add in defaults for superblock size, interleave, and rpms
|
||||
*/
|
||||
dl->d_sbsize = 0;
|
||||
|
||||
strcpy(dl->d_typename, c1->name);
|
||||
|
||||
dl->d_secsize = 512;
|
||||
dl->d_secperunit = new->chunks->size;
|
||||
#ifndef __ia64__
|
||||
dl->d_ncylinders = new->bios_cyl;
|
||||
dl->d_ntracks = new->bios_hd;
|
||||
dl->d_nsectors = new->bios_sect;
|
||||
#endif
|
||||
dl->d_secpercyl = dl->d_ntracks * dl->d_nsectors;
|
||||
|
||||
dl->d_npartitions = MAXPARTITIONS;
|
||||
|
||||
dl->d_type = new->name[0] == 's' || new->name[0] == 'd' ||
|
||||
new->name[0] == 'o' ? DTYPE_SCSI : DTYPE_ESDI;
|
||||
dl->d_partitions[RAW_PART].p_size = c1->size;
|
||||
dl->d_partitions[RAW_PART].p_offset = c1->offset;
|
||||
dl->d_rpm = 3600;
|
||||
dl->d_interleave = 1;
|
||||
|
||||
dl->d_magic = DISKMAGIC;
|
||||
dl->d_magic2 = DISKMAGIC;
|
||||
dl->d_checksum = dkcksum(dl);
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskmbr.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
/*
|
||||
* XXX: A lot of hardcoded 512s probably should be foo->sector_size;
|
||||
* I'm not sure which, so I leave it like it worked before. --schweikh
|
||||
*/
|
||||
static int
|
||||
Write_FreeBSD(int fd, const struct disk *new, const struct chunk *c1)
|
||||
{
|
||||
struct disklabel *dl;
|
||||
int i;
|
||||
void *p;
|
||||
u_char buf[BBSIZE];
|
||||
|
||||
for (i = 0; i < BBSIZE/512; i++) {
|
||||
if (!(p = read_block(fd, i + c1->offset, 512)))
|
||||
return (1);
|
||||
memcpy(buf + 512 * i, p, 512);
|
||||
free(p);
|
||||
}
|
||||
if (new->boot1)
|
||||
memcpy(buf, new->boot1, 512);
|
||||
|
||||
if (new->boot2)
|
||||
memcpy(buf + 512, new->boot2, BBSIZE - 512);
|
||||
|
||||
dl = (struct disklabel *)(buf + 512 * LABELSECTOR + LABELOFFSET);
|
||||
Fill_Disklabel(dl, new, c1);
|
||||
|
||||
for (i = 0; i < BBSIZE / 512; i++)
|
||||
write_block(fd, i + c1->offset, buf + 512 * i, 512);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Write_Int32(u_int32_t *p, u_int32_t v)
|
||||
{
|
||||
u_int8_t *bp = (u_int8_t *)p;
|
||||
|
||||
bp[0] = (v >> 0) & 0xff;
|
||||
bp[1] = (v >> 8) & 0xff;
|
||||
bp[2] = (v >> 16) & 0xff;
|
||||
bp[3] = (v >> 24) & 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* Special install-time configuration for the i386 boot0 boot manager.
|
||||
*/
|
||||
static void
|
||||
Cfg_Boot_Mgr(u_char *mbrblk, int edd)
|
||||
{
|
||||
|
||||
if (mbrblk[0x1b0] == 0x66 && mbrblk[0x1b1] == 0xbb) {
|
||||
if (edd)
|
||||
mbrblk[0x1bb] |= 0x80; /* Packet mode on */
|
||||
else
|
||||
mbrblk[0x1bb] &= 0x7f; /* Packet mode off */
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *d1)
|
||||
{
|
||||
int fd, j;
|
||||
uint i;
|
||||
struct chunk *c1;
|
||||
int ret = 0;
|
||||
char device[64];
|
||||
u_char *mbrblk;
|
||||
struct dos_partition *dp,work[NDOSPART];
|
||||
int s[4];
|
||||
int need_edd = 0; /* Need EDD (packet interface) */
|
||||
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, d1->name);
|
||||
|
||||
fd = open(device, O_RDWR);
|
||||
if (fd < 0)
|
||||
return 1;
|
||||
|
||||
memset(s, 0, sizeof s);
|
||||
if (!(mbrblk = read_block(fd, 0, d1->sector_size))) {
|
||||
close (fd);
|
||||
return (1);
|
||||
}
|
||||
dp = (struct dos_partition *)(mbrblk + DOSPARTOFF);
|
||||
memcpy(work, dp, sizeof work);
|
||||
dp = work;
|
||||
free(mbrblk);
|
||||
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
if (!strcmp(c1->name, "X"))
|
||||
continue;
|
||||
j = c1->name[strlen(d1->name) + 1] - '1';
|
||||
if (j < 0 || j > 3)
|
||||
continue;
|
||||
s[j]++;
|
||||
if (c1->type == freebsd)
|
||||
ret += Write_FreeBSD(fd, d1, c1);
|
||||
|
||||
Write_Int32(&dp[j].dp_start, c1->offset);
|
||||
Write_Int32(&dp[j].dp_size, c1->size);
|
||||
|
||||
i = c1->offset;
|
||||
if (i >= 1024 * d1->bios_sect * d1->bios_hd) {
|
||||
dp[j].dp_ssect = 0xff;
|
||||
dp[j].dp_shd = 0xff;
|
||||
dp[j].dp_scyl = 0xff;
|
||||
need_edd++;
|
||||
} else {
|
||||
dp[j].dp_ssect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_ssect++;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_shd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_shd;
|
||||
i /= d1->bios_hd;
|
||||
dp[j].dp_scyl = i;
|
||||
i -= dp[j].dp_scyl;
|
||||
dp[j].dp_ssect |= i >> 2;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf("S:%lu = (%x/%x/%x)", c1->offset,
|
||||
dp[j].dp_scyl, dp[j].dp_shd, dp[j].dp_ssect);
|
||||
#endif
|
||||
|
||||
i = c1->end;
|
||||
dp[j].dp_esect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_esect++;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_ehd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_ehd;
|
||||
i /= d1->bios_hd;
|
||||
if (i > 1023)
|
||||
i = 1023;
|
||||
dp[j].dp_ecyl = i;
|
||||
i -= dp[j].dp_ecyl;
|
||||
dp[j].dp_esect |= i >> 2;
|
||||
#ifdef DEBUG
|
||||
printf(" E:%lu = (%x/%x/%x)\n", c1->end,
|
||||
dp[j].dp_ecyl, dp[j].dp_ehd, dp[j].dp_esect);
|
||||
#endif
|
||||
|
||||
dp[j].dp_typ = c1->subtype;
|
||||
if (c1->flags & CHUNK_ACTIVE)
|
||||
dp[j].dp_flag = 0x80;
|
||||
else
|
||||
dp[j].dp_flag = 0;
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; i < NDOSPART; i++) {
|
||||
if (!s[i])
|
||||
memset(dp + i, 0, sizeof *dp);
|
||||
if (dp[i].dp_flag)
|
||||
j++;
|
||||
}
|
||||
if (!j)
|
||||
for(i = 0; i < NDOSPART; i++)
|
||||
if (dp[i].dp_typ == 0xa5)
|
||||
dp[i].dp_flag = 0x80;
|
||||
|
||||
if (!(mbrblk = read_block(fd, 0, d1->sector_size))) {
|
||||
close (fd);
|
||||
return (1);
|
||||
}
|
||||
if (d1->bootmgr) {
|
||||
memcpy(mbrblk, d1->bootmgr, DOSPARTOFF);
|
||||
Cfg_Boot_Mgr(mbrblk, need_edd);
|
||||
}
|
||||
memcpy(mbrblk + DOSPARTOFF, dp, sizeof *dp * NDOSPART);
|
||||
mbrblk[512-2] = 0x55;
|
||||
mbrblk[512-1] = 0xaa;
|
||||
write_block(fd, 0, mbrblk, d1->sector_size);
|
||||
if (d1->bootmgr && d1->bootmgr_size > d1->sector_size)
|
||||
for (i = 1; i * d1->sector_size <= d1->bootmgr_size; i++)
|
||||
write_block(fd, i, &d1->bootmgr[i * d1->sector_size],
|
||||
d1->sector_size);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
@ -1,423 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Marcel Moolenaar
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* CRC32 code derived from work by Gary S. Brown.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskmbr.h>
|
||||
#include <sys/gpt.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <uuid.h>
|
||||
|
||||
#include "libdisk.h"
|
||||
|
||||
static uuid_t _efi = GPT_ENT_TYPE_EFI;
|
||||
static uuid_t _fbsd = GPT_ENT_TYPE_FREEBSD;
|
||||
static uuid_t _swap = GPT_ENT_TYPE_FREEBSD_SWAP;
|
||||
static uuid_t _ufs = GPT_ENT_TYPE_FREEBSD_UFS;
|
||||
|
||||
static uint32_t crc32_tab[] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
crc32(const void *buf, size_t size)
|
||||
{
|
||||
const uint8_t *p;
|
||||
uint32_t crc;
|
||||
|
||||
p = buf;
|
||||
crc = ~0U;
|
||||
|
||||
while (size--)
|
||||
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
|
||||
|
||||
return (crc ^ ~0U);
|
||||
}
|
||||
|
||||
static int
|
||||
write_pmbr(int fd, const struct disk *disk)
|
||||
{
|
||||
struct dos_partition dp;
|
||||
char *buffer;
|
||||
u_long nsects;
|
||||
int error;
|
||||
|
||||
error = 0;
|
||||
nsects = disk->media_size / disk->sector_size;
|
||||
nsects--; /* The GPT starts at LBA 1 */
|
||||
|
||||
buffer = calloc(disk->sector_size, 1);
|
||||
if (buffer == NULL)
|
||||
return (ENOMEM);
|
||||
buffer[DOSMAGICOFFSET] = DOSMAGIC & 0xff;
|
||||
buffer[DOSMAGICOFFSET + 1] = DOSMAGIC >> 8;
|
||||
|
||||
dp.dp_flag = 0;
|
||||
dp.dp_shd = dp.dp_ssect = dp.dp_scyl = 0xff;
|
||||
dp.dp_typ = DOSPTYP_PMBR;
|
||||
dp.dp_ehd = dp.dp_esect = dp.dp_ecyl = 0xff;
|
||||
dp.dp_start = 1;
|
||||
dp.dp_size = (nsects > 0xffffffffu) ? ~0u : nsects;
|
||||
memcpy(buffer + DOSPARTOFF, &dp, DOSPARTSIZE);
|
||||
|
||||
if (lseek(fd, 0L, SEEK_SET) != 0L ||
|
||||
write(fd, buffer, disk->sector_size) != disk->sector_size)
|
||||
error = (errno) ? errno : EAGAIN;
|
||||
|
||||
free(buffer);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
read_gpt(int fd, const struct disk *disk, struct gpt_hdr *hdr,
|
||||
struct gpt_ent *tbl)
|
||||
{
|
||||
char *buffer;
|
||||
off_t off;
|
||||
size_t nsects, sz;
|
||||
int error, i;
|
||||
|
||||
error = 0;
|
||||
nsects = disk->gpt_size * sizeof(struct gpt_ent) / disk->sector_size;
|
||||
nsects++;
|
||||
sz = nsects * disk->sector_size;
|
||||
buffer = malloc(sz);
|
||||
if (buffer == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
if (lseek(fd, disk->sector_size, SEEK_SET) != disk->sector_size ||
|
||||
read(fd, buffer, disk->sector_size) != disk->sector_size) {
|
||||
error = (errno) ? errno : EAGAIN;
|
||||
goto bail;
|
||||
}
|
||||
if (memcmp(buffer, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0) {
|
||||
/*
|
||||
* No GPT on disk. Create one out of thin air.
|
||||
*/
|
||||
bzero(&hdr[0], sizeof(struct gpt_hdr));
|
||||
memcpy(hdr[0].hdr_sig, GPT_HDR_SIG, sizeof(hdr[0].hdr_sig));
|
||||
hdr[0].hdr_revision = GPT_HDR_REVISION;
|
||||
hdr[0].hdr_size = offsetof(struct gpt_hdr, padding);
|
||||
hdr[0].hdr_lba_self = 1;
|
||||
hdr[0].hdr_lba_alt = disk->media_size / disk->sector_size - 1L;
|
||||
hdr[0].hdr_lba_start = disk->lba_start;
|
||||
hdr[0].hdr_lba_end = disk->lba_end;
|
||||
uuid_create(&hdr[0].hdr_uuid, NULL);
|
||||
hdr[0].hdr_lba_table = 2;
|
||||
hdr[0].hdr_entries = disk->gpt_size;
|
||||
hdr[0].hdr_entsz = sizeof(struct gpt_ent);
|
||||
hdr[1] = hdr[0];
|
||||
hdr[1].hdr_lba_self = hdr[0].hdr_lba_alt;
|
||||
hdr[1].hdr_lba_alt = hdr[0].hdr_lba_self;
|
||||
hdr[1].hdr_lba_table = disk->lba_end + 1;
|
||||
|
||||
for (i = 0; i < disk->gpt_size; i++) {
|
||||
bzero(&tbl[i], sizeof(struct gpt_ent));
|
||||
uuid_create(&tbl[i].ent_uuid, NULL);
|
||||
}
|
||||
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a GPT on disk. Read it.
|
||||
*/
|
||||
memcpy(&hdr[0], buffer, sizeof(struct gpt_hdr));
|
||||
off = hdr->hdr_lba_table * disk->sector_size;
|
||||
if (lseek(fd, off, SEEK_SET) != off ||
|
||||
read(fd, buffer, sz) != sz) {
|
||||
error = (errno) ? errno : EAGAIN;
|
||||
goto bail;
|
||||
}
|
||||
memcpy(tbl, buffer, sizeof(struct gpt_ent) * disk->gpt_size);
|
||||
off = hdr->hdr_lba_alt * disk->sector_size;
|
||||
if (lseek(fd, off, SEEK_SET) != off ||
|
||||
read(fd, buffer, disk->sector_size) != disk->sector_size) {
|
||||
error = (errno) ? errno : EAGAIN;
|
||||
goto bail;
|
||||
}
|
||||
memcpy(&hdr[1], buffer, sizeof(struct gpt_hdr));
|
||||
|
||||
bail:
|
||||
free(buffer);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
update_gpt(int fd, const struct disk *disk, struct gpt_hdr *hdr,
|
||||
struct gpt_ent *tbl)
|
||||
{
|
||||
struct gpt_ent *save;
|
||||
char *buffer;
|
||||
struct chunk *c;
|
||||
off_t off;
|
||||
size_t bufsz;
|
||||
int error, idx, sav;
|
||||
|
||||
error = 0;
|
||||
|
||||
/*
|
||||
* Save the entries of those chunks that have an index. They are
|
||||
* the ones that exist on disk already.
|
||||
*/
|
||||
sav = 0;
|
||||
for (c = disk->chunks->part; c != NULL; c = c->next) {
|
||||
if ((c->flags & CHUNK_HAS_INDEX))
|
||||
sav++;
|
||||
}
|
||||
if (sav > 0) {
|
||||
save = malloc(sav * sizeof(struct gpt_ent));
|
||||
if (save == NULL)
|
||||
abort();
|
||||
sav = 0;
|
||||
for (c = disk->chunks->part; c != NULL; c = c->next) {
|
||||
if ((c->flags & CHUNK_HAS_INDEX)) {
|
||||
idx = CHUNK_FTOI(c->flags);
|
||||
save[sav] = tbl[idx];
|
||||
c->flags ^= CHUNK_ITOF(idx);
|
||||
c->flags |= CHUNK_ITOF(sav);
|
||||
sav++;
|
||||
}
|
||||
}
|
||||
} else
|
||||
save = NULL;
|
||||
|
||||
/*
|
||||
* Clear the table entries.
|
||||
*/
|
||||
for (idx = 0; idx < disk->gpt_size; idx++) {
|
||||
uuid_create_nil(&tbl[idx].ent_type, NULL);
|
||||
tbl[idx].ent_lba_start = 0;
|
||||
tbl[idx].ent_lba_end = 0;
|
||||
tbl[idx].ent_attr = 0;
|
||||
bzero(tbl[idx].ent_name, sizeof(tbl[idx].ent_name));
|
||||
}
|
||||
|
||||
/*
|
||||
* Repopulate the table from the chunks, possibly using saved
|
||||
* information.
|
||||
*/
|
||||
idx = 0;
|
||||
for (c = disk->chunks->part; c != NULL; c = c->next) {
|
||||
if (!(c->flags & CHUNK_HAS_INDEX)) {
|
||||
switch (c->type) {
|
||||
case freebsd:
|
||||
tbl[idx].ent_type = _fbsd;
|
||||
break;
|
||||
case efi:
|
||||
tbl[idx].ent_type = _efi;
|
||||
break;
|
||||
case part:
|
||||
switch (c->subtype) {
|
||||
case FS_SWAP:
|
||||
tbl[idx].ent_type = _swap;
|
||||
break;
|
||||
case FS_BSDFFS:
|
||||
tbl[idx].ent_type = _ufs;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
} else {
|
||||
sav = CHUNK_FTOI(c->flags);
|
||||
tbl[idx].ent_type = save[sav].ent_type;
|
||||
memcpy(tbl[idx].ent_name, save[sav].ent_name,
|
||||
sizeof(tbl[idx].ent_name));
|
||||
}
|
||||
tbl[idx].ent_lba_start = c->offset;
|
||||
tbl[idx].ent_lba_end = c->end;
|
||||
|
||||
idx++;
|
||||
if (idx == disk->gpt_size)
|
||||
return (ENOSPC);
|
||||
}
|
||||
if (save != NULL)
|
||||
free(save);
|
||||
|
||||
hdr[0].hdr_crc_table = crc32(tbl,
|
||||
disk->gpt_size * sizeof(struct gpt_ent));
|
||||
hdr[0].hdr_crc_self = 0;
|
||||
hdr[0].hdr_crc_self = crc32(&hdr[0], hdr[0].hdr_size);
|
||||
|
||||
hdr[1].hdr_crc_table = hdr[0].hdr_crc_table;
|
||||
hdr[1].hdr_crc_self = 0;
|
||||
hdr[1].hdr_crc_self = crc32(&hdr[1], hdr[1].hdr_size);
|
||||
|
||||
/*
|
||||
* Write the new GPT back to the disk.
|
||||
*/
|
||||
bufsz = disk->gpt_size * sizeof(struct gpt_ent);
|
||||
if (bufsz == 0 || bufsz % disk->sector_size)
|
||||
bufsz += disk->sector_size;
|
||||
bufsz = (bufsz / disk->sector_size) * disk->sector_size;
|
||||
buffer = calloc(1, bufsz);
|
||||
|
||||
memcpy(buffer, &hdr[0], sizeof(struct gpt_hdr));
|
||||
off = hdr[0].hdr_lba_self * disk->sector_size;
|
||||
if (lseek(fd, off, SEEK_SET) != off ||
|
||||
write(fd, buffer, disk->sector_size) != disk->sector_size) {
|
||||
error = (errno) ? errno : EAGAIN;
|
||||
goto bail;
|
||||
}
|
||||
memcpy(buffer, &hdr[1], sizeof(struct gpt_hdr));
|
||||
off = hdr[1].hdr_lba_self * disk->sector_size;
|
||||
if (lseek(fd, off, SEEK_SET) != off ||
|
||||
write(fd, buffer, disk->sector_size) != disk->sector_size) {
|
||||
error = (errno) ? errno : EAGAIN;
|
||||
goto bail;
|
||||
}
|
||||
memcpy(buffer, tbl, disk->gpt_size * sizeof(struct gpt_ent));
|
||||
off = hdr[0].hdr_lba_table * disk->sector_size;
|
||||
if (lseek(fd, off, SEEK_SET) != off ||
|
||||
write(fd, buffer, bufsz) != bufsz) {
|
||||
error = (errno) ? errno : EAGAIN;
|
||||
goto bail;
|
||||
}
|
||||
off = hdr[1].hdr_lba_table * disk->sector_size;
|
||||
if (lseek(fd, off, SEEK_SET) != off ||
|
||||
write(fd, buffer, bufsz) != bufsz) {
|
||||
error = (errno) ? errno : EAGAIN;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
free(buffer);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *disk)
|
||||
{
|
||||
char devname[64];
|
||||
struct gpt_hdr *hdr;
|
||||
struct gpt_ent *tbl;
|
||||
int error, fd;
|
||||
|
||||
hdr = malloc(sizeof(struct gpt_hdr) * 2);
|
||||
if (hdr == NULL)
|
||||
return (ENOMEM);
|
||||
tbl = malloc(sizeof(struct gpt_ent) * disk->gpt_size);
|
||||
if (tbl == NULL) {
|
||||
free(hdr);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
snprintf(devname, sizeof(devname), "%s%s", _PATH_DEV, disk->name);
|
||||
fd = open(devname, O_RDWR);
|
||||
if (fd == -1) {
|
||||
free(tbl);
|
||||
free(hdr);
|
||||
return (errno);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can always write the PMBR, because we reject disks that do not
|
||||
* have a PMBR and are not virgin.
|
||||
*/
|
||||
error = write_pmbr(fd, disk);
|
||||
if (error)
|
||||
goto bail;
|
||||
|
||||
/*
|
||||
* Read the existing GPT from disk or otherwise create one out of
|
||||
* thin air. This way we can preserve the UUIDs and the entry names
|
||||
* when updating it.
|
||||
*/
|
||||
error = read_gpt(fd, disk, hdr, tbl);
|
||||
if (error)
|
||||
goto bail;
|
||||
|
||||
/*
|
||||
* Update and write the in-memory copy of the GPT.
|
||||
*/
|
||||
error = update_gpt(fd, disk, hdr, tbl);
|
||||
|
||||
bail:
|
||||
close(fd);
|
||||
free(tbl);
|
||||
free(hdr);
|
||||
return (error);
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2006 Olivier Houchard
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *d1)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/diskpc98.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
/*
|
||||
* XXX: A lot of hardcoded 512s probably should be foo->sector_size;
|
||||
* I'm not sure which, so I leave it like it worked before. --schweikh
|
||||
*/
|
||||
static int
|
||||
Write_FreeBSD(int fd, const struct disk *new, const struct chunk *c1)
|
||||
{
|
||||
struct disklabel *dl;
|
||||
int i;
|
||||
void *p;
|
||||
u_char buf[BBSIZE];
|
||||
|
||||
for (i = 0; i < BBSIZE / 512; i++) {
|
||||
if (!(p = read_block(fd, i + c1->offset, 512)))
|
||||
return (1);
|
||||
memcpy(buf + 512 * i, p, 512);
|
||||
free(p);
|
||||
}
|
||||
if (new->boot1)
|
||||
memcpy(buf, new->boot1, 512);
|
||||
|
||||
if (new->boot2)
|
||||
memcpy(buf + 512, new->boot2, BBSIZE - 512);
|
||||
|
||||
dl = (struct disklabel *)(buf + 512 * LABELSECTOR + LABELOFFSET);
|
||||
Fill_Disklabel(dl, new, c1);
|
||||
|
||||
for (i = 0; i < BBSIZE / 512; i++)
|
||||
write_block(fd, i + c1->offset, buf + 512 * i, 512);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *d1)
|
||||
{
|
||||
int fd, i, j;
|
||||
struct chunk *c1;
|
||||
int ret = 0;
|
||||
char device[64];
|
||||
u_char *mbrblk;
|
||||
struct pc98_partition *dp, work[NDOSPART];
|
||||
int s[7];
|
||||
int PC98_EntireDisk = 0;
|
||||
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, d1->name);
|
||||
|
||||
/* XXX - for entire FreeBSD(98) */
|
||||
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
|
||||
if ((c1->type == freebsd) || (c1->offset == 0))
|
||||
device[9] = 0;
|
||||
}
|
||||
|
||||
fd = open(device, O_RDWR);
|
||||
if (fd < 0) {
|
||||
#ifdef DEBUG
|
||||
warn("open(%s) failed", device);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(s, 0, sizeof s);
|
||||
if (!(mbrblk = read_block(fd, 1, d1->sector_size))) {
|
||||
close (fd);
|
||||
return (1);
|
||||
}
|
||||
dp = (struct pc98_partition *)(mbrblk + DOSPARTOFF);
|
||||
memcpy(work, dp, sizeof work);
|
||||
dp = work;
|
||||
free(mbrblk);
|
||||
for (c1 = d1->chunks->part; c1; c1 = c1->next) {
|
||||
if (c1->type == unused)
|
||||
continue;
|
||||
if (!strcmp(c1->name, "X"))
|
||||
continue;
|
||||
j = c1->name[strlen(d1->name) + 1] - '1';
|
||||
if (j < 0 || j > 7)
|
||||
continue;
|
||||
s[j]++;
|
||||
if (c1->type == freebsd)
|
||||
ret += Write_FreeBSD(fd, d1, c1);
|
||||
|
||||
i = c1->offset;
|
||||
dp[j].dp_ssect = dp[j].dp_ipl_sct = i % d1->bios_sect;
|
||||
i -= dp[j].dp_ssect;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_shd = dp[j].dp_ipl_head = i % d1->bios_hd;
|
||||
i -= dp[j].dp_shd;
|
||||
i /= d1->bios_hd;
|
||||
dp[j].dp_scyl = dp[j].dp_ipl_cyl = i;
|
||||
#ifdef DEBUG
|
||||
printf("S:%lu = (%x/%x/%x)", c1->offset,
|
||||
dp[j].dp_scyl, dp[j].dp_shd, dp[j].dp_ssect);
|
||||
#endif
|
||||
|
||||
i = c1->end;
|
||||
#if 1
|
||||
dp[j].dp_esect = dp[j].dp_ehd = 0;
|
||||
dp[j].dp_ecyl = i / (d1->bios_sect * d1->bios_hd);
|
||||
#else
|
||||
dp[j].dp_esect = i % d1->bios_sect;
|
||||
i -= dp[j].dp_esect;
|
||||
i /= d1->bios_sect;
|
||||
dp[j].dp_ehd = i % d1->bios_hd;
|
||||
i -= dp[j].dp_ehd;
|
||||
i /= d1->bios_hd;
|
||||
dp[j].dp_ecyl = i;
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
printf(" E:%lu = (%x/%x/%x)\n", c1->end,
|
||||
dp[j].dp_ecyl, dp[j].dp_ehd, dp[j].dp_esect);
|
||||
#endif
|
||||
|
||||
dp[j].dp_mid = c1->subtype & 0xff;
|
||||
dp[j].dp_sid = c1->subtype >> 8;
|
||||
if (c1->flags & CHUNK_ACTIVE)
|
||||
dp[j].dp_mid |= 0x80;
|
||||
|
||||
strncpy(dp[j].dp_name, c1->sname, 16);
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; i < NDOSPART; i++) {
|
||||
if (!s[i])
|
||||
memset(dp + i, 0, sizeof *dp);
|
||||
}
|
||||
|
||||
if (d1->bootipl)
|
||||
write_block(fd, 0, d1->bootipl, d1->sector_size);
|
||||
|
||||
if (!(mbrblk = read_block(fd, 1, d1->sector_size))) {
|
||||
close (fd);
|
||||
return (1);
|
||||
}
|
||||
memcpy(mbrblk + DOSPARTOFF, dp, sizeof *dp * NDOSPART);
|
||||
/* XXX - for entire FreeBSD(98) */
|
||||
for (c1 = d1->chunks->part; c1; c1 = c1->next)
|
||||
if (((c1->type == freebsd) || (c1->type == fat))
|
||||
&& (c1->offset == 0))
|
||||
PC98_EntireDisk = 1;
|
||||
if (PC98_EntireDisk == 0)
|
||||
write_block(fd, 1, mbrblk, d1->sector_size);
|
||||
|
||||
if (d1->bootmenu)
|
||||
for (i = 0; i * d1->sector_size < d1->bootmenu_size; i++)
|
||||
write_block(fd, 2 + i,
|
||||
&d1->bootmenu[i * d1->sector_size],
|
||||
d1->sector_size);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Suleiman Souhlal.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <paths.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *d1)
|
||||
{
|
||||
/*
|
||||
* We don't have to write any label, so we only check that we can
|
||||
* open the disk.
|
||||
*/
|
||||
int fd;
|
||||
char device[64];
|
||||
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, d1->name);
|
||||
|
||||
fd = open(device, O_RDWR);
|
||||
if (fd < 0) {
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@FreeBSD.org> 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
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/sun_disklabel.h>
|
||||
#include <paths.h>
|
||||
#include <errno.h>
|
||||
#include "libdisk.h"
|
||||
|
||||
#include "geom_sunlabel_enc.c"
|
||||
|
||||
int
|
||||
Write_Disk(const struct disk *d1)
|
||||
{
|
||||
struct sun_disklabel *sl;
|
||||
struct chunk *c, *c1, *c2;
|
||||
int i;
|
||||
char *p;
|
||||
u_long secpercyl;
|
||||
char device[64];
|
||||
u_char buf[SUN_SIZE];
|
||||
int fd;
|
||||
|
||||
strcpy(device, _PATH_DEV);
|
||||
strcat(device, d1->name);
|
||||
|
||||
fd = open(device, O_RDWR);
|
||||
if (fd < 0) {
|
||||
warn("open(%s) failed", device);
|
||||
return (1);
|
||||
}
|
||||
|
||||
sl = calloc(sizeof *sl, 1);
|
||||
c = d1->chunks;
|
||||
c2 = c->part;
|
||||
secpercyl = d1->bios_sect * d1->bios_hd;
|
||||
sl->sl_pcylinders = c->size / secpercyl;
|
||||
sl->sl_ncylinders = c2->size / secpercyl;
|
||||
sl->sl_acylinders = sl->sl_pcylinders - sl->sl_ncylinders;
|
||||
sl->sl_magic = SUN_DKMAGIC;
|
||||
sl->sl_nsectors = d1->bios_sect;
|
||||
sl->sl_ntracks = d1->bios_hd;
|
||||
if (c->size > 4999 * 1024 * 2) {
|
||||
sprintf(sl->sl_text, "FreeBSD%luG cyl %u alt %u hd %u sec %u",
|
||||
(c->size + 1024 * 1024) / (2 * 1024 * 1024),
|
||||
sl->sl_ncylinders, sl->sl_acylinders,
|
||||
sl->sl_ntracks, sl->sl_nsectors);
|
||||
} else {
|
||||
sprintf(sl->sl_text, "FreeBSD%luM cyl %u alt %u hd %u sec %u",
|
||||
(c->size + 1024) / (2 * 1024),
|
||||
sl->sl_ncylinders, sl->sl_acylinders,
|
||||
sl->sl_ntracks, sl->sl_nsectors);
|
||||
}
|
||||
sl->sl_interleave = 1;
|
||||
sl->sl_sparespercyl = 0;
|
||||
sl->sl_rpm = 3600;
|
||||
|
||||
for (c1 = c2->part; c1 != NULL; c1 = c1->next) {
|
||||
p = c1->name;
|
||||
p += strlen(p);
|
||||
p--;
|
||||
if (*p < 'a')
|
||||
continue;
|
||||
i = *p - 'a';
|
||||
if (i >= SUN_NPART)
|
||||
continue;
|
||||
sl->sl_part[i].sdkp_cyloffset = c1->offset / secpercyl;
|
||||
sl->sl_part[i].sdkp_nsectors = c1->size;
|
||||
for (i = 1; i < 16; i++) {
|
||||
write_block(fd, c1->offset + i, d1->boot1 + (i * 512),
|
||||
512);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We need to fill in the "RAW" partition as well. Emperical data
|
||||
* seems to indicate that this covers the "obviously" visible part
|
||||
* of the disk, ie: sl->sl_ncylinders.
|
||||
*/
|
||||
sl->sl_part[SUN_RAWPART].sdkp_cyloffset = 0;
|
||||
sl->sl_part[SUN_RAWPART].sdkp_nsectors = sl->sl_ncylinders * secpercyl;
|
||||
|
||||
memset(buf, 0, sizeof buf);
|
||||
sunlabel_enc(buf, sl);
|
||||
write_block(fd, 0, buf, sizeof buf);
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
@ -45,7 +45,6 @@ LIBCURSES?= ${DESTDIR}${LIBDIR}/libcurses.a
|
||||
LIBDEVINFO?= ${DESTDIR}${LIBDIR}/libdevinfo.a
|
||||
LIBDEVSTAT?= ${DESTDIR}${LIBDIR}/libdevstat.a
|
||||
LIBDIALOG?= ${DESTDIR}${LIBDIR}/libdialog.a
|
||||
LIBDISK?= ${DESTDIR}${LIBDIR}/libdisk.a
|
||||
LIBDNS?= ${DESTDIR}${LIBDIR}/libdns.a
|
||||
LIBDTRACE?= ${DESTDIR}${LIBDIR}/libdtrace.a
|
||||
LIBDWARF?= ${DESTDIR}${LIBDIR}/libdwarf.a
|
||||
@ -54,7 +53,6 @@ LIBELF?= ${DESTDIR}${LIBDIR}/libelf.a
|
||||
LIBFETCH?= ${DESTDIR}${LIBDIR}/libfetch.a
|
||||
LIBFL?= "don't use LIBFL, use LIBL"
|
||||
LIBFORM?= ${DESTDIR}${LIBDIR}/libform.a
|
||||
LIBFTPIO?= ${DESTDIR}${LIBDIR}/libftpio.a
|
||||
LIBG2C?= ${DESTDIR}${LIBDIR}/libg2c.a
|
||||
LIBGCC?= ${DESTDIR}${LIBDIR}/libgcc.a
|
||||
LIBGCC_PIC?= ${DESTDIR}${LIBDIR}/libgcc_pic.a
|
||||
|
Loading…
x
Reference in New Issue
Block a user