menu_fdisk.c revision 589271a44eaf1e2b6b05d80b025dc8b94e009aef
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* This file contains functions that implement the fdisk menu commands.
*/
#include "global.h"
#include <errno.h>
#include <sys/resource.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#ifdef i386
#include <libfdisk.h>
#endif
#include "main.h"
#include "analyze.h"
#include "menu.h"
#include "menu_command.h"
#include "menu_defect.h"
#include "menu_partition.h"
#include "menu_fdisk.h"
#include "param.h"
#include "misc.h"
#include "label.h"
#include "startup.h"
#include "partition.h"
#include "prompts.h"
#include "checkdev.h"
#include "io.h"
#include "ctlr_scsi.h"
#include "auto_sense.h"
extern struct menu_item menu_fdisk[];
/*
* Byte swapping macros for accessing struct ipart
* to resolve little endian on Sparc.
*/
#if defined(sparc)
#else /* defined(sparc) */
#endif /* defined(sparc) */
/* Function prototypes */
#ifdef __STDC__
#if defined(sparc)
#endif /* defined(sparc) */
#else /* __STDC__ */
#if defined(sparc)
static int getbyte();
static int getlong();
#endif /* defined(sparc) */
static int get_solaris_part();
#endif /* __STDC__ */
#ifdef i386
#endif
/*
* Handling the alignment problem of struct ipart.
*/
static void
{
#if defined(sparc)
/*
* Sparc platform:
*
* little endian on Sparc since it is not
* properly aligned on Sparc.
*/
/*
* i386 platform:
*
* The fdisk table does not begin on a 4-byte boundary within
* the master boot record; so, we need to recopy its contents
* to another data structure to avoid an alignment exception.
*/
#else
#endif /* defined(sparc) */
}
/*
*/
#if defined(sparc)
static int
{
int b;
b = **bp;
return (b);
}
#ifdef DEADCODE
static int
{
int b;
*bp += 2;
return (b);
}
#endif /* DEADCODE */
static int
{
*bp += 2;
*bp += 2;
return (b);
}
#endif /* defined(sparc) */
#ifdef i386
/*
* Convert emcpowerN[a-p,p0,p1,p2,p3,p4] to emcpowerNp0 path,
* this is specific for emc powerpath driver.
*/
static void
{
char *emcp = "emcpower";
char np[MAXNAMELEN];
i++;
npt[i] = '\0';
}
#endif
/*
* Convert cn[tn]dn to cn[tn]dns2 path
*/
static void
{
char buf[MAXPATHLEN];
char np[MAXNAMELEN];
char *npt;
#ifdef i386
return;
}
#endif
/*
*/
/*
* Skip if the path is already included with sN
*/
/* If pN is found, do not include it */
*npt = '\0';
}
} else {
}
} else {
}
}
/*
* Convert cn[tn]dnsn to cn[tn]dnp0 path
*/
static void
{
char buf[MAXPATHLEN];
char np[MAXNAMELEN];
char *npt;
/*
*/
} else {
}
#ifdef i386
if (emcpower_name(np)) {
return;
}
#endif
/*
* Skip if the path is already included with pN
*/
/* If sN is found, do not include it */
*--npt = '\0';
}
} else {
}
} else {
}
}
/*
* Open file descriptor for current disk (cur_file)
* with "p0" path or cur_disk->disk_path
*/
void
open_cur_file(int mode)
{
char *dkpath;
char pbuf[MAXPATHLEN];
switch (mode) {
case FD_USE_P0_PATH:
break;
case FD_USE_CUR_DISK_PATH:
} else {
}
break;
default:
err_print("Error: Invalid mode option for opening "
"cur_file\n");
fullabort();
}
/* Close previous cur_file */
/* Open cur_file with the required path dkpath */
"Error: can't open selected disk '%s'.\n", dkpath);
fullabort();
}
}
/*
* This routine implements the 'fdisk' command. It simply runs
* the fdisk command on the current disk.
* Use of this is restricted to interactive mode only.
*/
int
c_fdisk()
{
char buf[MAXPATHLEN];
char pbuf[MAXPATHLEN];
/*
* We must be in interactive mode to use the fdisk command
*/
err_print("Fdisk command is for interactive use only!\n");
return (-1);
}
/*
* There must be a current disk type and a current disk
*/
err_print("Current Disk Type is not set.\n");
return (-1);
}
/*
* Before running the fdisk command, get file status of
* supports fixed disk partition table.
*/
"Disk does not support fixed disk partition table\n");
return (0);
}
/*
* Run the fdisk program.
*/
/*
* Open cur_file with "p0" path for accessing the fdisk table
*/
(void) open_cur_file(FD_USE_P0_PATH);
/*
* Get solaris partition information in the fdisk partition table
*/
err_print("No fdisk solaris partition found\n");
}
/*
* Restore cur_file with cur_disk->disk_path
*/
(void) open_cur_file(FD_USE_CUR_DISK_PATH);
return (0);
}
/*
* Read MBR on the disk
* if the Solaris partition has changed,
* reread the vtoc
*/
#ifdef DEADCODE
static void
{
int i;
register struct partition_info *parts;
for (i = 0; i < NDKMAP; i++) {
#if defined(_SUNOS_VTOC_16)
#endif
#if defined(_SUNOS_VTOC_16)
}
#endif
}
#if defined(_SUNOS_VTOC_16)
/*
* Adjust for the boot partitions
*/
#endif /* defined(_SUNOS_VTOC_16) */
}
#endif /* DEADCODE */
static int
{
int i;
int status;
char *mbr;
char *bootptr;
struct dk_label update_label;
#ifdef i386
#endif
/*
* We may get mbr of different size, but the first 512 bytes
* are valid information.
*/
err_print("No memory available.\n");
return (-1);
}
err_print("Cannot read fdisk partition information.\n");
return (-1);
}
#ifdef i386
(void) extpart_init(&epp);
#endif
for (i = 0; i < FD_NUMPART; i++) {
int ipc;
/* Handling the alignment problem of struct ipart */
#ifdef i386
/* We support only one extended partition per disk */
ext_part_found = 1;
&numsec);
if (rval == FDISK_SUCCESS) {
/*
* Found a solaris partition inside the
* extended partition. Update the statistics.
*/
}
found = 2;
sizeof (struct ipart));
}
continue;
}
#endif
/*
* we are interested in Solaris and EFI partition types
*/
#ifdef i386
#else
#endif
/*
* if the disk has an EFI label, nhead and nsect may
* be zero. This test protects us from FPE's, and
* format still seems to work fine
*/
}
#ifdef DEBUG
else {
err_print("Critical geometry values are zero:\n"
}
#endif /* DEBUG */
found = 1;
break;
}
}
#ifdef i386
libfdisk_fini(&epp);
#endif
if (!found) {
err_print("Solaris fdisk partition not found\n");
return (-1);
} else if (found == 1) {
/*
* Found a primary solaris partition.
* compare the previous and current Solaris partition
* but don't use bootid in determination of Solaris partition
* changes
*/
}
/* if the disk partitioning has changed - get the VTOC */
if (status) {
if (status == -1) {
i = errno;
/* Try the old ioctl DKIOCGVTOC */
if (status == -1) {
err_print("Bad ioctl DKIOCGEXTVTOC.\n");
err_print("Cannot read vtoc information.\n");
return (-1);
}
}
if (status == -1) {
err_print("Cannot read label information.\n");
return (-1);
}
/* copy vtoc information */
#if defined(_SUNOS_VTOC_16)
/*
* this is to update the slice table on x86
* we don't care about VTOC8 here
*/
for (i = 0; i < NDKMAP; i ++) {
((int)(update_label.dkl_nhead *
}
#endif /* defined(_SUNOS_VTOC_16) */
}
return (0);
}
int
{
char *mbr;
char buf[MAXPATHLEN];
char *bootptr;
#ifdef i386
#endif
((cur_label == L_TYPE_EFI) &&
/*
* Make sure to reset solaris_offset to zero if it is
* previously set by a selected disk that
* supports the fdisk table.
*/
solaris_offset = 0;
/*
* Return if this disk does not support fdisk table or
* if it uses an EFI label but has not yet been labelled.
* If the EFI label has not been written then the open
* on the partition will fail.
*/
return (0);
}
return (-1);
}
/*
* We may get mbr of different size, but the first 512 bytes
* are valid information.
*/
err_print("No memory available.\n");
return (-1);
}
err_print("Bad read of fdisk partition.\n");
return (-1);
}
#ifdef i386
(void) extpart_init(&epp);
#endif
for (i = 0; i < FD_NUMPART; i++) {
int ipc;
/* Handling the alignment problem of struct ipart */
#ifdef i386
/* We support only one extended partition per disk */
ext_part_found = 1;
&numsec);
if (rval == FDISK_SUCCESS) {
/*
* Found a solaris partition inside the
* extended partition. Update the statistics.
*/
}
}
continue;
}
#endif
#ifdef i386
#else
#endif
/*
* if the disk has an EFI label, we typically won't
* have values for nhead and nsect. format seems to
* work without them, and we need to protect ourselves
* from FPE's
*/
}
#ifdef DEBUG
else {
err_print("Critical geometry values are zero:\n"
}
#endif /* DEBUG */
break;
}
}
#ifdef i386
libfdisk_fini(&epp);
#endif
return (0);
}
#if defined(_FIRMWARE_NEEDS_FDISK)
int
{
char *mbr;
char *bootptr;
char pbuf[MAXPATHLEN];
#ifdef i386
#endif
return (-1);
}
/*
* We may get mbr of different size, but the first 512 bytes
* are valid information.
*/
err_print("No memory available.\n");
return (-1);
}
err_print("Bad read of fdisk partition.\n");
return (-1);
}
#ifdef i386
(void) extpart_init(&epp);
#endif
for (i = 0; i < FD_NUMPART; i++) {
int ipc;
/* Handling the alignment problem of struct ipart */
#ifdef i386
/* We support only one extended partition per disk */
ext_part_found = 1;
&numsec);
if (rval == FDISK_SUCCESS) {
/*
* Found a solaris partition inside the
* extended partition. Update the statistics.
*/
}
}
continue;
}
#endif
/*
* if the disk has an EFI label, the nhead and nsect fields
* the label may be zero. This protects us from FPE's, and
* format still seems to work happily
*/
#ifdef i386
#else
#endif
}
#ifdef DEBUG
else {
err_print("Critical label fields aren't "
"non-zero:\n"
"\tlabel->dkl_nhead = %d; "
"label->dkl_nsect = "
}
#endif /* DEBUG */
break;
}
}
#ifdef i386
libfdisk_fini(&epp);
#endif
return (0);
}
#endif /* defined(_FIRMWARE_NEEDS_FDISK) */
int
{
char buf[MAXPATHLEN];
cur_label == L_TYPE_EFI) {
/*
* Return if this disk does not support fdisk table or
* if the disk is labeled with EFI.
*/
return (1);
}
return (1);
} else {
err_print("WARNING - ");
err_print("This disk may be in use by an application "
"that has\n\t modified the fdisk table. Ensure "
"that this disk is\n\t not currently in use "
"before proceeding to use fdisk.\n");
return (0);
}
}
#ifdef i386
int
{
int rval, lf_op_flag = 0;
char p0_path[MAXPATHLEN];
switch (rval) {
/*
* FDISK_EBADLOGDRIVE, FDISK_ENOLOGDRIVE
* and FDISK_EBADMAGIC can be considered
* as soft errors and hence we do not exit.
*/
case FDISK_EBADLOGDRIVE:
break;
case FDISK_ENOLOGDRIVE:
break;
case FDISK_EBADMAGIC:
break;
case FDISK_ENOVGEOM:
err_print("Could not get virtual geometry for"
" this device\n");
fullabort();
break;
case FDISK_ENOPGEOM:
err_print("Could not get physical geometry for"
" this device\n");
fullabort();
break;
case FDISK_ENOLGEOM:
err_print("Could not get label geometry for "
" this device\n");
fullabort();
break;
default:
err_print("Failed to initialise libfdisk.\n");
fullabort();
break;
}
}
return (0);
}
#endif