1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * rmf_slice.c : 31*7c478bd9Sstevel@tonic-gate * This file contains the functions for parsing a slice file 32*7c478bd9Sstevel@tonic-gate * for rmformat. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 36*7c478bd9Sstevel@tonic-gate #include <ctype.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 38*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 39*7c478bd9Sstevel@tonic-gate #include <unistd.h> 40*7c478bd9Sstevel@tonic-gate #include <string.h> 41*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 42*7c478bd9Sstevel@tonic-gate #include <errno.h> 43*7c478bd9Sstevel@tonic-gate #include <memory.h> 44*7c478bd9Sstevel@tonic-gate #include <dirent.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 47*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 48*7c478bd9Sstevel@tonic-gate #include <stdio.h> 49*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 50*7c478bd9Sstevel@tonic-gate #include <priv.h> 51*7c478bd9Sstevel@tonic-gate #include "rmformat.h" 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate extern void my_perror(char *err_string); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate static int32_t last_token_type = 0; 56*7c478bd9Sstevel@tonic-gate #define spc() (last_token_type) 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate /* 60*7c478bd9Sstevel@tonic-gate * This global is used to store the current line # in the 61*7c478bd9Sstevel@tonic-gate * data file. It must be global because the I/O routines 62*7c478bd9Sstevel@tonic-gate * are allowed to side effect it to keep track of backslashed 63*7c478bd9Sstevel@tonic-gate * newlines. 64*7c478bd9Sstevel@tonic-gate */ 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate static int32_t data_lineno; /* current line # in data file */ 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate #define CHG_MODE_UNDEFINED (-1) /* undefined value */ 69*7c478bd9Sstevel@tonic-gate #define CHG_MODE_SET 0 /* set bits by or'ing */ 70*7c478bd9Sstevel@tonic-gate #define CHG_MODE_CLR 1 /* clr bits by and'ing */ 71*7c478bd9Sstevel@tonic-gate #define CHG_MODE_ABS 2 /* set absolute value */ 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate #define TOKEN_SIZE 36 /* max length of a token */ 75*7c478bd9Sstevel@tonic-gate typedef char TOKEN[TOKEN_SIZE+1]; /* token type */ 76*7c478bd9Sstevel@tonic-gate #define DATA_INPUT 0 /* 2 modes of input */ 77*7c478bd9Sstevel@tonic-gate #define CMD_INPUT 1 78*7c478bd9Sstevel@tonic-gate #define WILD_STRING "$" /* wildcard character */ 79*7c478bd9Sstevel@tonic-gate #define COMMENT_CHAR '#' /* comment character */ 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate * List of strings with arbitrary matching values 83*7c478bd9Sstevel@tonic-gate */ 84*7c478bd9Sstevel@tonic-gate typedef struct slist { 85*7c478bd9Sstevel@tonic-gate char *str; 86*7c478bd9Sstevel@tonic-gate char *help; 87*7c478bd9Sstevel@tonic-gate int32_t value; 88*7c478bd9Sstevel@tonic-gate } slist_t; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate static slist_t ptag_choices[] = { 91*7c478bd9Sstevel@tonic-gate { "unassigned", "", V_UNASSIGNED }, 92*7c478bd9Sstevel@tonic-gate { "boot", "", V_BOOT }, 93*7c478bd9Sstevel@tonic-gate { "root", "", V_ROOT }, 94*7c478bd9Sstevel@tonic-gate { "swap", "", V_SWAP }, 95*7c478bd9Sstevel@tonic-gate { "usr", "", V_USR }, 96*7c478bd9Sstevel@tonic-gate { "backup", "", V_BACKUP }, 97*7c478bd9Sstevel@tonic-gate { "stand", "", V_STAND }, 98*7c478bd9Sstevel@tonic-gate { "var", "", V_VAR }, 99*7c478bd9Sstevel@tonic-gate { "home", "", V_HOME }, 100*7c478bd9Sstevel@tonic-gate { "alternates", "", V_ALTSCTR }, 101*7c478bd9Sstevel@tonic-gate { NULL } 102*7c478bd9Sstevel@tonic-gate }; 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate /* 106*7c478bd9Sstevel@tonic-gate * Choices for the p_flag vtoc field 107*7c478bd9Sstevel@tonic-gate */ 108*7c478bd9Sstevel@tonic-gate static slist_t pflag_choices[] = { 109*7c478bd9Sstevel@tonic-gate { "wm", "read-write, mountable", 0 }, 110*7c478bd9Sstevel@tonic-gate { "wu", "read-write, unmountable", V_UNMNT }, 111*7c478bd9Sstevel@tonic-gate { "rm", "read-only, mountable", V_RONLY }, 112*7c478bd9Sstevel@tonic-gate { "ru", "read-only, unmountable", V_RONLY|V_UNMNT }, 113*7c478bd9Sstevel@tonic-gate { NULL } 114*7c478bd9Sstevel@tonic-gate }; 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate /* 117*7c478bd9Sstevel@tonic-gate * The definitions are the token types that the data file parser recognizes. 118*7c478bd9Sstevel@tonic-gate */ 119*7c478bd9Sstevel@tonic-gate #define SUP_EOF -1 /* eof token */ 120*7c478bd9Sstevel@tonic-gate #define SUP_STRING 0 /* string token */ 121*7c478bd9Sstevel@tonic-gate #define SUP_EQL 1 /* equals token */ 122*7c478bd9Sstevel@tonic-gate #define SUP_COMMA 2 /* comma token */ 123*7c478bd9Sstevel@tonic-gate #define SUP_COLON 3 /* colon token */ 124*7c478bd9Sstevel@tonic-gate #define SUP_EOL 4 /* newline token */ 125*7c478bd9Sstevel@tonic-gate #define SUP_OR 5 /* vertical bar */ 126*7c478bd9Sstevel@tonic-gate #define SUP_AND 6 /* ampersand */ 127*7c478bd9Sstevel@tonic-gate #define SUP_TILDE 7 /* tilde */ 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* 131*7c478bd9Sstevel@tonic-gate * Prototypes for ANSI C compilers 132*7c478bd9Sstevel@tonic-gate */ 133*7c478bd9Sstevel@tonic-gate static int32_t sup_prxfile(char *file_name, struct vtoc *vt); 134*7c478bd9Sstevel@tonic-gate static int32_t sup_setpart(struct vtoc *vt); 135*7c478bd9Sstevel@tonic-gate static void sup_pushchar(int32_t c); 136*7c478bd9Sstevel@tonic-gate static void clean_token(char *cleantoken, char *token); 137*7c478bd9Sstevel@tonic-gate static void clean_token(char *cleantoken, char *token); 138*7c478bd9Sstevel@tonic-gate static int32_t sup_inputchar(); 139*7c478bd9Sstevel@tonic-gate static int32_t sup_gettoken(char *buf); 140*7c478bd9Sstevel@tonic-gate static int32_t sup_get_token(char *buf); 141*7c478bd9Sstevel@tonic-gate static int32_t find_value(slist_t *slist, char *str, int32_t *value); 142*7c478bd9Sstevel@tonic-gate static int32_t check_vtoc_sanity(smedia_handle_t, int32_t fd, struct vtoc *vt); 143*7c478bd9Sstevel@tonic-gate static int32_t str2sector(char *str); 144*7c478bd9Sstevel@tonic-gate static int32_t strcnt(char *s1, char *s2); 145*7c478bd9Sstevel@tonic-gate static int32_t get_fdisk(smedia_handle_t, int32_t fd, int32_t offset, 146*7c478bd9Sstevel@tonic-gate struct fdisk_info *fdisk); 147*7c478bd9Sstevel@tonic-gate static void erase(smedia_handle_t handle, uint32_t offset, uint32_t size); 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate extern char *myname; 150*7c478bd9Sstevel@tonic-gate extern int64_t my_atoll(char *ptr); 151*7c478bd9Sstevel@tonic-gate extern smmedium_prop_t med_info; 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate static FILE *data_file; 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate static int32_t 156*7c478bd9Sstevel@tonic-gate sup_prxfile(char *file_name, struct vtoc *vt) 157*7c478bd9Sstevel@tonic-gate { 158*7c478bd9Sstevel@tonic-gate int32_t status, ret_val; 159*7c478bd9Sstevel@tonic-gate TOKEN token; 160*7c478bd9Sstevel@tonic-gate TOKEN cleaned; 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate /* 163*7c478bd9Sstevel@tonic-gate * Open the data file. Return 0 if unable to do so. 164*7c478bd9Sstevel@tonic-gate */ 165*7c478bd9Sstevel@tonic-gate data_file = fopen(file_name, "r"); 166*7c478bd9Sstevel@tonic-gate if (data_file == NULL) { 167*7c478bd9Sstevel@tonic-gate PERROR("Open failed"); 168*7c478bd9Sstevel@tonic-gate return (-1); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate /* 171*7c478bd9Sstevel@tonic-gate * Step through the data file a meta-line at a time. There are 172*7c478bd9Sstevel@tonic-gate * typically several backslashed newlines in each meta-line, 173*7c478bd9Sstevel@tonic-gate * so data_lineno will be getting side effected along the way. 174*7c478bd9Sstevel@tonic-gate */ 175*7c478bd9Sstevel@tonic-gate data_lineno = 1; 176*7c478bd9Sstevel@tonic-gate for (;;) { 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* 179*7c478bd9Sstevel@tonic-gate * Get the keyword. 180*7c478bd9Sstevel@tonic-gate */ 181*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 182*7c478bd9Sstevel@tonic-gate /* 183*7c478bd9Sstevel@tonic-gate * If we hit the end of the data file, we're done. 184*7c478bd9Sstevel@tonic-gate */ 185*7c478bd9Sstevel@tonic-gate if (status == SUP_EOF) 186*7c478bd9Sstevel@tonic-gate break; 187*7c478bd9Sstevel@tonic-gate /* 188*7c478bd9Sstevel@tonic-gate * If the line starts with some key character, it's an error. 189*7c478bd9Sstevel@tonic-gate */ 190*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 191*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 192*7c478bd9Sstevel@tonic-gate gettext("Expecting keyword, found '%s'"), 193*7c478bd9Sstevel@tonic-gate token); 194*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 195*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 196*7c478bd9Sstevel@tonic-gate continue; 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate /* 199*7c478bd9Sstevel@tonic-gate * Clean up the token and see which keyword it is. Call 200*7c478bd9Sstevel@tonic-gate * the appropriate routine to process the rest of the line. 201*7c478bd9Sstevel@tonic-gate */ 202*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 203*7c478bd9Sstevel@tonic-gate if (strcmp(cleaned, "slices") == 0) { 204*7c478bd9Sstevel@tonic-gate ret_val = sup_setpart(vt); 205*7c478bd9Sstevel@tonic-gate (void) fclose(data_file); 206*7c478bd9Sstevel@tonic-gate return (ret_val); 207*7c478bd9Sstevel@tonic-gate } else { 208*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Unknown keyword '%s'"), 209*7c478bd9Sstevel@tonic-gate cleaned); 210*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 211*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 212*7c478bd9Sstevel@tonic-gate (void) fclose(data_file); 213*7c478bd9Sstevel@tonic-gate return (-1); 214*7c478bd9Sstevel@tonic-gate } 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate /* 217*7c478bd9Sstevel@tonic-gate * Close the data file. 218*7c478bd9Sstevel@tonic-gate */ 219*7c478bd9Sstevel@tonic-gate (void) fclose(data_file); 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 222*7c478bd9Sstevel@tonic-gate gettext("Unexpected end of file (line no %d)\n"), data_lineno); 223*7c478bd9Sstevel@tonic-gate return (-1); 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate static int32_t 227*7c478bd9Sstevel@tonic-gate sup_gettoken(char *buf) 228*7c478bd9Sstevel@tonic-gate { 229*7c478bd9Sstevel@tonic-gate /* 230*7c478bd9Sstevel@tonic-gate * Skip end of lines and blank lines. 231*7c478bd9Sstevel@tonic-gate */ 232*7c478bd9Sstevel@tonic-gate while ((last_token_type = sup_get_token(buf)) == SUP_EOL) 233*7c478bd9Sstevel@tonic-gate ; 234*7c478bd9Sstevel@tonic-gate return (last_token_type); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate static int32_t 238*7c478bd9Sstevel@tonic-gate sup_get_token(char *buf) 239*7c478bd9Sstevel@tonic-gate { 240*7c478bd9Sstevel@tonic-gate char *ptr = buf; 241*7c478bd9Sstevel@tonic-gate int32_t c, quoted = 0; 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate /* 244*7c478bd9Sstevel@tonic-gate * Was an end of file detected last try? 245*7c478bd9Sstevel@tonic-gate */ 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate if (feof(data_file)) { 248*7c478bd9Sstevel@tonic-gate return (SUP_EOF); 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate /* 252*7c478bd9Sstevel@tonic-gate * Zero out the returned token buffer 253*7c478bd9Sstevel@tonic-gate */ 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate bzero(buf, TOKEN_SIZE + 1); 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate /* 258*7c478bd9Sstevel@tonic-gate * Strip off leading white-space. 259*7c478bd9Sstevel@tonic-gate */ 260*7c478bd9Sstevel@tonic-gate while (isspace(c = sup_inputchar())) 261*7c478bd9Sstevel@tonic-gate ; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate /* 264*7c478bd9Sstevel@tonic-gate * Only white spaces and then end of file? 265*7c478bd9Sstevel@tonic-gate */ 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate if (feof(data_file)) { 268*7c478bd9Sstevel@tonic-gate return (SUP_EOF); 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate /* 272*7c478bd9Sstevel@tonic-gate * Read in characters until we hit unquoted white-space. 273*7c478bd9Sstevel@tonic-gate */ 274*7c478bd9Sstevel@tonic-gate for (; !isspace(c) || quoted; c = sup_inputchar()) { 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate /* 277*7c478bd9Sstevel@tonic-gate * If we hit eof, check if we have anything in buffer. 278*7c478bd9Sstevel@tonic-gate * if we have, return STRING, next time we will return EOF 279*7c478bd9Sstevel@tonic-gate * else, return EOF here...should not happen. 280*7c478bd9Sstevel@tonic-gate */ 281*7c478bd9Sstevel@tonic-gate if (feof(data_file)) { 282*7c478bd9Sstevel@tonic-gate if (ptr - buf > 0) { 283*7c478bd9Sstevel@tonic-gate return (SUP_STRING); 284*7c478bd9Sstevel@tonic-gate } else { 285*7c478bd9Sstevel@tonic-gate return (SUP_EOF); 286*7c478bd9Sstevel@tonic-gate } 287*7c478bd9Sstevel@tonic-gate } 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate /* 290*7c478bd9Sstevel@tonic-gate * If we hit a double quote, change the state of quoting. 291*7c478bd9Sstevel@tonic-gate */ 292*7c478bd9Sstevel@tonic-gate if (c == '"') { 293*7c478bd9Sstevel@tonic-gate quoted = !quoted; 294*7c478bd9Sstevel@tonic-gate continue; 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate /* 297*7c478bd9Sstevel@tonic-gate * If we hit a newline, that delimits a token. 298*7c478bd9Sstevel@tonic-gate */ 299*7c478bd9Sstevel@tonic-gate if (c == '\n') 300*7c478bd9Sstevel@tonic-gate break; 301*7c478bd9Sstevel@tonic-gate /* 302*7c478bd9Sstevel@tonic-gate * If we hit any nonquoted special delimiters, that delimits 303*7c478bd9Sstevel@tonic-gate * a token. 304*7c478bd9Sstevel@tonic-gate */ 305*7c478bd9Sstevel@tonic-gate if (!quoted && (c == '=' || c == ',' || c == ':' || 306*7c478bd9Sstevel@tonic-gate c == '#' || c == '|' || c == '&' || c == '~')) 307*7c478bd9Sstevel@tonic-gate break; 308*7c478bd9Sstevel@tonic-gate /* 309*7c478bd9Sstevel@tonic-gate * Store the character if there's room left. 310*7c478bd9Sstevel@tonic-gate */ 311*7c478bd9Sstevel@tonic-gate if (ptr - buf < TOKEN_SIZE) 312*7c478bd9Sstevel@tonic-gate *ptr++ = (char)c; 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate /* 315*7c478bd9Sstevel@tonic-gate * If we stored characters in the buffer, then we inputted a string. 316*7c478bd9Sstevel@tonic-gate * Push the delimiter back into the pipe and return the string. 317*7c478bd9Sstevel@tonic-gate */ 318*7c478bd9Sstevel@tonic-gate if (ptr - buf > 0) { 319*7c478bd9Sstevel@tonic-gate sup_pushchar(c); 320*7c478bd9Sstevel@tonic-gate return (SUP_STRING); 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate /* 323*7c478bd9Sstevel@tonic-gate * We didn't input a string, so we must have inputted a known delimiter. 324*7c478bd9Sstevel@tonic-gate * store the delimiter in the buffer, so it will get returned. 325*7c478bd9Sstevel@tonic-gate */ 326*7c478bd9Sstevel@tonic-gate buf[0] = c; 327*7c478bd9Sstevel@tonic-gate /* 328*7c478bd9Sstevel@tonic-gate * Switch on the delimiter. Return the appropriate value for each one. 329*7c478bd9Sstevel@tonic-gate */ 330*7c478bd9Sstevel@tonic-gate switch (c) { 331*7c478bd9Sstevel@tonic-gate case '=': 332*7c478bd9Sstevel@tonic-gate return (SUP_EQL); 333*7c478bd9Sstevel@tonic-gate case ':': 334*7c478bd9Sstevel@tonic-gate return (SUP_COLON); 335*7c478bd9Sstevel@tonic-gate case ',': 336*7c478bd9Sstevel@tonic-gate return (SUP_COMMA); 337*7c478bd9Sstevel@tonic-gate case '\n': 338*7c478bd9Sstevel@tonic-gate return (SUP_EOL); 339*7c478bd9Sstevel@tonic-gate case '|': 340*7c478bd9Sstevel@tonic-gate return (SUP_OR); 341*7c478bd9Sstevel@tonic-gate case '&': 342*7c478bd9Sstevel@tonic-gate return (SUP_AND); 343*7c478bd9Sstevel@tonic-gate case '~': 344*7c478bd9Sstevel@tonic-gate return (SUP_TILDE); 345*7c478bd9Sstevel@tonic-gate case '#': 346*7c478bd9Sstevel@tonic-gate /* 347*7c478bd9Sstevel@tonic-gate * For comments, we flush out the rest of the line and return 348*7c478bd9Sstevel@tonic-gate * an eol. 349*7c478bd9Sstevel@tonic-gate */ 350*7c478bd9Sstevel@tonic-gate while ((c = sup_inputchar()) != '\n' && !feof(data_file)) 351*7c478bd9Sstevel@tonic-gate ; 352*7c478bd9Sstevel@tonic-gate if (feof(data_file)) 353*7c478bd9Sstevel@tonic-gate return (SUP_EOF); 354*7c478bd9Sstevel@tonic-gate else 355*7c478bd9Sstevel@tonic-gate return (SUP_EOL); 356*7c478bd9Sstevel@tonic-gate /* 357*7c478bd9Sstevel@tonic-gate * Shouldn't ever get here. 358*7c478bd9Sstevel@tonic-gate */ 359*7c478bd9Sstevel@tonic-gate default: 360*7c478bd9Sstevel@tonic-gate return (SUP_STRING); 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate static int32_t 364*7c478bd9Sstevel@tonic-gate sup_inputchar() 365*7c478bd9Sstevel@tonic-gate { 366*7c478bd9Sstevel@tonic-gate int32_t c; 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate /* 369*7c478bd9Sstevel@tonic-gate * Input the character. 370*7c478bd9Sstevel@tonic-gate */ 371*7c478bd9Sstevel@tonic-gate c = getc(data_file); 372*7c478bd9Sstevel@tonic-gate /* 373*7c478bd9Sstevel@tonic-gate * If it's not a backslash, return it. 374*7c478bd9Sstevel@tonic-gate */ 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate /* 377*7c478bd9Sstevel@tonic-gate * It was a backslash. Get the next character. 378*7c478bd9Sstevel@tonic-gate */ 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate if (c == '\\') 381*7c478bd9Sstevel@tonic-gate c = getc(data_file); 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate /* 384*7c478bd9Sstevel@tonic-gate * If it was a newline, update the line counter and get the next 385*7c478bd9Sstevel@tonic-gate * character. 386*7c478bd9Sstevel@tonic-gate */ 387*7c478bd9Sstevel@tonic-gate if (c == '\n') { 388*7c478bd9Sstevel@tonic-gate data_lineno++; 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate /* 391*7c478bd9Sstevel@tonic-gate * Return the character. 392*7c478bd9Sstevel@tonic-gate */ 393*7c478bd9Sstevel@tonic-gate return (c); 394*7c478bd9Sstevel@tonic-gate } 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate static void 397*7c478bd9Sstevel@tonic-gate sup_pushchar(int32_t c) 398*7c478bd9Sstevel@tonic-gate { 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate (void) ungetc(c, data_file); 401*7c478bd9Sstevel@tonic-gate if (c == '\n') 402*7c478bd9Sstevel@tonic-gate data_lineno--; 403*7c478bd9Sstevel@tonic-gate } 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate static void 406*7c478bd9Sstevel@tonic-gate clean_token(char *cleantoken, char *token) 407*7c478bd9Sstevel@tonic-gate { 408*7c478bd9Sstevel@tonic-gate char *ptr; 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate /* 411*7c478bd9Sstevel@tonic-gate * Strip off leading white-space. 412*7c478bd9Sstevel@tonic-gate */ 413*7c478bd9Sstevel@tonic-gate for (ptr = token; isspace(*ptr) && (ptr <= 414*7c478bd9Sstevel@tonic-gate (token + strlen(token) - 1)); ptr++); 415*7c478bd9Sstevel@tonic-gate 416*7c478bd9Sstevel@tonic-gate /* 417*7c478bd9Sstevel@tonic-gate * Copy it into the clean buffer. 418*7c478bd9Sstevel@tonic-gate */ 419*7c478bd9Sstevel@tonic-gate (void) strcpy(cleantoken, ptr); 420*7c478bd9Sstevel@tonic-gate /* 421*7c478bd9Sstevel@tonic-gate * Strip off trailing white-space. 422*7c478bd9Sstevel@tonic-gate */ 423*7c478bd9Sstevel@tonic-gate for (ptr = cleantoken + strlen(cleantoken) - 1; 424*7c478bd9Sstevel@tonic-gate isspace(*ptr) && (ptr >= cleantoken); ptr--) { 425*7c478bd9Sstevel@tonic-gate *ptr = '\0'; 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate static int32_t 430*7c478bd9Sstevel@tonic-gate sup_setpart(struct vtoc *vt) 431*7c478bd9Sstevel@tonic-gate { 432*7c478bd9Sstevel@tonic-gate TOKEN token, cleaned, ident; 433*7c478bd9Sstevel@tonic-gate int32_t i, index, status, val1, val2; 434*7c478bd9Sstevel@tonic-gate ushort_t vtoc_tag = 0xFFFF; 435*7c478bd9Sstevel@tonic-gate ushort_t vtoc_flag = 0xFFFF; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate /* 438*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 439*7c478bd9Sstevel@tonic-gate */ 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate if (status != SUP_COLON) { 444*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 445*7c478bd9Sstevel@tonic-gate gettext("Expecting ':', found '%s'"), token); 446*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 447*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 448*7c478bd9Sstevel@tonic-gate return (-1); 449*7c478bd9Sstevel@tonic-gate } 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate for (;;) { 452*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 453*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 454*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 455*7c478bd9Sstevel@tonic-gate gettext("Expecting string, found '%s'"), token); 456*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 457*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 458*7c478bd9Sstevel@tonic-gate return (-1); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate clean_token(ident, token); 461*7c478bd9Sstevel@tonic-gate /* 462*7c478bd9Sstevel@tonic-gate * Also make sure it is within the legal range of letters. 463*7c478bd9Sstevel@tonic-gate */ 464*7c478bd9Sstevel@tonic-gate /* 465*7c478bd9Sstevel@tonic-gate * Here's the index of the partition we're dealing with 466*7c478bd9Sstevel@tonic-gate */ 467*7c478bd9Sstevel@tonic-gate index = (int32_t)my_atoll(ident); 468*7c478bd9Sstevel@tonic-gate if ((index < 0) || (index > NDKMAP)) { 469*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 470*7c478bd9Sstevel@tonic-gate gettext("Unknown partition '%s'"), index); 471*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 472*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 473*7c478bd9Sstevel@tonic-gate return (-1); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate /* 476*7c478bd9Sstevel@tonic-gate * Check for floppy and PCMCIA_MEM cards. 477*7c478bd9Sstevel@tonic-gate * for floppy, the partition no. can be 0 1 2. 478*7c478bd9Sstevel@tonic-gate * for PCMCIA, the partition no. can be 2 479*7c478bd9Sstevel@tonic-gate */ 480*7c478bd9Sstevel@tonic-gate if (med_info.sm_media_type == SM_FLOPPY) { 481*7c478bd9Sstevel@tonic-gate if ((index < 0) || (index > 2)) { 482*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 483*7c478bd9Sstevel@tonic-gate "Floppy can have partitions 0 1 and 2\n")); 484*7c478bd9Sstevel@tonic-gate return (-1); 485*7c478bd9Sstevel@tonic-gate } 486*7c478bd9Sstevel@tonic-gate } 487*7c478bd9Sstevel@tonic-gate if (med_info.sm_media_type == SM_PCMCIA_MEM) { 488*7c478bd9Sstevel@tonic-gate if (index != 2) { 489*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext( 490*7c478bd9Sstevel@tonic-gate "PCMCIA Memory cards can have partition 2 only.\n")); 491*7c478bd9Sstevel@tonic-gate return (-1); 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate } 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate DPRINTF1("\n Partition %d: ", index); 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 498*7c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 499*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 500*7c478bd9Sstevel@tonic-gate gettext("Expecting '=', found '%s'"), token); 501*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 502*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 503*7c478bd9Sstevel@tonic-gate return (-1); 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate } 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 509*7c478bd9Sstevel@tonic-gate /* 510*7c478bd9Sstevel@tonic-gate * If we hit a key character, it's an error. 511*7c478bd9Sstevel@tonic-gate */ 512*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 513*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 514*7c478bd9Sstevel@tonic-gate gettext("Expecting value, found '%s'"), token); 515*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 516*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 517*7c478bd9Sstevel@tonic-gate return (-1); 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 520*7c478bd9Sstevel@tonic-gate /* 521*7c478bd9Sstevel@tonic-gate * <tag> may be one of: boot, root, swap, etc. 522*7c478bd9Sstevel@tonic-gate * <flag> consists of two characters: 523*7c478bd9Sstevel@tonic-gate * W (writable) or R (read-only) 524*7c478bd9Sstevel@tonic-gate * M (mountable) or U (unmountable) 525*7c478bd9Sstevel@tonic-gate * 526*7c478bd9Sstevel@tonic-gate * Start with the defaults assigned above: 527*7c478bd9Sstevel@tonic-gate */ 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate /* 530*7c478bd9Sstevel@tonic-gate * All other attributes have a pair of numeric values. 531*7c478bd9Sstevel@tonic-gate * Convert the first value to a number. This value 532*7c478bd9Sstevel@tonic-gate * is the starting cylinder number of the partition. 533*7c478bd9Sstevel@tonic-gate */ 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate /* Check for valid partition, e.g. > 8 or 16 */ 536*7c478bd9Sstevel@tonic-gate val1 = str2sector(cleaned); 537*7c478bd9Sstevel@tonic-gate if (val1 == -1) { 538*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 539*7c478bd9Sstevel@tonic-gate gettext("Invalid partition beggining %s \n"), 540*7c478bd9Sstevel@tonic-gate cleaned); 541*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 542*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate DPRINTF1(" begins %s", cleaned); 546*7c478bd9Sstevel@tonic-gate /* 547*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 548*7c478bd9Sstevel@tonic-gate */ 549*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 550*7c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 551*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 552*7c478bd9Sstevel@tonic-gate gettext("Expecting ', ', found '%s'"), token); 553*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 554*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 555*7c478bd9Sstevel@tonic-gate return (-1); 556*7c478bd9Sstevel@tonic-gate } 557*7c478bd9Sstevel@tonic-gate /* 558*7c478bd9Sstevel@tonic-gate * Pull in the second value. 559*7c478bd9Sstevel@tonic-gate */ 560*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 561*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 562*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 563*7c478bd9Sstevel@tonic-gate gettext("Expecting value, found '%s'"), token); 564*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 565*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 566*7c478bd9Sstevel@tonic-gate return (-1); 567*7c478bd9Sstevel@tonic-gate } 568*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate val2 = str2sector(cleaned); 571*7c478bd9Sstevel@tonic-gate if (val2 == -1) { 572*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 573*7c478bd9Sstevel@tonic-gate gettext("Invalid partition size %s \n"), 574*7c478bd9Sstevel@tonic-gate cleaned); 575*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 576*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 577*7c478bd9Sstevel@tonic-gate } 578*7c478bd9Sstevel@tonic-gate DPRINTF1(" ends %s ", cleaned); 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate /* 581*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 582*7c478bd9Sstevel@tonic-gate */ 583*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate if (status == SUP_COMMA) { 586*7c478bd9Sstevel@tonic-gate /* tags and flags */ 587*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 588*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 589*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 590*7c478bd9Sstevel@tonic-gate gettext("Expecting value, found '%s'"), 591*7c478bd9Sstevel@tonic-gate token); 592*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 593*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 594*7c478bd9Sstevel@tonic-gate return (-1); 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 597*7c478bd9Sstevel@tonic-gate if (find_value(pflag_choices, cleaned, &i) == 1) { 598*7c478bd9Sstevel@tonic-gate /* 599*7c478bd9Sstevel@tonic-gate * Found valid tag. Use it and advance parser 600*7c478bd9Sstevel@tonic-gate */ 601*7c478bd9Sstevel@tonic-gate DPRINTF1(" flag = %s", cleaned); 602*7c478bd9Sstevel@tonic-gate vtoc_flag = (ushort_t)i; 603*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 604*7c478bd9Sstevel@tonic-gate } else if (find_value(ptag_choices, cleaned, &i) == 1) { 605*7c478bd9Sstevel@tonic-gate DPRINTF1(" tag = %s", cleaned); 606*7c478bd9Sstevel@tonic-gate vtoc_tag = (ushort_t)i; 607*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 608*7c478bd9Sstevel@tonic-gate if (status == SUP_COMMA) { 609*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 610*7c478bd9Sstevel@tonic-gate gettext("Expecting : got %s\n"), 611*7c478bd9Sstevel@tonic-gate token); 612*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 613*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), 614*7c478bd9Sstevel@tonic-gate data_lineno); 615*7c478bd9Sstevel@tonic-gate return (-1); 616*7c478bd9Sstevel@tonic-gate } 617*7c478bd9Sstevel@tonic-gate } else { 618*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 619*7c478bd9Sstevel@tonic-gate gettext("Invalid flag or tag\n")); 620*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 621*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 622*7c478bd9Sstevel@tonic-gate return (-1); 623*7c478bd9Sstevel@tonic-gate } 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate if (status == SUP_COMMA) { 627*7c478bd9Sstevel@tonic-gate /* Can be tag only */ 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 630*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 631*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 632*7c478bd9Sstevel@tonic-gate gettext( 633*7c478bd9Sstevel@tonic-gate "Expecting value, found '%s'"), 634*7c478bd9Sstevel@tonic-gate token); 635*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 636*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), 637*7c478bd9Sstevel@tonic-gate data_lineno); 638*7c478bd9Sstevel@tonic-gate return (-1); 639*7c478bd9Sstevel@tonic-gate } 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 642*7c478bd9Sstevel@tonic-gate if (find_value(ptag_choices, 643*7c478bd9Sstevel@tonic-gate cleaned, &i) == 1) { 644*7c478bd9Sstevel@tonic-gate DPRINTF1(" tag = %s", cleaned); 645*7c478bd9Sstevel@tonic-gate vtoc_tag = (ushort_t)i; 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 648*7c478bd9Sstevel@tonic-gate } 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate /* 652*7c478bd9Sstevel@tonic-gate * Fill in the appropriate map entry with the values. 653*7c478bd9Sstevel@tonic-gate */ 654*7c478bd9Sstevel@tonic-gate vt->v_part[index].p_start = val1; 655*7c478bd9Sstevel@tonic-gate vt->v_part[index].p_size = val2; 656*7c478bd9Sstevel@tonic-gate if (vtoc_tag != 0xFFFF) { 657*7c478bd9Sstevel@tonic-gate vt->v_part[index].p_tag = vtoc_tag; 658*7c478bd9Sstevel@tonic-gate vtoc_tag = 0xFFFF; 659*7c478bd9Sstevel@tonic-gate } 660*7c478bd9Sstevel@tonic-gate if (vtoc_flag != 0xFFFF) { 661*7c478bd9Sstevel@tonic-gate vt->v_part[index].p_flag = vtoc_flag; 662*7c478bd9Sstevel@tonic-gate vtoc_flag = 0xFFFF; 663*7c478bd9Sstevel@tonic-gate } 664*7c478bd9Sstevel@tonic-gate if (status == SUP_EOF) { 665*7c478bd9Sstevel@tonic-gate DPRINTF("\nEnd of file\n"); 666*7c478bd9Sstevel@tonic-gate break; 667*7c478bd9Sstevel@tonic-gate } 668*7c478bd9Sstevel@tonic-gate if (status != SUP_COLON) { 669*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 670*7c478bd9Sstevel@tonic-gate gettext("Expecting ':', found '%s'"), token); 671*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 672*7c478bd9Sstevel@tonic-gate gettext("Line no %d\n"), data_lineno); 673*7c478bd9Sstevel@tonic-gate return (-1); 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate return (0); 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate static int32_t 681*7c478bd9Sstevel@tonic-gate find_value(slist_t *slist, char *match_str, int32_t *match_value) 682*7c478bd9Sstevel@tonic-gate { 683*7c478bd9Sstevel@tonic-gate int32_t i; 684*7c478bd9Sstevel@tonic-gate int32_t nmatches; 685*7c478bd9Sstevel@tonic-gate int32_t length; 686*7c478bd9Sstevel@tonic-gate int32_t match_length; 687*7c478bd9Sstevel@tonic-gate 688*7c478bd9Sstevel@tonic-gate nmatches = 0; 689*7c478bd9Sstevel@tonic-gate length = 0; 690*7c478bd9Sstevel@tonic-gate 691*7c478bd9Sstevel@tonic-gate match_length = strlen(match_str); 692*7c478bd9Sstevel@tonic-gate 693*7c478bd9Sstevel@tonic-gate for (; slist->str != NULL; slist++) { 694*7c478bd9Sstevel@tonic-gate /* 695*7c478bd9Sstevel@tonic-gate * See how many characters of the token match 696*7c478bd9Sstevel@tonic-gate */ 697*7c478bd9Sstevel@tonic-gate i = strcnt(match_str, slist->str); 698*7c478bd9Sstevel@tonic-gate /* 699*7c478bd9Sstevel@tonic-gate * If it's not the whole token, then it's not a match. 700*7c478bd9Sstevel@tonic-gate */ 701*7c478bd9Sstevel@tonic-gate if (i < match_length) { 702*7c478bd9Sstevel@tonic-gate continue; 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate /* 705*7c478bd9Sstevel@tonic-gate * If it ties with another input, remember that. 706*7c478bd9Sstevel@tonic-gate */ 707*7c478bd9Sstevel@tonic-gate if (i == length) 708*7c478bd9Sstevel@tonic-gate nmatches++; 709*7c478bd9Sstevel@tonic-gate /* 710*7c478bd9Sstevel@tonic-gate * If it matches the most so far, record that. 711*7c478bd9Sstevel@tonic-gate */ 712*7c478bd9Sstevel@tonic-gate if (i > length) { 713*7c478bd9Sstevel@tonic-gate *match_value = slist->value; 714*7c478bd9Sstevel@tonic-gate nmatches = 1; 715*7c478bd9Sstevel@tonic-gate length = i; 716*7c478bd9Sstevel@tonic-gate } 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate return (nmatches); 720*7c478bd9Sstevel@tonic-gate } 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate static int32_t 723*7c478bd9Sstevel@tonic-gate strcnt(char *s1, char *s2) 724*7c478bd9Sstevel@tonic-gate { 725*7c478bd9Sstevel@tonic-gate int32_t i = 0; 726*7c478bd9Sstevel@tonic-gate 727*7c478bd9Sstevel@tonic-gate while ((*s1 != '\0') && (*s1++ == *s2++)) 728*7c478bd9Sstevel@tonic-gate i++; 729*7c478bd9Sstevel@tonic-gate return (i); 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate 732*7c478bd9Sstevel@tonic-gate static int32_t 733*7c478bd9Sstevel@tonic-gate str2sector(char *str) 734*7c478bd9Sstevel@tonic-gate { 735*7c478bd9Sstevel@tonic-gate int32_t mul_factor = 1; 736*7c478bd9Sstevel@tonic-gate char *s1, *s2, *base; 737*7c478bd9Sstevel@tonic-gate int32_t num_sectors; 738*7c478bd9Sstevel@tonic-gate int64_t size; 739*7c478bd9Sstevel@tonic-gate 740*7c478bd9Sstevel@tonic-gate base = s2 = (char *)malloc(strlen(str) + 1); 741*7c478bd9Sstevel@tonic-gate if (s2 == NULL) { 742*7c478bd9Sstevel@tonic-gate PERROR("Malloc failed"); 743*7c478bd9Sstevel@tonic-gate return (-1); 744*7c478bd9Sstevel@tonic-gate } 745*7c478bd9Sstevel@tonic-gate *s2 = '\0'; 746*7c478bd9Sstevel@tonic-gate 747*7c478bd9Sstevel@tonic-gate 748*7c478bd9Sstevel@tonic-gate 749*7c478bd9Sstevel@tonic-gate s1 = str; 750*7c478bd9Sstevel@tonic-gate while (*s1) { 751*7c478bd9Sstevel@tonic-gate if ((*s1 != 'x') && ((*s1 < 'A') || (*s1 > 'F')) && 752*7c478bd9Sstevel@tonic-gate ((*s1 < 'a') || (*s1 > 'f')) && ((*s1 < '0') || 753*7c478bd9Sstevel@tonic-gate (*s1 > '9'))) { 754*7c478bd9Sstevel@tonic-gate if (*s1 == 'G') { 755*7c478bd9Sstevel@tonic-gate mul_factor = 1024*1024*1024; 756*7c478bd9Sstevel@tonic-gate s1++; 757*7c478bd9Sstevel@tonic-gate } else if (*s1 == 'M') { 758*7c478bd9Sstevel@tonic-gate mul_factor = 1024*1024; 759*7c478bd9Sstevel@tonic-gate s1++; 760*7c478bd9Sstevel@tonic-gate } else if (*s1 == 'K') { 761*7c478bd9Sstevel@tonic-gate mul_factor = 1024; 762*7c478bd9Sstevel@tonic-gate s1++; 763*7c478bd9Sstevel@tonic-gate } 764*7c478bd9Sstevel@tonic-gate if ((*s1 != 'B') || (*(++s1) != NULL)) { 765*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 766*7c478bd9Sstevel@tonic-gate gettext("Extra chars at the end\n")); 767*7c478bd9Sstevel@tonic-gate free(base); 768*7c478bd9Sstevel@tonic-gate return (-1); 769*7c478bd9Sstevel@tonic-gate } 770*7c478bd9Sstevel@tonic-gate break; 771*7c478bd9Sstevel@tonic-gate } else { 772*7c478bd9Sstevel@tonic-gate *s2++ = *s1++; 773*7c478bd9Sstevel@tonic-gate *s2 = '\0'; 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate } 776*7c478bd9Sstevel@tonic-gate *s2 = NULL; 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate size = my_atoll(base); 779*7c478bd9Sstevel@tonic-gate if ((!mul_factor) || (size == -1)) { 780*7c478bd9Sstevel@tonic-gate free(base); 781*7c478bd9Sstevel@tonic-gate return (-1); 782*7c478bd9Sstevel@tonic-gate } 783*7c478bd9Sstevel@tonic-gate num_sectors = (uint64_t)size * (uint64_t)mul_factor /512; 784*7c478bd9Sstevel@tonic-gate 785*7c478bd9Sstevel@tonic-gate free(base); 786*7c478bd9Sstevel@tonic-gate return (num_sectors); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate int32_t 791*7c478bd9Sstevel@tonic-gate valid_slice_file(smedia_handle_t handle, int32_t fd, char *file_name, 792*7c478bd9Sstevel@tonic-gate struct vtoc *vt) 793*7c478bd9Sstevel@tonic-gate { 794*7c478bd9Sstevel@tonic-gate struct stat status; 795*7c478bd9Sstevel@tonic-gate int32_t ret_val; 796*7c478bd9Sstevel@tonic-gate if (stat(file_name, &status)) { 797*7c478bd9Sstevel@tonic-gate PERROR(file_name); 798*7c478bd9Sstevel@tonic-gate return (-1); 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate (void) memset(vt, 0, sizeof (*vt)); 801*7c478bd9Sstevel@tonic-gate /* Set default tag and flag */ 802*7c478bd9Sstevel@tonic-gate #ifdef sparc 803*7c478bd9Sstevel@tonic-gate vt->v_part[0].p_tag = V_ROOT; 804*7c478bd9Sstevel@tonic-gate vt->v_part[1].p_tag = V_SWAP; 805*7c478bd9Sstevel@tonic-gate vt->v_part[2].p_tag = V_BACKUP; 806*7c478bd9Sstevel@tonic-gate vt->v_part[6].p_tag = V_USR; 807*7c478bd9Sstevel@tonic-gate 808*7c478bd9Sstevel@tonic-gate vt->v_part[1].p_flag = V_UNMNT; /* Unmountable */ 809*7c478bd9Sstevel@tonic-gate vt->v_part[2].p_flag = V_UNMNT; /* Unmountable */ 810*7c478bd9Sstevel@tonic-gate #endif 811*7c478bd9Sstevel@tonic-gate 812*7c478bd9Sstevel@tonic-gate ret_val = sup_prxfile(file_name, vt); 813*7c478bd9Sstevel@tonic-gate if (ret_val < 0) 814*7c478bd9Sstevel@tonic-gate return (-1); 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 817*7c478bd9Sstevel@tonic-gate { 818*7c478bd9Sstevel@tonic-gate int32_t i; 819*7c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) { 820*7c478bd9Sstevel@tonic-gate DPRINTF1("\npart %d\n", i); 821*7c478bd9Sstevel@tonic-gate DPRINTF1("\t start %d", (int32_t)vt->v_part[i].p_start); 822*7c478bd9Sstevel@tonic-gate DPRINTF1("\t size %d ", (int32_t)vt->v_part[i].p_size); 823*7c478bd9Sstevel@tonic-gate DPRINTF1("\t tag %d", vt->v_part[i].p_tag); 824*7c478bd9Sstevel@tonic-gate DPRINTF1("\t flag %d", vt->v_part[i].p_flag); 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate } 827*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 828*7c478bd9Sstevel@tonic-gate if (check_vtoc_sanity(handle, fd, vt) < 0) { 829*7c478bd9Sstevel@tonic-gate return (-1); 830*7c478bd9Sstevel@tonic-gate } 831*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 832*7c478bd9Sstevel@tonic-gate { 833*7c478bd9Sstevel@tonic-gate int32_t i; 834*7c478bd9Sstevel@tonic-gate for (i = 0; i < 8; i++) { 835*7c478bd9Sstevel@tonic-gate DPRINTF1("\npart %d\n", i); 836*7c478bd9Sstevel@tonic-gate DPRINTF1("\t start %d", (int32_t)vt->v_part[i].p_start); 837*7c478bd9Sstevel@tonic-gate DPRINTF1("\t size %d ", (int32_t)vt->v_part[i].p_size); 838*7c478bd9Sstevel@tonic-gate DPRINTF1("\t tag %d", vt->v_part[i].p_tag); 839*7c478bd9Sstevel@tonic-gate DPRINTF1("\t flag %d", vt->v_part[i].p_flag); 840*7c478bd9Sstevel@tonic-gate } 841*7c478bd9Sstevel@tonic-gate } 842*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 843*7c478bd9Sstevel@tonic-gate return (0); 844*7c478bd9Sstevel@tonic-gate } 845*7c478bd9Sstevel@tonic-gate 846*7c478bd9Sstevel@tonic-gate #define SWAP(a, b) {int32_t tmp; tmp = (a); (a) = (b); (b) = tmp; } 847*7c478bd9Sstevel@tonic-gate 848*7c478bd9Sstevel@tonic-gate /* 849*7c478bd9Sstevel@tonic-gate * On x86 Solaris, the partitioning is done in two levels, fdisk and Solaris 850*7c478bd9Sstevel@tonic-gate * VTOC. Where as, on sparc solaris, it is only VTOC. On floppy and PCMCIA 851*7c478bd9Sstevel@tonic-gate * also it is assumed to be only VTOC, no fdisk. 852*7c478bd9Sstevel@tonic-gate * 853*7c478bd9Sstevel@tonic-gate * On sparc, the back up slice can cover the whole medium. But on x86 854*7c478bd9Sstevel@tonic-gate * (SCSI/ATAPI disks), the backup slice can cover the solaris partition 855*7c478bd9Sstevel@tonic-gate * in fdisk table. 856*7c478bd9Sstevel@tonic-gate * Following table describes how is it handled 857*7c478bd9Sstevel@tonic-gate * SPARC: 858*7c478bd9Sstevel@tonic-gate * SCSI/ATAPI, floppy, pcmcia : don't check for fdisk. 859*7c478bd9Sstevel@tonic-gate * DKIOCGGEOM is sufficient. 860*7c478bd9Sstevel@tonic-gate * x86 : floppy, pcmcia : Don't check for fdisk. DKIOCGGEOM is sufficient. 861*7c478bd9Sstevel@tonic-gate * SCSI/ATAPI : Check for fdisk. 862*7c478bd9Sstevel@tonic-gate * if not present, assume that the solaris 863*7c478bd9Sstevel@tonic-gate * partition covers 100% of the medium 864*7c478bd9Sstevel@tonic-gate * (minus one cylinder). 865*7c478bd9Sstevel@tonic-gate * 866*7c478bd9Sstevel@tonic-gate * if present : 867*7c478bd9Sstevel@tonic-gate * check for active solaris partition. 868*7c478bd9Sstevel@tonic-gate * if not found, take the first solaris 869*7c478bd9Sstevel@tonic-gate * partition. 870*7c478bd9Sstevel@tonic-gate * If there are no solaris partitions, its an error, stop. 871*7c478bd9Sstevel@tonic-gate */ 872*7c478bd9Sstevel@tonic-gate 873*7c478bd9Sstevel@tonic-gate static int32_t 874*7c478bd9Sstevel@tonic-gate check_vtoc_sanity(smedia_handle_t handle, int32_t fd, struct vtoc *vt) 875*7c478bd9Sstevel@tonic-gate { 876*7c478bd9Sstevel@tonic-gate 877*7c478bd9Sstevel@tonic-gate int32_t i, j; 878*7c478bd9Sstevel@tonic-gate struct dk_geom dkg; 879*7c478bd9Sstevel@tonic-gate int32_t num_backup = 0; 880*7c478bd9Sstevel@tonic-gate long backup_size = 0; 881*7c478bd9Sstevel@tonic-gate struct part_struct { 882*7c478bd9Sstevel@tonic-gate long start; 883*7c478bd9Sstevel@tonic-gate long end; 884*7c478bd9Sstevel@tonic-gate int32_t num; 885*7c478bd9Sstevel@tonic-gate } part[NDKMAP]; 886*7c478bd9Sstevel@tonic-gate long min_val, min_slice, num_slices; 887*7c478bd9Sstevel@tonic-gate long media_size; 888*7c478bd9Sstevel@tonic-gate int32_t cyl_size; 889*7c478bd9Sstevel@tonic-gate int sparc_style = 0; /* sparc_style handling ? */ 890*7c478bd9Sstevel@tonic-gate struct fdisk_info fdisk; 891*7c478bd9Sstevel@tonic-gate int sol_part; 892*7c478bd9Sstevel@tonic-gate int total_parts = 0; 893*7c478bd9Sstevel@tonic-gate 894*7c478bd9Sstevel@tonic-gate #ifdef sparc 895*7c478bd9Sstevel@tonic-gate sparc_style = 1; 896*7c478bd9Sstevel@tonic-gate #endif /* sparc */ 897*7c478bd9Sstevel@tonic-gate 898*7c478bd9Sstevel@tonic-gate if ((med_info.sm_media_type == SM_FLOPPY) || 899*7c478bd9Sstevel@tonic-gate (med_info.sm_media_type == SM_PCMCIA_MEM) || 900*7c478bd9Sstevel@tonic-gate (med_info.sm_media_type == SM_PCMCIA_ATA) || 901*7c478bd9Sstevel@tonic-gate (med_info.sm_media_type == SM_SCSI_FLOPPY)) { 902*7c478bd9Sstevel@tonic-gate sparc_style = 1; 903*7c478bd9Sstevel@tonic-gate } 904*7c478bd9Sstevel@tonic-gate 905*7c478bd9Sstevel@tonic-gate if (sparc_style) { 906*7c478bd9Sstevel@tonic-gate DPRINTF("sparc style true\n"); 907*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &dkg) < 0) { 908*7c478bd9Sstevel@tonic-gate PERROR("DKIOCGGEOM Failed"); 909*7c478bd9Sstevel@tonic-gate return (-1); 910*7c478bd9Sstevel@tonic-gate } 911*7c478bd9Sstevel@tonic-gate media_size = dkg.dkg_ncyl * dkg.dkg_nhead * dkg.dkg_nsect; 912*7c478bd9Sstevel@tonic-gate cyl_size = dkg.dkg_nhead * dkg.dkg_nsect; 913*7c478bd9Sstevel@tonic-gate } 914*7c478bd9Sstevel@tonic-gate 915*7c478bd9Sstevel@tonic-gate if (!sparc_style) { 916*7c478bd9Sstevel@tonic-gate /* 917*7c478bd9Sstevel@tonic-gate * Try to get the fdisk information if available. 918*7c478bd9Sstevel@tonic-gate */ 919*7c478bd9Sstevel@tonic-gate if (get_fdisk(handle, fd, 0, &fdisk) >= 0) { 920*7c478bd9Sstevel@tonic-gate /* fdisk table on disk */ 921*7c478bd9Sstevel@tonic-gate sol_part = 0xFF; 922*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 923*7c478bd9Sstevel@tonic-gate if (fdisk.part[i].systid == SUNIXOS || 924*7c478bd9Sstevel@tonic-gate fdisk.part[i].systid == SUNIXOS2) { 925*7c478bd9Sstevel@tonic-gate if (sol_part == 0xFF) 926*7c478bd9Sstevel@tonic-gate sol_part = i; 927*7c478bd9Sstevel@tonic-gate total_parts++; 928*7c478bd9Sstevel@tonic-gate if (fdisk.part[i].bootid == ACTIVE) 929*7c478bd9Sstevel@tonic-gate sol_part = i; 930*7c478bd9Sstevel@tonic-gate } 931*7c478bd9Sstevel@tonic-gate } 932*7c478bd9Sstevel@tonic-gate if (sol_part == 0xFF) { 933*7c478bd9Sstevel@tonic-gate /* No Solaris partition */ 934*7c478bd9Sstevel@tonic-gate 935*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("No FDISK \ 936*7c478bd9Sstevel@tonic-gate Solaris partition found!\n")); 937*7c478bd9Sstevel@tonic-gate return (-1); 938*7c478bd9Sstevel@tonic-gate } 939*7c478bd9Sstevel@tonic-gate if (total_parts > 1) 940*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Multiple FDISK \ 941*7c478bd9Sstevel@tonic-gate Solaris partitions found.\n")); 942*7c478bd9Sstevel@tonic-gate media_size = fdisk.part[sol_part].numsect; 943*7c478bd9Sstevel@tonic-gate 944*7c478bd9Sstevel@tonic-gate DPRINTF1("sol_part %d\n", sol_part); 945*7c478bd9Sstevel@tonic-gate DPRINTF1("media_size %d\n", (int)media_size); 946*7c478bd9Sstevel@tonic-gate } else { 947*7c478bd9Sstevel@tonic-gate DPRINTF("Didn't get fdisk\n"); 948*7c478bd9Sstevel@tonic-gate /* 949*7c478bd9Sstevel@tonic-gate * No fdisk partition available. Assume a 100% Solaris. 950*7c478bd9Sstevel@tonic-gate * partition. 951*7c478bd9Sstevel@tonic-gate * Try getting disk geometry. 952*7c478bd9Sstevel@tonic-gate */ 953*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &dkg) < 0) 954*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCG_PHYGEOM, &dkg) < 0) { 955*7c478bd9Sstevel@tonic-gate DPRINTF("DKIOCG_PHYGEOM ioctl failed"); 956*7c478bd9Sstevel@tonic-gate return (-1); 957*7c478bd9Sstevel@tonic-gate } 958*7c478bd9Sstevel@tonic-gate /* On x86 platform 1 cylinder is used for fdisk table */ 959*7c478bd9Sstevel@tonic-gate dkg.dkg_ncyl = dkg.dkg_ncyl - 1; 960*7c478bd9Sstevel@tonic-gate media_size = dkg.dkg_ncyl * dkg.dkg_nhead * 961*7c478bd9Sstevel@tonic-gate dkg.dkg_nsect; 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate } 964*7c478bd9Sstevel@tonic-gate 965*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 966*7c478bd9Sstevel@tonic-gate DPRINTF1("Ncyl %d\n", dkg.dkg_ncyl); 967*7c478bd9Sstevel@tonic-gate DPRINTF1("nhead %d\n", dkg.dkg_nhead); 968*7c478bd9Sstevel@tonic-gate DPRINTF1("nsect %d\n", dkg.dkg_nsect); 969*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate if (media_size == 0) { 972*7c478bd9Sstevel@tonic-gate media_size = med_info.sm_capacity; 973*7c478bd9Sstevel@tonic-gate } 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate (void) memset(&part, 0, sizeof (part)); 976*7c478bd9Sstevel@tonic-gate for (i = 0, j = 0; i < NDKMAP; i++) { 977*7c478bd9Sstevel@tonic-gate if (vt->v_part[i].p_tag == V_BACKUP) { 978*7c478bd9Sstevel@tonic-gate if (vt->v_part[i].p_start != 0) { 979*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 980*7c478bd9Sstevel@tonic-gate gettext( 981*7c478bd9Sstevel@tonic-gate "Backup slice should start at sector 0\n")); 982*7c478bd9Sstevel@tonic-gate return (-1); 983*7c478bd9Sstevel@tonic-gate } 984*7c478bd9Sstevel@tonic-gate backup_size = vt->v_part[i].p_size; 985*7c478bd9Sstevel@tonic-gate num_backup++; 986*7c478bd9Sstevel@tonic-gate continue; 987*7c478bd9Sstevel@tonic-gate } 988*7c478bd9Sstevel@tonic-gate if (vt->v_part[i].p_size) { 989*7c478bd9Sstevel@tonic-gate 990*7c478bd9Sstevel@tonic-gate if (sparc_style) { 991*7c478bd9Sstevel@tonic-gate if (vt->v_part[i].p_start % cyl_size) { 992*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 993*7c478bd9Sstevel@tonic-gate gettext( 994*7c478bd9Sstevel@tonic-gate "Slice %d does not start on cylinder boundary\n"), i); 995*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 996*7c478bd9Sstevel@tonic-gate gettext( 997*7c478bd9Sstevel@tonic-gate "Cylinder size %d 512 byte sectors\n"), cyl_size); 998*7c478bd9Sstevel@tonic-gate return (-1); 999*7c478bd9Sstevel@tonic-gate } 1000*7c478bd9Sstevel@tonic-gate } 1001*7c478bd9Sstevel@tonic-gate part[j].start = vt->v_part[i].p_start; 1002*7c478bd9Sstevel@tonic-gate part[j].end = vt->v_part[i].p_start + 1003*7c478bd9Sstevel@tonic-gate vt->v_part[i].p_size -1; 1004*7c478bd9Sstevel@tonic-gate part[j].num = i; 1005*7c478bd9Sstevel@tonic-gate j++; 1006*7c478bd9Sstevel@tonic-gate } 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate if (num_backup > 1) { 1009*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1010*7c478bd9Sstevel@tonic-gate gettext("Maximum one backup slice is allowed\n")); 1011*7c478bd9Sstevel@tonic-gate (void) smedia_release_handle(handle); 1012*7c478bd9Sstevel@tonic-gate (void) close(fd); 1013*7c478bd9Sstevel@tonic-gate exit(1); 1014*7c478bd9Sstevel@tonic-gate } 1015*7c478bd9Sstevel@tonic-gate num_slices = j; 1016*7c478bd9Sstevel@tonic-gate 1017*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_slices; i++) { 1018*7c478bd9Sstevel@tonic-gate min_val = part[i].start; 1019*7c478bd9Sstevel@tonic-gate min_slice = i; 1020*7c478bd9Sstevel@tonic-gate for (j = i+1; j < num_slices; j++) { 1021*7c478bd9Sstevel@tonic-gate if (part[j].start < min_val) { 1022*7c478bd9Sstevel@tonic-gate min_val = part[j].start; 1023*7c478bd9Sstevel@tonic-gate min_slice = j; 1024*7c478bd9Sstevel@tonic-gate } 1025*7c478bd9Sstevel@tonic-gate } 1026*7c478bd9Sstevel@tonic-gate if (min_slice != i) { 1027*7c478bd9Sstevel@tonic-gate SWAP(part[i].start, part[min_slice].start) 1028*7c478bd9Sstevel@tonic-gate SWAP(part[i].end, part[min_slice].end) 1029*7c478bd9Sstevel@tonic-gate SWAP(part[i].num, part[min_slice].num) 1030*7c478bd9Sstevel@tonic-gate } 1031*7c478bd9Sstevel@tonic-gate } 1032*7c478bd9Sstevel@tonic-gate 1033*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 1034*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_slices; i++) { 1035*7c478bd9Sstevel@tonic-gate DPRINTF4("\n %d (%d) : %d, %d", i, part[i].num, 1036*7c478bd9Sstevel@tonic-gate part[i].start, part[i].end); 1037*7c478bd9Sstevel@tonic-gate } 1038*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1039*7c478bd9Sstevel@tonic-gate 1040*7c478bd9Sstevel@tonic-gate if (backup_size > media_size) { 1041*7c478bd9Sstevel@tonic-gate if (sparc_style) { 1042*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1043*7c478bd9Sstevel@tonic-gate gettext( 1044*7c478bd9Sstevel@tonic-gate "Backup slice extends beyond size of media\n")); 1045*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1046*7c478bd9Sstevel@tonic-gate gettext("media size : %d sectors \n"), media_size); 1047*7c478bd9Sstevel@tonic-gate } else { 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1050*7c478bd9Sstevel@tonic-gate gettext("Backup slice extends beyond size of FDISK \ 1051*7c478bd9Sstevel@tonic-gate Solaris partition\n")); 1052*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1053*7c478bd9Sstevel@tonic-gate gettext( 1054*7c478bd9Sstevel@tonic-gate "FDISK Solaris partition size : %d sectors \n"), 1055*7c478bd9Sstevel@tonic-gate media_size); 1056*7c478bd9Sstevel@tonic-gate } 1057*7c478bd9Sstevel@tonic-gate return (-1); 1058*7c478bd9Sstevel@tonic-gate } 1059*7c478bd9Sstevel@tonic-gate 1060*7c478bd9Sstevel@tonic-gate /* 1061*7c478bd9Sstevel@tonic-gate * If we have only backup slice return success here. 1062*7c478bd9Sstevel@tonic-gate */ 1063*7c478bd9Sstevel@tonic-gate if (num_slices == 0) 1064*7c478bd9Sstevel@tonic-gate return (0); 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate if (backup_size) { 1067*7c478bd9Sstevel@tonic-gate if (part[num_slices - 1].end > backup_size) { 1068*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1069*7c478bd9Sstevel@tonic-gate gettext("Slice %d extends beyond backup slice.\n"), 1070*7c478bd9Sstevel@tonic-gate part[num_slices -1].num); 1071*7c478bd9Sstevel@tonic-gate return (-1); 1072*7c478bd9Sstevel@tonic-gate } 1073*7c478bd9Sstevel@tonic-gate } else { 1074*7c478bd9Sstevel@tonic-gate if (part[num_slices - 1].end > media_size) { 1075*7c478bd9Sstevel@tonic-gate if (sparc_style) { 1076*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1077*7c478bd9Sstevel@tonic-gate gettext( 1078*7c478bd9Sstevel@tonic-gate "Slice %d extends beyond media size\n"), 1079*7c478bd9Sstevel@tonic-gate part[num_slices -1].num); 1080*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1081*7c478bd9Sstevel@tonic-gate gettext("media size : %d sectors \n"), 1082*7c478bd9Sstevel@tonic-gate media_size); 1083*7c478bd9Sstevel@tonic-gate } else { 1084*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1085*7c478bd9Sstevel@tonic-gate gettext( 1086*7c478bd9Sstevel@tonic-gate "Slice %d extends beyond FDISK Solaris partition size\n"), 1087*7c478bd9Sstevel@tonic-gate part[num_slices -1].num); 1088*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1089*7c478bd9Sstevel@tonic-gate gettext("FDISK Solaris partition size : %d \ 1090*7c478bd9Sstevel@tonic-gate sectors \n"), media_size); 1091*7c478bd9Sstevel@tonic-gate } 1092*7c478bd9Sstevel@tonic-gate return (-1); 1093*7c478bd9Sstevel@tonic-gate } 1094*7c478bd9Sstevel@tonic-gate } 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate 1097*7c478bd9Sstevel@tonic-gate 1098*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_slices; i++) { 1099*7c478bd9Sstevel@tonic-gate if (i == 0) 1100*7c478bd9Sstevel@tonic-gate continue; 1101*7c478bd9Sstevel@tonic-gate if (part[i].start <= part[i-1].end) { 1102*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1103*7c478bd9Sstevel@tonic-gate gettext("Overlap between slices %d and %d\n"), 1104*7c478bd9Sstevel@tonic-gate part[i-1].num, part[i].num); 1105*7c478bd9Sstevel@tonic-gate (void) smedia_release_handle(handle); 1106*7c478bd9Sstevel@tonic-gate (void) close(fd); 1107*7c478bd9Sstevel@tonic-gate exit(1); 1108*7c478bd9Sstevel@tonic-gate } 1109*7c478bd9Sstevel@tonic-gate } 1110*7c478bd9Sstevel@tonic-gate 1111*7c478bd9Sstevel@tonic-gate return (0); 1112*7c478bd9Sstevel@tonic-gate } 1113*7c478bd9Sstevel@tonic-gate 1114*7c478bd9Sstevel@tonic-gate 1115*7c478bd9Sstevel@tonic-gate static int32_t 1116*7c478bd9Sstevel@tonic-gate get_fdisk(smedia_handle_t handle, int32_t fd, int32_t offset, 1117*7c478bd9Sstevel@tonic-gate struct fdisk_info *fdisk) 1118*7c478bd9Sstevel@tonic-gate { 1119*7c478bd9Sstevel@tonic-gate struct mboot *boot_sec; 1120*7c478bd9Sstevel@tonic-gate struct ipart *part; 1121*7c478bd9Sstevel@tonic-gate char *buf; 1122*7c478bd9Sstevel@tonic-gate int32_t i, ret; 1123*7c478bd9Sstevel@tonic-gate int save_errno; 1124*7c478bd9Sstevel@tonic-gate 1125*7c478bd9Sstevel@tonic-gate /* Read the master boot program */ 1126*7c478bd9Sstevel@tonic-gate 1127*7c478bd9Sstevel@tonic-gate buf = (char *)malloc(med_info.sm_blocksize); 1128*7c478bd9Sstevel@tonic-gate if (buf == NULL) { 1129*7c478bd9Sstevel@tonic-gate PERROR("malloc failed"); 1130*7c478bd9Sstevel@tonic-gate exit(1); 1131*7c478bd9Sstevel@tonic-gate } 1132*7c478bd9Sstevel@tonic-gate errno = 0; 1133*7c478bd9Sstevel@tonic-gate ret = ioctl(fd, DKIOCGMBOOT, buf); 1134*7c478bd9Sstevel@tonic-gate if (ret < 0) { 1135*7c478bd9Sstevel@tonic-gate if (errno != ENOTTY) { 1136*7c478bd9Sstevel@tonic-gate PERROR("DKIOCGMBOOT ioctl failed"); 1137*7c478bd9Sstevel@tonic-gate return (-1); 1138*7c478bd9Sstevel@tonic-gate } 1139*7c478bd9Sstevel@tonic-gate 1140*7c478bd9Sstevel@tonic-gate /* need the file_dac_read privilege */ 1141*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, 1142*7c478bd9Sstevel@tonic-gate (char *)NULL); 1143*7c478bd9Sstevel@tonic-gate 1144*7c478bd9Sstevel@tonic-gate ret = smedia_raw_read(handle, offset/med_info.sm_blocksize, 1145*7c478bd9Sstevel@tonic-gate buf, med_info.sm_blocksize); 1146*7c478bd9Sstevel@tonic-gate 1147*7c478bd9Sstevel@tonic-gate /* drop the file_dac_read privilege */ 1148*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, 1149*7c478bd9Sstevel@tonic-gate (char *)NULL); 1150*7c478bd9Sstevel@tonic-gate 1151*7c478bd9Sstevel@tonic-gate save_errno = errno; 1152*7c478bd9Sstevel@tonic-gate errno = save_errno; 1153*7c478bd9Sstevel@tonic-gate if (ret != med_info.sm_blocksize) { 1154*7c478bd9Sstevel@tonic-gate if (errno == ENOTSUP) { 1155*7c478bd9Sstevel@tonic-gate errno = 0; 1156*7c478bd9Sstevel@tonic-gate if (lseek(fd, offset, SEEK_SET)) { 1157*7c478bd9Sstevel@tonic-gate PERROR("Seek failed:"); 1158*7c478bd9Sstevel@tonic-gate free(buf); 1159*7c478bd9Sstevel@tonic-gate return (-1); 1160*7c478bd9Sstevel@tonic-gate } 1161*7c478bd9Sstevel@tonic-gate 1162*7c478bd9Sstevel@tonic-gate /* need the file_dac_read privilege */ 1163*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 1164*7c478bd9Sstevel@tonic-gate PRIV_FILE_DAC_READ, (char *)NULL); 1165*7c478bd9Sstevel@tonic-gate 1166*7c478bd9Sstevel@tonic-gate ret = read(fd, buf, sizeof (struct mboot)); 1167*7c478bd9Sstevel@tonic-gate 1168*7c478bd9Sstevel@tonic-gate /* drop the file_dac_read privilege */ 1169*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 1170*7c478bd9Sstevel@tonic-gate PRIV_FILE_DAC_READ, (char *)NULL); 1171*7c478bd9Sstevel@tonic-gate 1172*7c478bd9Sstevel@tonic-gate if (ret != sizeof (struct mboot)) { 1173*7c478bd9Sstevel@tonic-gate PERROR("Could not read master boot record"); 1174*7c478bd9Sstevel@tonic-gate free(buf); 1175*7c478bd9Sstevel@tonic-gate return (-1); 1176*7c478bd9Sstevel@tonic-gate } 1177*7c478bd9Sstevel@tonic-gate } else { 1178*7c478bd9Sstevel@tonic-gate PERROR("Could not read master boot record"); 1179*7c478bd9Sstevel@tonic-gate free(buf); 1180*7c478bd9Sstevel@tonic-gate return (-1); 1181*7c478bd9Sstevel@tonic-gate } 1182*7c478bd9Sstevel@tonic-gate } 1183*7c478bd9Sstevel@tonic-gate } 1184*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */ 1185*7c478bd9Sstevel@tonic-gate boot_sec = (struct mboot *)buf; 1186*7c478bd9Sstevel@tonic-gate 1187*7c478bd9Sstevel@tonic-gate /* Is this really a master boot record? */ 1188*7c478bd9Sstevel@tonic-gate if (les(boot_sec->signature) != MBB_MAGIC) { 1189*7c478bd9Sstevel@tonic-gate DPRINTF("fdisk: Invalid master boot file \n"); 1190*7c478bd9Sstevel@tonic-gate DPRINTF2("Bad magic number: is %x, should be %x.\n", 1191*7c478bd9Sstevel@tonic-gate les(boot_sec->signature), MBB_MAGIC); 1192*7c478bd9Sstevel@tonic-gate free(buf); 1193*7c478bd9Sstevel@tonic-gate return (-1); 1194*7c478bd9Sstevel@tonic-gate } 1195*7c478bd9Sstevel@tonic-gate 1196*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 1197*7c478bd9Sstevel@tonic-gate DPRINTF1("part %d\n", i); 1198*7c478bd9Sstevel@tonic-gate /* LINTED pointer cast may result in improper alignment */ 1199*7c478bd9Sstevel@tonic-gate part = (struct ipart *)&boot_sec->parts[i * 1200*7c478bd9Sstevel@tonic-gate sizeof (struct ipart)]; 1201*7c478bd9Sstevel@tonic-gate fdisk->part[i].bootid = part->bootid; 1202*7c478bd9Sstevel@tonic-gate if (part->bootid && (part->bootid != ACTIVE)) { 1203*7c478bd9Sstevel@tonic-gate /* Hmmm...not a valid fdisk! */ 1204*7c478bd9Sstevel@tonic-gate return (-1); 1205*7c478bd9Sstevel@tonic-gate } 1206*7c478bd9Sstevel@tonic-gate fdisk->part[i].systid = part->systid; 1207*7c478bd9Sstevel@tonic-gate 1208*7c478bd9Sstevel@tonic-gate /* To avoid the misalign access in sparc */ 1209*7c478bd9Sstevel@tonic-gate 1210*7c478bd9Sstevel@tonic-gate fdisk->part[i].relsect = lel(GET_32(&(part->relsect))); 1211*7c478bd9Sstevel@tonic-gate fdisk->part[i].numsect = lel(GET_32(&(part->numsect))); 1212*7c478bd9Sstevel@tonic-gate 1213*7c478bd9Sstevel@tonic-gate DPRINTF1("\tboot id 0x%x\n", part->bootid); 1214*7c478bd9Sstevel@tonic-gate DPRINTF1("\tsystem id 0x%x\n", part->systid); 1215*7c478bd9Sstevel@tonic-gate DPRINTF1("\trel sector 0x%x\n", fdisk->part[i].relsect); 1216*7c478bd9Sstevel@tonic-gate DPRINTF1("\tnum sector 0x%x\n", fdisk->part[i].numsect); 1217*7c478bd9Sstevel@tonic-gate } 1218*7c478bd9Sstevel@tonic-gate free(buf); 1219*7c478bd9Sstevel@tonic-gate return (0); 1220*7c478bd9Sstevel@tonic-gate } 1221*7c478bd9Sstevel@tonic-gate 1222*7c478bd9Sstevel@tonic-gate 1223*7c478bd9Sstevel@tonic-gate /* 1224*7c478bd9Sstevel@tonic-gate * wrrite_defualt_label(int32_t fd) 1225*7c478bd9Sstevel@tonic-gate * fd = file descriptor for the device. 1226*7c478bd9Sstevel@tonic-gate * 1227*7c478bd9Sstevel@tonic-gate * For sparc solaris 1228*7c478bd9Sstevel@tonic-gate * Create a vtoc partition with 1229*7c478bd9Sstevel@tonic-gate * slice 0 = slice 2 = medium capacity. 1230*7c478bd9Sstevel@tonic-gate * The cyl, head, sect (CHS) values are computed as done in sd 1231*7c478bd9Sstevel@tonic-gate * capacity <= 1GB, 1232*7c478bd9Sstevel@tonic-gate * nhead = 64, nsect = 32 1233*7c478bd9Sstevel@tonic-gate * capacity > 1gb, 1234*7c478bd9Sstevel@tonic-gate * nhead = 255, nsect = 63 1235*7c478bd9Sstevel@tonic-gate * 1236*7c478bd9Sstevel@tonic-gate * For x86 solaris 1237*7c478bd9Sstevel@tonic-gate * Create a fdisk partition, 1238*7c478bd9Sstevel@tonic-gate * partition 0 covers the full medium, the partition 1239*7c478bd9Sstevel@tonic-gate * type is set to Solaris. 1240*7c478bd9Sstevel@tonic-gate * Then create solaris vtoc. The algorithm is same as sparc solaris. 1241*7c478bd9Sstevel@tonic-gate * But the capacity is reduced by 1 cyl, to leave space for fdisk table. 1242*7c478bd9Sstevel@tonic-gate */ 1243*7c478bd9Sstevel@tonic-gate 1244*7c478bd9Sstevel@tonic-gate #ifdef sparc 1245*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 1246*7c478bd9Sstevel@tonic-gate void 1247*7c478bd9Sstevel@tonic-gate write_default_label(smedia_handle_t handle, int32_t fd) 1248*7c478bd9Sstevel@tonic-gate { 1249*7c478bd9Sstevel@tonic-gate 1250*7c478bd9Sstevel@tonic-gate struct vtoc v_toc; 1251*7c478bd9Sstevel@tonic-gate int32_t nhead, numcyl, nsect, capacity; 1252*7c478bd9Sstevel@tonic-gate int32_t ret; 1253*7c478bd9Sstevel@tonic-gate char asciilabel[LEN_DKL_ASCII]; 1254*7c478bd9Sstevel@tonic-gate char asciilabel2[LEN_DKL_ASCII] = "DEFAULT\0"; 1255*7c478bd9Sstevel@tonic-gate int32_t acyl = 2; 1256*7c478bd9Sstevel@tonic-gate 1257*7c478bd9Sstevel@tonic-gate 1258*7c478bd9Sstevel@tonic-gate DPRINTF("Writing default vtoc\n"); 1259*7c478bd9Sstevel@tonic-gate (void) memset(&v_toc, 0, sizeof (v_toc)); 1260*7c478bd9Sstevel@tonic-gate 1261*7c478bd9Sstevel@tonic-gate 1262*7c478bd9Sstevel@tonic-gate v_toc.v_nparts = V_NUMPAR; 1263*7c478bd9Sstevel@tonic-gate v_toc.v_sanity = VTOC_SANE; 1264*7c478bd9Sstevel@tonic-gate v_toc.v_version = V_VERSION; 1265*7c478bd9Sstevel@tonic-gate v_toc.v_sectorsz = DEV_BSIZE; 1266*7c478bd9Sstevel@tonic-gate 1267*7c478bd9Sstevel@tonic-gate /* 1268*7c478bd9Sstevel@tonic-gate * For the head, cyl and number of sector per track, 1269*7c478bd9Sstevel@tonic-gate * if the capacity <= 1GB, head = 64, sect = 32. 1270*7c478bd9Sstevel@tonic-gate * else head = 255, sect 63 1271*7c478bd9Sstevel@tonic-gate * NOTE: the capacity should be equal to C*H*S values. 1272*7c478bd9Sstevel@tonic-gate * This will cause some truncation of size due to 1273*7c478bd9Sstevel@tonic-gate * round off errors. 1274*7c478bd9Sstevel@tonic-gate */ 1275*7c478bd9Sstevel@tonic-gate if (med_info.sm_capacity <= 0x200000) { 1276*7c478bd9Sstevel@tonic-gate nhead = 64; 1277*7c478bd9Sstevel@tonic-gate nsect = 32; 1278*7c478bd9Sstevel@tonic-gate } else { 1279*7c478bd9Sstevel@tonic-gate nhead = 255; 1280*7c478bd9Sstevel@tonic-gate nsect = 63; 1281*7c478bd9Sstevel@tonic-gate } 1282*7c478bd9Sstevel@tonic-gate 1283*7c478bd9Sstevel@tonic-gate numcyl = med_info.sm_capacity / (nhead * nsect); 1284*7c478bd9Sstevel@tonic-gate capacity = nhead * nsect * numcyl; 1285*7c478bd9Sstevel@tonic-gate 1286*7c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_start = 0; 1287*7c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_size = capacity; 1288*7c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_tag = V_ROOT; 1289*7c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_flag = 0; /* Mountable */ 1290*7c478bd9Sstevel@tonic-gate 1291*7c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_start = 0; 1292*7c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_size = capacity; 1293*7c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_tag = V_BACKUP; 1294*7c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_flag = V_UNMNT; 1295*7c478bd9Sstevel@tonic-gate 1296*7c478bd9Sstevel@tonic-gate /* Create asciilabel for compatibility with format utility */ 1297*7c478bd9Sstevel@tonic-gate (void) snprintf(asciilabel, sizeof (asciilabel), 1298*7c478bd9Sstevel@tonic-gate "%s cyl %d alt %d hd %d sec %d", 1299*7c478bd9Sstevel@tonic-gate asciilabel2, numcyl, acyl, nhead, nsect); 1300*7c478bd9Sstevel@tonic-gate (void) memcpy(v_toc.v_asciilabel, asciilabel, 1301*7c478bd9Sstevel@tonic-gate LEN_DKL_ASCII); 1302*7c478bd9Sstevel@tonic-gate 1303*7c478bd9Sstevel@tonic-gate errno = 0; 1304*7c478bd9Sstevel@tonic-gate 1305*7c478bd9Sstevel@tonic-gate /* need the file_dac_write privilege */ 1306*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1307*7c478bd9Sstevel@tonic-gate (char *)NULL); 1308*7c478bd9Sstevel@tonic-gate 1309*7c478bd9Sstevel@tonic-gate ret = write_vtoc(fd, &v_toc); 1310*7c478bd9Sstevel@tonic-gate 1311*7c478bd9Sstevel@tonic-gate /* drop the file_dac_write privilege */ 1312*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1313*7c478bd9Sstevel@tonic-gate (char *)NULL); 1314*7c478bd9Sstevel@tonic-gate 1315*7c478bd9Sstevel@tonic-gate if (ret < 0) { 1316*7c478bd9Sstevel@tonic-gate PERROR("write VTOC failed"); 1317*7c478bd9Sstevel@tonic-gate DPRINTF1("Errno = %d\n", errno); 1318*7c478bd9Sstevel@tonic-gate } 1319*7c478bd9Sstevel@tonic-gate } 1320*7c478bd9Sstevel@tonic-gate 1321*7c478bd9Sstevel@tonic-gate #else /* !sparc */ 1322*7c478bd9Sstevel@tonic-gate #ifdef i386 1323*7c478bd9Sstevel@tonic-gate 1324*7c478bd9Sstevel@tonic-gate void 1325*7c478bd9Sstevel@tonic-gate write_default_label(smedia_handle_t handle, int32_t fd) 1326*7c478bd9Sstevel@tonic-gate { 1327*7c478bd9Sstevel@tonic-gate 1328*7c478bd9Sstevel@tonic-gate int32_t i, ret; 1329*7c478bd9Sstevel@tonic-gate struct dk_geom dkg; 1330*7c478bd9Sstevel@tonic-gate struct vtoc v_toc; 1331*7c478bd9Sstevel@tonic-gate int tmp_fd; 1332*7c478bd9Sstevel@tonic-gate char *fdisk_buf; 1333*7c478bd9Sstevel@tonic-gate struct mboot boot_code; /* Buffer for master boot record */ 1334*7c478bd9Sstevel@tonic-gate struct ipart parts[FD_NUMPART]; 1335*7c478bd9Sstevel@tonic-gate int32_t numcyl, nhead, nsect; 1336*7c478bd9Sstevel@tonic-gate int32_t unixend; 1337*7c478bd9Sstevel@tonic-gate int32_t blocksize; 1338*7c478bd9Sstevel@tonic-gate int32_t capacity; 1339*7c478bd9Sstevel@tonic-gate int save_errno; 1340*7c478bd9Sstevel@tonic-gate size_t bytes_written; 1341*7c478bd9Sstevel@tonic-gate char asciilabel[LEN_DKL_ASCII]; 1342*7c478bd9Sstevel@tonic-gate char asciilabel2[LEN_DKL_ASCII] = "DEFAULT\0"; 1343*7c478bd9Sstevel@tonic-gate int32_t acyl = 2; 1344*7c478bd9Sstevel@tonic-gate 1345*7c478bd9Sstevel@tonic-gate DPRINTF("Writing default fdisk table and vtoc\n"); 1346*7c478bd9Sstevel@tonic-gate (void) memset(&v_toc, 0, sizeof (v_toc)); 1347*7c478bd9Sstevel@tonic-gate /* 1348*7c478bd9Sstevel@tonic-gate * Try getting disk geometry. 1349*7c478bd9Sstevel@tonic-gate */ 1350*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &dkg) < 0) 1351*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCG_PHYGEOM, &dkg) < 0) { 1352*7c478bd9Sstevel@tonic-gate 1353*7c478bd9Sstevel@tonic-gate DPRINTF("DKIOCG_PHYGEOM ioctl failed"); 1354*7c478bd9Sstevel@tonic-gate return; 1355*7c478bd9Sstevel@tonic-gate } 1356*7c478bd9Sstevel@tonic-gate 1357*7c478bd9Sstevel@tonic-gate tmp_fd = open("/usr/lib/fs/ufs/mboot", O_RDONLY); 1358*7c478bd9Sstevel@tonic-gate if (tmp_fd <= 0) { 1359*7c478bd9Sstevel@tonic-gate return; 1360*7c478bd9Sstevel@tonic-gate } 1361*7c478bd9Sstevel@tonic-gate 1362*7c478bd9Sstevel@tonic-gate if (read(tmp_fd, &boot_code, sizeof (struct mboot)) 1363*7c478bd9Sstevel@tonic-gate != sizeof (struct mboot)) { 1364*7c478bd9Sstevel@tonic-gate (void) close(tmp_fd); 1365*7c478bd9Sstevel@tonic-gate return; 1366*7c478bd9Sstevel@tonic-gate } 1367*7c478bd9Sstevel@tonic-gate 1368*7c478bd9Sstevel@tonic-gate blocksize = med_info.sm_blocksize; 1369*7c478bd9Sstevel@tonic-gate fdisk_buf = (char *)malloc(blocksize); 1370*7c478bd9Sstevel@tonic-gate if (fdisk_buf == NULL) { 1371*7c478bd9Sstevel@tonic-gate DPRINTF("malloc for fdisk_buf failed\n"); 1372*7c478bd9Sstevel@tonic-gate return; 1373*7c478bd9Sstevel@tonic-gate } 1374*7c478bd9Sstevel@tonic-gate 1375*7c478bd9Sstevel@tonic-gate (void) memset(&parts, 0, sizeof (parts)); 1376*7c478bd9Sstevel@tonic-gate 1377*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 1378*7c478bd9Sstevel@tonic-gate parts[i].systid = UNUSED; 1379*7c478bd9Sstevel@tonic-gate parts[i].numsect = lel(UNUSED); 1380*7c478bd9Sstevel@tonic-gate parts[i].relsect = lel(UNUSED); 1381*7c478bd9Sstevel@tonic-gate parts[i].bootid = 0; 1382*7c478bd9Sstevel@tonic-gate } 1383*7c478bd9Sstevel@tonic-gate 1384*7c478bd9Sstevel@tonic-gate numcyl = dkg.dkg_ncyl; 1385*7c478bd9Sstevel@tonic-gate nhead = dkg.dkg_nhead; 1386*7c478bd9Sstevel@tonic-gate nsect = dkg.dkg_nsect; 1387*7c478bd9Sstevel@tonic-gate 1388*7c478bd9Sstevel@tonic-gate parts[0].bootid = ACTIVE; 1389*7c478bd9Sstevel@tonic-gate parts[0].begsect = 1; 1390*7c478bd9Sstevel@tonic-gate 1391*7c478bd9Sstevel@tonic-gate unixend = numcyl; 1392*7c478bd9Sstevel@tonic-gate 1393*7c478bd9Sstevel@tonic-gate parts[0].relsect = lel(nhead * nsect); 1394*7c478bd9Sstevel@tonic-gate parts[0].numsect = lel((long)((numcyl) * nhead * nsect)); 1395*7c478bd9Sstevel@tonic-gate parts[0].systid = SUNIXOS2; /* Solaris */ 1396*7c478bd9Sstevel@tonic-gate parts[0].beghead = 0; 1397*7c478bd9Sstevel@tonic-gate parts[0].begcyl = 1; 1398*7c478bd9Sstevel@tonic-gate parts[0].endhead = nhead - 1; 1399*7c478bd9Sstevel@tonic-gate parts[0].endsect = (nsect & 0x3f) | 1400*7c478bd9Sstevel@tonic-gate (char)((unixend >> 2) & 0x00c0); 1401*7c478bd9Sstevel@tonic-gate parts[0].endcyl = (char)(unixend & 0x00ff); 1402*7c478bd9Sstevel@tonic-gate 1403*7c478bd9Sstevel@tonic-gate (void) memcpy(&(boot_code.parts), parts, sizeof (parts)); 1404*7c478bd9Sstevel@tonic-gate (void) memcpy(fdisk_buf, &boot_code, sizeof (boot_code)); 1405*7c478bd9Sstevel@tonic-gate 1406*7c478bd9Sstevel@tonic-gate /* need the file_dac_write privilege */ 1407*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1408*7c478bd9Sstevel@tonic-gate (char *)NULL); 1409*7c478bd9Sstevel@tonic-gate 1410*7c478bd9Sstevel@tonic-gate ret = ioctl(fd, DKIOCSMBOOT, fdisk_buf); 1411*7c478bd9Sstevel@tonic-gate 1412*7c478bd9Sstevel@tonic-gate /* drop the file_dac_write privilege */ 1413*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1414*7c478bd9Sstevel@tonic-gate (char *)NULL); 1415*7c478bd9Sstevel@tonic-gate 1416*7c478bd9Sstevel@tonic-gate if (ret == -1) { 1417*7c478bd9Sstevel@tonic-gate if (errno != ENOTTY) { 1418*7c478bd9Sstevel@tonic-gate PERROR("DKIOCSMBOOT ioctl Failed"); 1419*7c478bd9Sstevel@tonic-gate return; 1420*7c478bd9Sstevel@tonic-gate } 1421*7c478bd9Sstevel@tonic-gate 1422*7c478bd9Sstevel@tonic-gate /* need the file_dac_write privilege */ 1423*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1424*7c478bd9Sstevel@tonic-gate (char *)NULL); 1425*7c478bd9Sstevel@tonic-gate 1426*7c478bd9Sstevel@tonic-gate bytes_written = smedia_raw_write(handle, 0, fdisk_buf, 1427*7c478bd9Sstevel@tonic-gate blocksize); 1428*7c478bd9Sstevel@tonic-gate 1429*7c478bd9Sstevel@tonic-gate /* drop the file_dac_write privilege */ 1430*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1431*7c478bd9Sstevel@tonic-gate (char *)NULL); 1432*7c478bd9Sstevel@tonic-gate 1433*7c478bd9Sstevel@tonic-gate save_errno = errno; 1434*7c478bd9Sstevel@tonic-gate errno = save_errno; 1435*7c478bd9Sstevel@tonic-gate if (bytes_written != blocksize) { 1436*7c478bd9Sstevel@tonic-gate if (errno == ENOTSUP) { 1437*7c478bd9Sstevel@tonic-gate 1438*7c478bd9Sstevel@tonic-gate /* need the file_dac_write privilege */ 1439*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, 1440*7c478bd9Sstevel@tonic-gate PRIV_FILE_DAC_WRITE, (char *)NULL); 1441*7c478bd9Sstevel@tonic-gate 1442*7c478bd9Sstevel@tonic-gate ret = write(fd, fdisk_buf, blocksize); 1443*7c478bd9Sstevel@tonic-gate 1444*7c478bd9Sstevel@tonic-gate /* drop the file_dac_write privilege */ 1445*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, 1446*7c478bd9Sstevel@tonic-gate PRIV_FILE_DAC_WRITE, (char *)NULL); 1447*7c478bd9Sstevel@tonic-gate 1448*7c478bd9Sstevel@tonic-gate if (ret != blocksize) { 1449*7c478bd9Sstevel@tonic-gate return; 1450*7c478bd9Sstevel@tonic-gate } 1451*7c478bd9Sstevel@tonic-gate } else { 1452*7c478bd9Sstevel@tonic-gate return; 1453*7c478bd9Sstevel@tonic-gate } 1454*7c478bd9Sstevel@tonic-gate } 1455*7c478bd9Sstevel@tonic-gate } 1456*7c478bd9Sstevel@tonic-gate capacity = (numcyl - 1) * nhead * nsect; 1457*7c478bd9Sstevel@tonic-gate 1458*7c478bd9Sstevel@tonic-gate v_toc.v_nparts = V_NUMPAR; 1459*7c478bd9Sstevel@tonic-gate v_toc.v_sanity = VTOC_SANE; 1460*7c478bd9Sstevel@tonic-gate v_toc.v_version = V_VERSION; 1461*7c478bd9Sstevel@tonic-gate v_toc.v_sectorsz = DEV_BSIZE; 1462*7c478bd9Sstevel@tonic-gate 1463*7c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_start = 0; 1464*7c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_size = capacity; 1465*7c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_tag = V_ROOT; 1466*7c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_flag = 0; /* Mountable */ 1467*7c478bd9Sstevel@tonic-gate 1468*7c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_start = 0; 1469*7c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_size = capacity; 1470*7c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_tag = V_BACKUP; 1471*7c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_flag = V_UNMNT; 1472*7c478bd9Sstevel@tonic-gate 1473*7c478bd9Sstevel@tonic-gate /* Create asciilabel for compatibility with format utility */ 1474*7c478bd9Sstevel@tonic-gate (void) snprintf(asciilabel, sizeof (asciilabel), 1475*7c478bd9Sstevel@tonic-gate "%s cyl %d alt %d hd %d sec %d", 1476*7c478bd9Sstevel@tonic-gate asciilabel2, numcyl, acyl, nhead, nsect); 1477*7c478bd9Sstevel@tonic-gate (void) memcpy(v_toc.v_asciilabel, asciilabel, 1478*7c478bd9Sstevel@tonic-gate LEN_DKL_ASCII); 1479*7c478bd9Sstevel@tonic-gate 1480*7c478bd9Sstevel@tonic-gate errno = 0; 1481*7c478bd9Sstevel@tonic-gate 1482*7c478bd9Sstevel@tonic-gate 1483*7c478bd9Sstevel@tonic-gate /* need the file_dac_write privilege */ 1484*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1485*7c478bd9Sstevel@tonic-gate (char *)NULL); 1486*7c478bd9Sstevel@tonic-gate 1487*7c478bd9Sstevel@tonic-gate ret = write_vtoc(fd, &v_toc); 1488*7c478bd9Sstevel@tonic-gate 1489*7c478bd9Sstevel@tonic-gate /* drop the file_dac_write privilege */ 1490*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1491*7c478bd9Sstevel@tonic-gate (char *)NULL); 1492*7c478bd9Sstevel@tonic-gate 1493*7c478bd9Sstevel@tonic-gate if (ret < 0) { 1494*7c478bd9Sstevel@tonic-gate PERROR("write VTOC failed"); 1495*7c478bd9Sstevel@tonic-gate DPRINTF1("Errno = %d\n", errno); 1496*7c478bd9Sstevel@tonic-gate } 1497*7c478bd9Sstevel@tonic-gate } 1498*7c478bd9Sstevel@tonic-gate 1499*7c478bd9Sstevel@tonic-gate #else /* !i386 */ 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate #error One of sparc or i386 must be defined! 1502*7c478bd9Sstevel@tonic-gate 1503*7c478bd9Sstevel@tonic-gate #endif /* i386 */ 1504*7c478bd9Sstevel@tonic-gate #endif /* sparc */ 1505*7c478bd9Sstevel@tonic-gate 1506*7c478bd9Sstevel@tonic-gate /* 1507*7c478bd9Sstevel@tonic-gate * void overwrite_metadata(int32_t fd, smedia_handle_t handle) 1508*7c478bd9Sstevel@tonic-gate * 1509*7c478bd9Sstevel@tonic-gate * purpose : quick format does not erase the data on Iomega 1510*7c478bd9Sstevel@tonic-gate * zip/jaz media. So, the meta data on the disk should be erased. 1511*7c478bd9Sstevel@tonic-gate * 1512*7c478bd9Sstevel@tonic-gate * If there is a valid fdisk table, 1513*7c478bd9Sstevel@tonic-gate * erase first 64K of each partition. 1514*7c478bd9Sstevel@tonic-gate * If there is a valid vtoc, 1515*7c478bd9Sstevel@tonic-gate * erase first 64k of each slice. 1516*7c478bd9Sstevel@tonic-gate * Then erase the 0th sector (the home for vtoc and fdisk) of the disk. 1517*7c478bd9Sstevel@tonic-gate * Note that teh vtoc on x86 resides in one of the fdisk partition. 1518*7c478bd9Sstevel@tonic-gate * So delay the erasing of the solaris partition until the vtoc is read. 1519*7c478bd9Sstevel@tonic-gate */ 1520*7c478bd9Sstevel@tonic-gate 1521*7c478bd9Sstevel@tonic-gate void 1522*7c478bd9Sstevel@tonic-gate overwrite_metadata(int32_t fd, smedia_handle_t handle) 1523*7c478bd9Sstevel@tonic-gate { 1524*7c478bd9Sstevel@tonic-gate 1525*7c478bd9Sstevel@tonic-gate struct fdisk_info fdisk; 1526*7c478bd9Sstevel@tonic-gate uint32_t sol_offset = 0; 1527*7c478bd9Sstevel@tonic-gate int i, ret; 1528*7c478bd9Sstevel@tonic-gate struct vtoc t_vtoc; 1529*7c478bd9Sstevel@tonic-gate #ifdef i386 1530*7c478bd9Sstevel@tonic-gate uint32_t sol_size = 0; 1531*7c478bd9Sstevel@tonic-gate int32_t active = 0; 1532*7c478bd9Sstevel@tonic-gate #endif /* i386 */ 1533*7c478bd9Sstevel@tonic-gate 1534*7c478bd9Sstevel@tonic-gate /* Get fdisk info. */ 1535*7c478bd9Sstevel@tonic-gate if (get_fdisk(handle, fd, 0, &fdisk) >= 0) { 1536*7c478bd9Sstevel@tonic-gate /* Got a valid fdisk */ 1537*7c478bd9Sstevel@tonic-gate for (i = 0; i < FD_NUMPART; i++) { 1538*7c478bd9Sstevel@tonic-gate 1539*7c478bd9Sstevel@tonic-gate if (fdisk.part[i].numsect == 0) 1540*7c478bd9Sstevel@tonic-gate continue; 1541*7c478bd9Sstevel@tonic-gate if ((fdisk.part[i].systid == UNUSED) || 1542*7c478bd9Sstevel@tonic-gate (fdisk.part[i].systid == 0)) 1543*7c478bd9Sstevel@tonic-gate continue; 1544*7c478bd9Sstevel@tonic-gate #ifdef i386 1545*7c478bd9Sstevel@tonic-gate if (fdisk.part[i].systid == SUNIXOS || 1546*7c478bd9Sstevel@tonic-gate fdisk.part[i].systid == SUNIXOS2) { 1547*7c478bd9Sstevel@tonic-gate if (!sol_offset) { 1548*7c478bd9Sstevel@tonic-gate sol_offset = fdisk.part[i].relsect; 1549*7c478bd9Sstevel@tonic-gate sol_size = fdisk.part[i].numsect; 1550*7c478bd9Sstevel@tonic-gate if (fdisk.part[i].bootid == ACTIVE) 1551*7c478bd9Sstevel@tonic-gate active = 1; 1552*7c478bd9Sstevel@tonic-gate continue; 1553*7c478bd9Sstevel@tonic-gate } else if ((fdisk.part[i].bootid == ACTIVE) && 1554*7c478bd9Sstevel@tonic-gate (!active)) { 1555*7c478bd9Sstevel@tonic-gate erase(handle, sol_offset, sol_size); 1556*7c478bd9Sstevel@tonic-gate sol_offset = fdisk.part[i].relsect; 1557*7c478bd9Sstevel@tonic-gate sol_size = fdisk.part[i].numsect; 1558*7c478bd9Sstevel@tonic-gate active = 1; 1559*7c478bd9Sstevel@tonic-gate continue; 1560*7c478bd9Sstevel@tonic-gate } 1561*7c478bd9Sstevel@tonic-gate } 1562*7c478bd9Sstevel@tonic-gate #endif /* i386 */ 1563*7c478bd9Sstevel@tonic-gate erase(handle, fdisk.part[i].relsect, 1564*7c478bd9Sstevel@tonic-gate fdisk.part[i].numsect); 1565*7c478bd9Sstevel@tonic-gate } 1566*7c478bd9Sstevel@tonic-gate } 1567*7c478bd9Sstevel@tonic-gate 1568*7c478bd9Sstevel@tonic-gate (void) memset(&t_vtoc, 0, sizeof (t_vtoc)); 1569*7c478bd9Sstevel@tonic-gate 1570*7c478bd9Sstevel@tonic-gate if (sol_offset) { 1571*7c478bd9Sstevel@tonic-gate /* fdisk x86 Solaris partition */ 1572*7c478bd9Sstevel@tonic-gate /* VTOC location in solaris partition is DK_LABEL_LOC */ 1573*7c478bd9Sstevel@tonic-gate 1574*7c478bd9Sstevel@tonic-gate /* need the file_dac_read privilege */ 1575*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, 1576*7c478bd9Sstevel@tonic-gate (char *)NULL); 1577*7c478bd9Sstevel@tonic-gate 1578*7c478bd9Sstevel@tonic-gate ret = read_vtoc(fd, &t_vtoc); 1579*7c478bd9Sstevel@tonic-gate 1580*7c478bd9Sstevel@tonic-gate /* drop the file_dac_read privilege */ 1581*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, 1582*7c478bd9Sstevel@tonic-gate (char *)NULL); 1583*7c478bd9Sstevel@tonic-gate 1584*7c478bd9Sstevel@tonic-gate if (ret < 0) { 1585*7c478bd9Sstevel@tonic-gate /* No valid vtoc, erase fdisk table. */ 1586*7c478bd9Sstevel@tonic-gate erase(handle, 0, 1); 1587*7c478bd9Sstevel@tonic-gate return; 1588*7c478bd9Sstevel@tonic-gate } 1589*7c478bd9Sstevel@tonic-gate } else { 1590*7c478bd9Sstevel@tonic-gate /* Sparc Solaris or x86 solaris with faked fdisk */ 1591*7c478bd9Sstevel@tonic-gate 1592*7c478bd9Sstevel@tonic-gate /* need the file_dac_read privilege */ 1593*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, 1594*7c478bd9Sstevel@tonic-gate (char *)NULL); 1595*7c478bd9Sstevel@tonic-gate 1596*7c478bd9Sstevel@tonic-gate ret = read_vtoc(fd, &t_vtoc); 1597*7c478bd9Sstevel@tonic-gate 1598*7c478bd9Sstevel@tonic-gate /* drop the file_dac_read privilege */ 1599*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ, 1600*7c478bd9Sstevel@tonic-gate (char *)NULL); 1601*7c478bd9Sstevel@tonic-gate 1602*7c478bd9Sstevel@tonic-gate if (ret < 0) { 1603*7c478bd9Sstevel@tonic-gate /* No valid vtoc, erase from 0th sector */ 1604*7c478bd9Sstevel@tonic-gate erase(handle, 0, med_info.sm_capacity); 1605*7c478bd9Sstevel@tonic-gate return; 1606*7c478bd9Sstevel@tonic-gate } 1607*7c478bd9Sstevel@tonic-gate } 1608*7c478bd9Sstevel@tonic-gate 1609*7c478bd9Sstevel@tonic-gate for (i = 0; i < V_NUMPAR; i++) { 1610*7c478bd9Sstevel@tonic-gate if (t_vtoc.v_part[i].p_size != 0) { 1611*7c478bd9Sstevel@tonic-gate erase(handle, sol_offset + t_vtoc.v_part[i].p_start, 1612*7c478bd9Sstevel@tonic-gate t_vtoc.v_part[i].p_size); 1613*7c478bd9Sstevel@tonic-gate /* 1614*7c478bd9Sstevel@tonic-gate * To make the udfs not recognise the partition we will 1615*7c478bd9Sstevel@tonic-gate * erase sectors 256, (p_size-256) and psize. 1616*7c478bd9Sstevel@tonic-gate */ 1617*7c478bd9Sstevel@tonic-gate erase(handle, 1618*7c478bd9Sstevel@tonic-gate sol_offset + t_vtoc.v_part[i].p_start + 256, 1619*7c478bd9Sstevel@tonic-gate 1); 1620*7c478bd9Sstevel@tonic-gate erase(handle, 1621*7c478bd9Sstevel@tonic-gate (sol_offset + t_vtoc.v_part[i].p_start + 1622*7c478bd9Sstevel@tonic-gate t_vtoc.v_part[i].p_size - 256), 1623*7c478bd9Sstevel@tonic-gate 1); 1624*7c478bd9Sstevel@tonic-gate erase(handle, 1625*7c478bd9Sstevel@tonic-gate (sol_offset + t_vtoc.v_part[i].p_start + 1626*7c478bd9Sstevel@tonic-gate t_vtoc.v_part[i].p_size - 1), 1627*7c478bd9Sstevel@tonic-gate 1); 1628*7c478bd9Sstevel@tonic-gate } 1629*7c478bd9Sstevel@tonic-gate } 1630*7c478bd9Sstevel@tonic-gate 1631*7c478bd9Sstevel@tonic-gate /* 1632*7c478bd9Sstevel@tonic-gate * If x86 fdisk solaris partition, erase the vtoc also. 1633*7c478bd9Sstevel@tonic-gate * for sparc, the erasing 0the sector erases vtoc. 1634*7c478bd9Sstevel@tonic-gate */ 1635*7c478bd9Sstevel@tonic-gate if (sol_offset) { 1636*7c478bd9Sstevel@tonic-gate erase(handle, sol_offset, DK_LABEL_LOC + 2); 1637*7c478bd9Sstevel@tonic-gate } 1638*7c478bd9Sstevel@tonic-gate 1639*7c478bd9Sstevel@tonic-gate /* 1640*7c478bd9Sstevel@tonic-gate * erase the 0th sector, it is not guaranteed to be 1641*7c478bd9Sstevel@tonic-gate * erased in the above sequence. 1642*7c478bd9Sstevel@tonic-gate */ 1643*7c478bd9Sstevel@tonic-gate 1644*7c478bd9Sstevel@tonic-gate erase(handle, 0, 1); 1645*7c478bd9Sstevel@tonic-gate } 1646*7c478bd9Sstevel@tonic-gate 1647*7c478bd9Sstevel@tonic-gate /* 1648*7c478bd9Sstevel@tonic-gate * void erase(smedia_handle_t handle, uint32_t offset, uint32_t size) 1649*7c478bd9Sstevel@tonic-gate * 1650*7c478bd9Sstevel@tonic-gate * Initialize the media with '0' from offset 'offset' upto 'size' 1651*7c478bd9Sstevel@tonic-gate * or 128 blocks(64k), whichever is smaller. 1652*7c478bd9Sstevel@tonic-gate */ 1653*7c478bd9Sstevel@tonic-gate 1654*7c478bd9Sstevel@tonic-gate static void 1655*7c478bd9Sstevel@tonic-gate erase(smedia_handle_t handle, uint32_t offset, uint32_t size) 1656*7c478bd9Sstevel@tonic-gate { 1657*7c478bd9Sstevel@tonic-gate char *buf; 1658*7c478bd9Sstevel@tonic-gate int32_t nblocks = size; 1659*7c478bd9Sstevel@tonic-gate int32_t ret; 1660*7c478bd9Sstevel@tonic-gate 1661*7c478bd9Sstevel@tonic-gate 1662*7c478bd9Sstevel@tonic-gate nblocks = (nblocks < 128) ? nblocks : 128; 1663*7c478bd9Sstevel@tonic-gate buf = (char *)malloc(nblocks * med_info.sm_blocksize); 1664*7c478bd9Sstevel@tonic-gate if (buf == NULL) { 1665*7c478bd9Sstevel@tonic-gate PERROR("malloc failed"); 1666*7c478bd9Sstevel@tonic-gate return; 1667*7c478bd9Sstevel@tonic-gate } 1668*7c478bd9Sstevel@tonic-gate (void) memset(buf, 0, nblocks * med_info.sm_blocksize); 1669*7c478bd9Sstevel@tonic-gate 1670*7c478bd9Sstevel@tonic-gate /* need the file_dac_write privilege */ 1671*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1672*7c478bd9Sstevel@tonic-gate (char *)NULL); 1673*7c478bd9Sstevel@tonic-gate 1674*7c478bd9Sstevel@tonic-gate ret = smedia_raw_write(handle, offset, buf, 1675*7c478bd9Sstevel@tonic-gate nblocks * med_info.sm_blocksize); 1676*7c478bd9Sstevel@tonic-gate 1677*7c478bd9Sstevel@tonic-gate /* drop the file_dac_write privilege */ 1678*7c478bd9Sstevel@tonic-gate (void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_WRITE, 1679*7c478bd9Sstevel@tonic-gate (char *)NULL); 1680*7c478bd9Sstevel@tonic-gate 1681*7c478bd9Sstevel@tonic-gate if (ret != (nblocks * med_info.sm_blocksize)) 1682*7c478bd9Sstevel@tonic-gate PERROR("error in writing\n"); 1683*7c478bd9Sstevel@tonic-gate 1684*7c478bd9Sstevel@tonic-gate free(buf); 1685*7c478bd9Sstevel@tonic-gate 1686*7c478bd9Sstevel@tonic-gate } 1687