installboot: allow installation into disk
Previously, installboot would require that the given target device is a partition. This is not strictly necessary: MINIX3 can also be installed (manually) into one or more primary partitions, requiring that the installboot target be the entire disk. With this patch, specifying a disk as target is now allowed, as long as the -f (force) option is given.
This commit is contained in:
parent
c3ae1bdfcd
commit
16440d9b8f
3 changed files with 77 additions and 52 deletions
|
@ -245,13 +245,13 @@ main(int argc, char *argv[])
|
|||
mode = O_RDWR;
|
||||
}
|
||||
|
||||
if (minixfs3_is_minix_partition(params->filesystem)) {
|
||||
if (minixfs3_is_minix_partition(params)) {
|
||||
/* Old setups has just 1 sector for bootblock,
|
||||
* but bootxx_minixfs is ~8Kb, so we require new setups
|
||||
* to have 32 sectors before the first subpartition.
|
||||
* This prevents from overwriting FS on old setups.
|
||||
*/
|
||||
if (!minixfs3_has_bootblock_space(params->filesystem)) {
|
||||
if (!minixfs3_has_bootblock_space(params)) {
|
||||
err(1, "No space for bootxx, you should have 32 sectors"
|
||||
" before the first subpartition on %s",
|
||||
params->filesystem);
|
||||
|
|
|
@ -166,8 +166,8 @@ void install_master(const char *device, char *masterboot, char **guide);
|
|||
int isoption(const char *option, const char *test);
|
||||
|
||||
/* minixfs3.c */
|
||||
int minixfs3_is_minix_partition(const char* partition);
|
||||
int minixfs3_has_bootblock_space(const char* partition);
|
||||
int minixfs3_is_minix_partition(ib_params *params);
|
||||
int minixfs3_has_bootblock_space(ib_params *params);
|
||||
|
||||
|
||||
/* machines.c */
|
||||
|
@ -178,9 +178,6 @@ extern struct ib_mach ib_mach_ews4800mips;
|
|||
extern struct ib_mach ib_mach_hp300;
|
||||
extern struct ib_mach ib_mach_hp700;
|
||||
extern struct ib_mach ib_mach_i386;
|
||||
#ifdef __minix
|
||||
extern struct ib_mach ib_mach_i386;
|
||||
#endif
|
||||
extern struct ib_mach ib_mach_landisk;
|
||||
extern struct ib_mach ib_mach_macppc;
|
||||
extern struct ib_mach ib_mach_news68k;
|
||||
|
|
|
@ -16,7 +16,14 @@
|
|||
|
||||
#define MFS_FIRST_SUBP_OFFSET 32
|
||||
|
||||
static int minixfs3_read_mbr(const char* device, char* buf)
|
||||
enum {
|
||||
TYPE_BAD,
|
||||
TYPE_PART,
|
||||
TYPE_DISK
|
||||
};
|
||||
|
||||
static int
|
||||
minixfs3_read_mbr(const char* device, char* buf)
|
||||
{
|
||||
int fd;
|
||||
int bytes;
|
||||
|
@ -56,30 +63,48 @@ static int minixfs3_read_mbr(const char* device, char* buf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
minixfs3_get_dev_type(const char *device, ib_params *params)
|
||||
{
|
||||
int len, type;
|
||||
|
||||
int minixfs3_is_minix_partition(const char* partition)
|
||||
/*
|
||||
* Unless the -f flag is given, we expect to be provided with a primary
|
||||
* partition. That is, a device name that ends with "pN", N being 0-3.
|
||||
* If the -f flag is given, we assume that anything else is a whole
|
||||
* disk. If we were given a subpartition, it will fail the subsequent
|
||||
* MBR signature test, so we need not check this explicitly.
|
||||
*/
|
||||
len = strlen(device);
|
||||
|
||||
if (len > 2 && device[len-2] == 'p' &&
|
||||
(unsigned) (device[len-1] - '0') <= 3) {
|
||||
type = TYPE_PART;
|
||||
} else {
|
||||
type = TYPE_DISK;
|
||||
}
|
||||
|
||||
if (type != TYPE_PART && !(params->flags & IB_FORCE)) {
|
||||
fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
|
||||
device);
|
||||
return TYPE_BAD;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
int
|
||||
minixfs3_is_minix_partition(ib_params *params)
|
||||
{
|
||||
char buf[DFL_SECSIZE]; /* part table + signature */
|
||||
int name_length = strlen(partition);
|
||||
|
||||
/* partition must be 0-3 */
|
||||
if (atol(&partition[name_length-1]) >= 4) {
|
||||
fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
|
||||
partition);
|
||||
if (minixfs3_get_dev_type(params->filesystem, params) == TYPE_BAD)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* it should be partition device, not disk */
|
||||
if (partition[name_length-2] != 'p') {
|
||||
fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
|
||||
partition);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MINIX 3 partition with current scheme *must* have subpartitions,
|
||||
* thus MBR has signature. minixfs3_read_mbr checks the signature.
|
||||
*/
|
||||
if (minixfs3_read_mbr(partition, buf))
|
||||
if (minixfs3_read_mbr(params->filesystem, buf))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -89,52 +114,55 @@ int minixfs3_is_minix_partition(const char* partition)
|
|||
* to install bootxx_minixfs3. New installation should have 16Kb before
|
||||
* the first subpartition.
|
||||
*/
|
||||
int minixfs3_has_bootblock_space(const char* partition)
|
||||
int
|
||||
minixfs3_has_bootblock_space(ib_params *params)
|
||||
{
|
||||
const char *device;
|
||||
char buf[DFL_SECSIZE]; /* part table + signature */
|
||||
char disk[NAME_MAX];
|
||||
char parent_name[NAME_MAX];
|
||||
struct mbr_partition *part;
|
||||
uint32_t first_subpartition = (uint32_t) ~0;
|
||||
uint32_t parent_partition = 0;
|
||||
int i;
|
||||
int name_length = strlen(partition);
|
||||
uint32_t parent_partition;
|
||||
int i, len, type = 0;
|
||||
|
||||
/* partition must be 0-3 */
|
||||
if (atol(&partition[name_length-1]) >= 4) {
|
||||
fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
|
||||
partition);
|
||||
exit(1);
|
||||
}
|
||||
/* it should be partition device, not disk */
|
||||
if (partition[name_length-2] != 'p') {
|
||||
fprintf(stderr, "Wrong device %s, must be /.../cxdyp[0-3]\n",
|
||||
partition);
|
||||
exit(1);
|
||||
}
|
||||
device = params->filesystem;
|
||||
|
||||
if (minixfs3_read_mbr(partition, buf))
|
||||
if ((type = minixfs3_get_dev_type(device, params)) == TYPE_BAD)
|
||||
exit(1);
|
||||
|
||||
if (minixfs3_read_mbr(device, buf))
|
||||
exit(1);
|
||||
|
||||
part = (struct mbr_partition *) buf;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (part[i].mbrp_size && part[i].mbrp_start < first_subpartition)
|
||||
if (part[i].mbrp_size &&
|
||||
part[i].mbrp_start < first_subpartition)
|
||||
first_subpartition = part[i].mbrp_start;
|
||||
}
|
||||
|
||||
strncpy(disk, partition, name_length - 2);
|
||||
disk[name_length - 2] = '\0';
|
||||
if (type == TYPE_PART) {
|
||||
/* The target is a partition. Look up its starting offset. */
|
||||
len = strlen(device);
|
||||
strncpy(parent_name, device, len - 2);
|
||||
parent_name[len - 2] = '\0';
|
||||
|
||||
if (minixfs3_read_mbr(disk, buf))
|
||||
exit(1);
|
||||
if (minixfs3_read_mbr(parent_name, buf))
|
||||
exit(1);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct mbr_partition *p = &part[i];
|
||||
if (p->mbrp_size && p->mbrp_start <= first_subpartition
|
||||
&& (p->mbrp_start + p->mbrp_size) > first_subpartition) {
|
||||
parent_partition = p->mbrp_start;
|
||||
break;
|
||||
parent_partition = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct mbr_partition *p = &part[i];
|
||||
if (p->mbrp_size && p->mbrp_start <= first_subpartition
|
||||
&& (p->mbrp_start + p->mbrp_size) >
|
||||
first_subpartition) {
|
||||
parent_partition = p->mbrp_start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* The target is a whole disk. The starting offset is 0. */
|
||||
parent_partition = 0;
|
||||
}
|
||||
|
||||
if ((first_subpartition - parent_partition) < MFS_FIRST_SUBP_OFFSET)
|
||||
|
|
Loading…
Reference in a new issue