Files
Arquivotheca.Solaris-2.5/cmd/format/modify_partition.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

404 lines
8.6 KiB
C
Executable File

#ifndef lint
#pragma ident "@(#)modify_partition.c 1.12 95/04/10 SMI"
#endif lint
/*
* Copyright (c) 1991 by Sun Microsystems, Inc.
*/
/*
* This file contains functions to implement the partition menu commands.
*/
#include "global.h"
#include "partition.h"
#include "menu_partition.h"
#include "menu_command.h"
#include "modify_partition.h"
#include "checkmount.h"
#include "misc.h"
#include "label.h"
#include <stdlib.h>
#include <string.h>
char *partn_list[] = { "0", "1", "2", "3", "4", "5", "6", "7", NULL };
char *sel_list[] = { "0", "1", "2", "3", NULL };
/*
* Mnemonics for the partitions we recognize
*/
#define A_PARTITION 0
#define B_PARTITION 1
#define C_PARTITION 2
#define D_PARTITION 3
#define E_PARTITION 4
#define F_PARTITION 5
#define G_PARTITION 6
#define H_PARTITION 7
#define I_PARTITION 8
#define J_PARTITION 9
#define MBYTE (1024*1024)
/*
* Modify/Create a predefined partition table.
*/
int
p_modify()
{
struct partition_info tmp_pinfo[1];
struct dk_map *map = tmp_pinfo->pinfo_map;
u_ioparam_t ioparam;
int inpt_dflt = 0;
int free_hog = -1;
int i;
char tmpstr[80];
char tmpstr2[300];
int sel_type = 0;
/*
* There must be a current disk type (and therefore a current disk).
*/
if (cur_dtype == NULL) {
err_print("Current Disk Type is not set.\n");
return (-1);
}
/*
* If the disk has mounted partitions, cannot modify
*/
if (checkmount((daddr_t)-1, (daddr_t)-1)) {
err_print(
"Cannot modify disk partitions while it has mounted partitions.\n\n");
return (-1);
}
/*
* prompt user for a partition table base
*/
if (cur_parts->pinfo_name != NULL) {
(void) sprintf(tmpstr,
"\t0. Current partition table (%s)",
cur_parts->pinfo_name);
} else {
(void) sprintf(tmpstr,
"\t0. Current partition table (unnamed)");
}
(void) sprintf(tmpstr2,
"Select partitioning base:\n%s\n"
"\t1. All Free Hog\n"
"Choose base (enter number) ",
tmpstr);
ioparam.io_charlist = sel_list;
sel_type = input(FIO_MSTR, tmpstr2, '?', &ioparam,
&sel_type, DATA_INPUT);
if (sel_type == 0) {
/*
* Check for invalid parameters but do
* not modify the table.
*/
if (check_map(cur_parts->pinfo_map)) {
err_print("\
Warning: Fix, or select a different partition table.\n");
return (0);
}
/*
* Create partition map from existing map
*/
tmp_pinfo->vtoc = cur_parts->vtoc;
for (i = 0; i < NDKMAP; i++) {
map[i].dkl_nblk = cur_parts->pinfo_map[i].dkl_nblk;
map[i].dkl_cylno = cur_parts->pinfo_map[i].dkl_cylno;
}
} else {
/*
* Make an empty partition map, with all the space
* in the c partition.
*/
set_vtoc_defaults(tmp_pinfo);
for (i = 0; i < NDKMAP; i++) {
map[i].dkl_nblk = 0;
map[i].dkl_cylno = 0;
}
map[C_PARTITION].dkl_nblk = ncyl * spc();
#ifdef i386
/*
* Adjust for the boot and possibly alternates partitions
*/
map[I_PARTITION].dkl_nblk = spc();
map[I_PARTITION].dkl_cylno = 0;
if (cur_ctype->ctype_ctype != DKC_SCSI_CCS) {
map[J_PARTITION].dkl_nblk = 2 * spc();
map[J_PARTITION].dkl_cylno = spc() / spc();
}
#endif
}
fmt_print("\n");
print_map(tmp_pinfo);
ioparam.io_charlist = confirm_list;
if (input(FIO_MSTR,
"Do you wish to continue creating a new partition\ntable based on above table",
'?', &ioparam, &inpt_dflt, DATA_INPUT)) {
return (0);
}
/*
* get Free Hog partition
*/
inpt_dflt = 1;
while (free_hog < 0) {
free_hog = G_PARTITION; /* default to g partition */
ioparam.io_charlist = partn_list;
free_hog = input(FIO_MSTR, "Free Hog partition", '?',
&ioparam, &free_hog, DATA_INPUT);
/* disallow c partition */
if (free_hog == C_PARTITION) {
fmt_print("'%c' cannot be the 'Free Hog' partition.\n",
C_PARTITION + PARTITION_BASE);
free_hog = -1;
continue;
}
/*
* If user selected all float set the
* float to be the whole disk.
*/
if (sel_type == 1) {
map[free_hog].dkl_nblk = map[C_PARTITION].dkl_nblk;
#ifdef i386
map[free_hog].dkl_nblk -= map[I_PARTITION].dkl_nblk;
if (cur_ctype->ctype_ctype != DKC_SCSI_CCS) {
map[free_hog].dkl_nblk -=
map[J_PARTITION].dkl_nblk;
}
#endif
break;
}
/*
* Warn the user if there is no free space in
* the float partition.
*/
if (map[free_hog].dkl_nblk == 0) {
err_print("\
Warning: No space available from Free Hog partition.\n");
ioparam.io_charlist = confirm_list;
if (input(FIO_MSTR, "Continue", '?',
&ioparam, &inpt_dflt, DATA_INPUT)) {
free_hog = -1;
}
}
}
inpt_dflt = 0;
/*
* get user modified partition table
*/
get_user_map(map, free_hog);
/*
* Update cylno offsets
*/
adj_cyl_offset(map);
fmt_print("\n");
print_map(tmp_pinfo);
ioparam.io_charlist = confirm_list;
if (input(FIO_MSTR, "\
Okay to make this the current partition table", '?',
&ioparam, &inpt_dflt, DATA_INPUT)) {
return (0);
} else {
make_partition();
/*
* Update new partition map
*/
for (i = 0; i < NDKMAP; i++) {
cur_parts->pinfo_map[i].dkl_nblk = map[i].dkl_nblk;
cur_parts->pinfo_map[i].dkl_cylno = map[i].dkl_cylno;
#ifdef i386
cur_parts->vtoc.v_part[i].p_start =
map[i].dkl_cylno * nhead * nsect;
cur_parts->vtoc.v_part[i].p_size =
map[i].dkl_nblk;
#endif
}
(void) p_name();
/*
* Label the disk now
*/
if (check("Ready to label disk, continue")) {
return (-1);
}
fmt_print("\n");
if (write_label()) {
err_print("Writing label failed\n");
return (-1);
}
return (0);
}
}
/*
* Adjust cylinder offsets
*/
void
adj_cyl_offset(map)
struct dk_map *map;
{
int i;
int cyloffset = 0;
/*
* Update cylno offsets
*/
#ifdef i386
/*
* Correct cylinder allocation for having the boot and alternates
* slice in the beginning of the disk
*/
for (i = NDKMAP/2; i < NDKMAP; i++) {
if (i != C_PARTITION && map[i].dkl_nblk) {
map[i].dkl_cylno = cyloffset;
cyloffset += (map[i].dkl_nblk + (spc()-1))/spc();
} else if (map[i].dkl_nblk == 0) {
map[i].dkl_cylno = 0;
}
}
for (i = 0; i < NDKMAP/2; i++) {
#else
for (i = 0; i < NDKMAP; i++) {
#endif
if (i != C_PARTITION && map[i].dkl_nblk) {
map[i].dkl_cylno = cyloffset;
cyloffset += (map[i].dkl_nblk + (spc()-1))/spc();
} else if (map[i].dkl_nblk == 0) {
map[i].dkl_cylno = 0;
}
}
}
/*
* Check partition table
*/
int
check_map(map)
struct dk_map *map;
{
int i;
int cyloffset = 0;
int tot_blks = 0;
#ifdef i386
/*
* On x86, we must account for the boot and alternates
*/
cyloffset = map[0].dkl_cylno;
tot_blks = map[0].dkl_nblk;
#endif
/*
* Do some checks for invalid parameters but do
* not modify the table.
*/
for (i = 0; i < NDKMAP; i++) {
if (map[i].dkl_cylno < 0 ||
map[i].dkl_cylno > (daddr_t)ncyl-1) {
err_print("\
Warning: Partition %c starting cylinder %d is out of range.\n",
(PARTITION_BASE+i), map[i].dkl_cylno);
return (-1);
}
if (map[i].dkl_nblk < 0 || map[i].dkl_nblk > (daddr_t)(ncyl -
map[i].dkl_cylno) * spc()) {
err_print("\
Warning: Partition %c, specified # of blocks, %d, is out of range.\n",
(PARTITION_BASE+i), map[i].dkl_nblk);
return (-1);
}
if (i != C_PARTITION && map[i].dkl_nblk) {
#ifdef i386
if (i == I_PARTITION || i == J_PARTITION)
continue;
#endif
if (map[i].dkl_cylno < cyloffset) {
err_print(
"Warning: Overlapping partition (%c) in table.\n", PARTITION_BASE+i);
return (-1);
} else if (map[i].dkl_cylno > cyloffset) {
err_print(
"Warning: Non-contiguous partition (%c) in table.\n", PARTITION_BASE+i);
}
cyloffset += (map[i].dkl_nblk + (spc()-1))/spc();
tot_blks = map[i].dkl_nblk;
}
}
if (tot_blks > map[C_PARTITION].dkl_nblk) {
err_print("\
Warning: Total blocks used is greater than number of blocks in '%c'\n\
\tpartition.\n", C_PARTITION + PARTITION_BASE);
return (-1);
}
return (0);
}
/*
* get user defined partitions
*/
void
get_user_map(map, float_part)
struct dk_map *map;
int float_part;
{
int i;
int newsize;
int deflt;
char tmpstr[80];
u_ioparam_t ioparam;
/*
* Get partition sizes
*/
for (i = 0; i < NDKMAP; i++) {
if (partn_list[i] == NULL)
break;
if ((i == C_PARTITION) || (i == float_part))
continue;
else {
ioparam.io_bounds.lower = 0;
ioparam.io_bounds.upper = map[i].dkl_nblk +
map[float_part].dkl_nblk;
deflt = map[i].dkl_nblk;
if (ioparam.io_bounds.upper == 0) {
err_print("\
Warning: no space available for '%s' from Free Hog partition\n",
partn_list[i]);
continue;
}
(void) sprintf(tmpstr,
"Enter size of partition '%s' ",
partn_list[i]);
newsize = input(FIO_CYL, tmpstr, ':',
&ioparam, &deflt, DATA_INPUT);
map[float_part].dkl_nblk -= (newsize - map[i].dkl_nblk);
map[i].dkl_nblk = newsize;
}
}
}