fmthard.c revision ace1a5f11236a072fca1b5e0ea1416a083a9f2aa
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
*
* Portions of this source code were provided by International
* Computers Limited (ICL) under a development agreement with AT&T.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Sun Microsystems version of fmthard:
*
* Supports the following arguments:
*
* -i Writes VTOC to stdout, rather than disk
* -q Quick check: exit code 0 if VTOC ok
* -d <data> Incremental changes to the VTOC
* -n <vname> Change volume name to <vname>
* -s <file> Read VTOC information from <file>, or stdin ("-")
* -u <state> Reboot after writing VTOC, according to <state>:
* boot: AD_BOOT (standard reboot)
* firm: AD_IBOOT (interactive reboot)
*
* Note that fmthard cannot write a VTOC on an unlabeled disk.
* You must use format or SunInstall for this purpose.
* (NOTE: the above restriction only applies on Sparc systems).
*
* The primary motivation for fmthard is to duplicate the
* partitioning from disk to disk:
*
*/
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/isa_defs.h>
#include <sys/efi_partition.h>
#if defined(_SUNOS_VTOC_16)
#endif
#include <sys/sysmacros.h>
#ifndef SECSIZE
#endif /* SECSIZE */
/*
* External functions.
*/
extern int write_vtoc(int, struct vtoc *);
/*
* Internal functions.
*/
extern int main(int, char **);
static void usage(void);
static void validate64(struct dk_gpt *);
/*
* Static variables.
*/
static char *delta; /* Incremental update */
static short eflag; /* force write of an EFI label */
static short iflag; /* Prints VTOC w/o updating */
static short qflag; /* Check for a formatted disk */
static short uflag; /* Exit to firmware after writing */
/* new vtoc and reboot. Used during */
/* installation of core floppies */
#if defined(sparc)
static char *uboot = "boot";
/* use installgrub(1M) to install boot blocks */
static char *uboot = "";
#else
#endif /* various platform-specific definitions */
static char *ufirm = "firm";
#if defined(_SUNOS_VTOC_16)
static int sectsiz;
#endif /* defined(_SUNOS_VTOC_16) */
int
{
int fd;
int c;
char *dfile;
char *vname;
#if defined(_SUNOS_VTOC_8)
#endif /* defined(_SUNOS_VTOC_8) */
int n;
#if defined(sparc)
#else
#endif
switch (c) {
#if defined(i386)
case 'p':
case 'b':
"fmthard: -p and -b no longer supported."
" Use installgrub(1M) to install boot blocks\n");
break;
#endif /* defined(i386) */
case 'd':
break;
case 'e':
++eflag;
break;
case 'i':
++iflag;
break;
case 'n':
break;
case 'q':
++qflag;
break;
case 's':
break;
case 'u':
++uflag;
uflag = 2;
break;
default:
usage();
}
usage();
"fmthard: Cannot stat device %s\n",
exit(1);
}
"fmthard: %s must be a raw device.\n",
exit(1);
}
exit(1);
}
/*
* Get the geometry information for this disk from the driver
*/
#ifdef DEBUG
perror("DKIOCGGEOM failed");
#endif /* DEBUG */
/* disk has EFI labels */
eflag++;
} else {
exit(1);
}
}
/*
* Read the vtoc on the disk
*/
if (!eflag) {
eflag++;
}
}
/*
* Quick check for valid disk: 0 if ok, 1 if not
*/
if (qflag) {
if (!eflag) {
} else {
}
}
/*
* Incremental changes to the VTOC
*/
if (delta) {
if (!eflag) {
} else {
}
exit(0);
}
usage();
/*
* Read new VTOC from stdin or data file
*/
if (dfile) {
if (!eflag)
else
} else {
dfile);
exit(1);
}
if (!eflag)
else
}
}
/*
* Print the modified VTOC, rather than updating the disk
*/
if (iflag) {
if (!eflag)
else
exit(0);
}
if (vname) {
if (!eflag) {
} else {
for (c = 0; c < disk_efi->efi_nparts; c++) {
V_RESERVED) {
vname, n);
}
}
}
}
/*
* Write the new VTOC on the disk
*/
if (!eflag) {
} else {
}
/*
* Shut system down after writing a new vtoc to disk
* This is used during installation of core floppies.
*/
if (uflag == 1)
else if (uflag == 2)
(void) printf("fmthard: New volume table of contents now in place.\n");
return (0);
/*NOTREACHED*/
}
/*
* display ()
*
* display contents of VTOC without writing it to disk
*/
static void
{
int i;
int c;
/*
* Print out the VTOC
*/
(void) printf("* Volume Name: ");
for (i = 0; i < LEN_DKL_VVOL; i++) {
break;
(void) printf("%c", c);
}
(void) printf("\n");
}
(void) printf("*\n");
(void) printf("* Dimensions:\n");
(void) printf("*\n");
(void) printf("* Flags:\n");
(void) printf("* 1: unmountable\n");
(void) printf("* 10: read-only\n");
(void) printf("*\n");
(void) printf(
"\n* Partition Tag Flag First Sector Sector Count\n");
for (i = 0; i < V_NUMPAR; i++) {
(void) printf(
" %d %d 0%x %ld %ld\n",
}
exit(0);
}
/*
* display64 ()
*
* display64 contents of EFI partition without writing it to disk
*/
static void
{
int i;
/*
* Print out the VTOC
*/
(void) printf("*\n");
(void) printf("* Dimensions:\n");
(void) printf("* N/A cylinders\n");
(void) printf("* N/A accessible cylinders\n");
(void) printf("*\n");
(void) printf("* Flags:\n");
(void) printf("* 1: unmountable\n");
(void) printf("* 10: read-only\n");
(void) printf("*\n");
(void) printf(
"\n* Partition Tag Flag First Sector Sector Count\n");
for (i = 0; i < efi->efi_nparts; i++) {
(void) printf(
" %d %d 0%x %8lld %8lld\n",
}
exit(0);
}
/*
* insert()
*
* Insert a change into the VTOC.
*/
static void
{
int part;
int tag;
long size;
exit(1);
}
"Error in data \"%s\": No such partition %x\n",
exit(1);
}
}
/*
* insert64()
*
* Insert a change into the VTOC.
*/
static void
{
int part;
int tag;
exit(1);
}
"Error in data \"%s\": No such partition %x\n",
exit(1);
}
}
/*
* load()
*
* Load VTOC information from a datafile.
*/
static void
{
int part;
int tag;
long size;
char line[256];
int i;
long nblks;
long fullsz;
for (i = 0; i < V_NUMPAR; ++i) {
}
/*
* initialize partition 2, by convention it corresponds to whole
* disk. It will be overwritten, if specified in the input datafile
*/
continue;
line);
exit(1);
}
"No such partition %x: \"%s\"\n",
exit(1);
}
"Partition %d not aligned on cylinder boundary: \"%s\"\n",
exit(1);
}
}
}
}
/*
* load64()
*
* Load VTOC information from a datafile.
*/
static void
{
int part;
int tag;
int nlines = 0;
char line[256];
int i;
continue;
line);
exit(1);
}
exit(1);
}
exit(1);
}
nlines++;
}
max_part++;
"efi_alloc_and_init failed: %d\n", i);
exit(1);
}
for (i = 0; i < (*efi)->efi_nparts; ++i) {
}
for (i = 0; i < nlines; i++) {
line);
exit(1);
}
"No such partition %x: \"%s\"\n",
exit(1);
}
}
}
static void
usage()
{
#if defined(sparc)
"Usage: fmthard [ -i ] [ -n volumename ] [ -s datafile ] [ -d arguments] \
raw-device\n");
"Usage: fmthard [ -i ] [ -S ] [-I geom_file] \
-n volumename | -s datafile [ -d arguments] raw-device\n");
#else
#endif
exit(2);
}
/*
* validate()
*
* Validate the new VTOC.
*/
static void
{
int i;
int j;
long fullsz;
long endsect;
long isize;
long jsize;
long nblks;
#if defined(_SUNOS_VTOC_16)
/* make the vtoc look sane - ha ha */
if (sectsiz == 0)
if (vtoc->v_sectorsz == 0)
#endif /* defined(_SUNOS_VTOC_16) */
for (i = 0; i < V_NUMPAR; i++) {
fmthard: Partition %d specifies the full disk and is not equal\n\
full size of disk. The full disk capacity is %lu sectors.\n", i, fullsz);
#if defined(sparc)
exit(1);
#endif
}
}
continue; /* Undefined partition */
fmthard: Partition %d not aligned on cylinder boundary \n", i);
exit(1);
}
fmthard: Partition %d specified as %lu sectors starting at %lu\n\
\tdoes not fit. The full disk contains %lu sectors.\n",
#if defined(sparc)
exit(1);
#endif
}
for (j = 0; j < V_NUMPAR; j++) {
continue;
continue;
if ((i != j) &&
fmthard: Partition %d overlaps partition %d. Overlap is allowed\n\
\tonly on partition on the full disk partition).\n",
i, j);
#if defined(sparc)
exit(1);
#endif
}
}
}
}
}
}
/*
* validate64()
*
* Validate the new VTOC.
*/
static void
{
int i;
int j;
int resv_part = 0;
for (i = 0; i < efi->efi_nparts; i++) {
continue; /* Undefined partition */
resv_part++;
fmthard: Partition %d specified as %lld sectors starting at %lld\n\
\tdoes not fit. The full disk contains %lld sectors.\n",
exit(1);
}
for (j = 0; j < V_NUMPAR; j++) {
continue;
if ((i != j) &&
fmthard: Partition %d overlaps partition %d. Overlap is allowed\n\
\tonly on partition on the full disk partition).\n",
i, j);
#if defined(sparc)
exit(1);
#endif
}
}
}
}
}
if (resv_part != 1) {
"expected one reserved partition, but found %d\n",
exit(1);
}
}
/*
* Read the VTOC
*/
int
{
int i;
if (i == VT_ENOTSUP) {
return (1);
}
if (i == VT_EINVAL) {
devname);
} else {
devname);
}
exit(1);
}
return (0);
}
void
{
int i;
if (i == VT_EINVAL)
"%s: this disk must be labeled first\n",
devname);
else
"%s: read_efi failed %d\n",
devname, i);
exit(1);
}
}
/*
* Write the VTOC
*/
void
{
int i;
if (i == VT_EINVAL) {
"%s: invalid entry exists in vtoc\n",
devname);
} else {
devname);
}
exit(1);
}
}
/*
* Write the VTOC
*/
void
{
int i;
if (i == VT_EINVAL) {
"%s: invalid entry exists in vtoc\n",
devname);
} else {
devname);
}
exit(1);
}
}