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 * This file contains the code to perform program startup. This 31*7c478bd9Sstevel@tonic-gate * includes reading the data file and the search for disks. 32*7c478bd9Sstevel@tonic-gate */ 33*7c478bd9Sstevel@tonic-gate #include "global.h" 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include <ctype.h> 36*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 37*7c478bd9Sstevel@tonic-gate #include <unistd.h> 38*7c478bd9Sstevel@tonic-gate #include <string.h> 39*7c478bd9Sstevel@tonic-gate #include <strings.h> 40*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 41*7c478bd9Sstevel@tonic-gate #include <errno.h> 42*7c478bd9Sstevel@tonic-gate #include <memory.h> 43*7c478bd9Sstevel@tonic-gate #include <dirent.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #include "startup.h" 49*7c478bd9Sstevel@tonic-gate #include "param.h" 50*7c478bd9Sstevel@tonic-gate #include "label.h" 51*7c478bd9Sstevel@tonic-gate #include "misc.h" 52*7c478bd9Sstevel@tonic-gate #include "menu_command.h" 53*7c478bd9Sstevel@tonic-gate #include "partition.h" 54*7c478bd9Sstevel@tonic-gate #include "ctlr_scsi.h" 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #include "auto_sense.h" 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate extern struct ctlr_type ctlr_types[]; 59*7c478bd9Sstevel@tonic-gate extern int nctypes; 60*7c478bd9Sstevel@tonic-gate extern struct ctlr_ops genericops; 61*7c478bd9Sstevel@tonic-gate extern long strtol(); 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate extern int errno; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate /* Function prototypes for ANSI C Compilers */ 68*7c478bd9Sstevel@tonic-gate static void usage(void); 69*7c478bd9Sstevel@tonic-gate static int sup_prxfile(void); 70*7c478bd9Sstevel@tonic-gate static void sup_setpath(void); 71*7c478bd9Sstevel@tonic-gate static void sup_setdtype(void); 72*7c478bd9Sstevel@tonic-gate static int sup_change_spec(struct disk_type *, char *); 73*7c478bd9Sstevel@tonic-gate static void sup_setpart(void); 74*7c478bd9Sstevel@tonic-gate static void search_for_logical_dev(char *devname); 75*7c478bd9Sstevel@tonic-gate static void add_device_to_disklist(char *devname, char *devpath); 76*7c478bd9Sstevel@tonic-gate static int disk_is_known(struct dk_cinfo *dkinfo); 77*7c478bd9Sstevel@tonic-gate static void datafile_error(char *errmsg, char *token); 78*7c478bd9Sstevel@tonic-gate static void search_duplicate_dtypes(void); 79*7c478bd9Sstevel@tonic-gate static void search_duplicate_pinfo(void); 80*7c478bd9Sstevel@tonic-gate static void check_dtypes_for_inconsistency(struct disk_type *dp1, 81*7c478bd9Sstevel@tonic-gate struct disk_type *dp2); 82*7c478bd9Sstevel@tonic-gate static void check_pinfo_for_inconsistency(struct partition_info *pp1, 83*7c478bd9Sstevel@tonic-gate struct partition_info *pp2); 84*7c478bd9Sstevel@tonic-gate static int str2blks(char *str); 85*7c478bd9Sstevel@tonic-gate static int str2cyls(char *str); 86*7c478bd9Sstevel@tonic-gate static struct chg_list *new_chg_list(struct disk_type *); 87*7c478bd9Sstevel@tonic-gate static char *get_physical_name(char *); 88*7c478bd9Sstevel@tonic-gate static void sort_disk_list(void); 89*7c478bd9Sstevel@tonic-gate static int disk_name_compare(const void *, const void *); 90*7c478bd9Sstevel@tonic-gate static void make_controller_list(void); 91*7c478bd9Sstevel@tonic-gate static void check_for_duplicate_disknames(char *arglist[]); 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* Function prototypes for non-ANSI C Compilers */ 96*7c478bd9Sstevel@tonic-gate static void usage(); 97*7c478bd9Sstevel@tonic-gate static int sup_prxfile(); 98*7c478bd9Sstevel@tonic-gate static void sup_setpath(); 99*7c478bd9Sstevel@tonic-gate static void sup_setdtype(); 100*7c478bd9Sstevel@tonic-gate static int sup_change_spec(); 101*7c478bd9Sstevel@tonic-gate static void sup_setpart(); 102*7c478bd9Sstevel@tonic-gate static void search_for_logical_dev(); 103*7c478bd9Sstevel@tonic-gate static void add_device_to_disklist(); 104*7c478bd9Sstevel@tonic-gate static int disk_is_known(); 105*7c478bd9Sstevel@tonic-gate static void datafile_error(); 106*7c478bd9Sstevel@tonic-gate static void search_duplicate_dtypes(); 107*7c478bd9Sstevel@tonic-gate static void search_duplicate_pinfo(); 108*7c478bd9Sstevel@tonic-gate static void check_dtypes_for_inconsistency(); 109*7c478bd9Sstevel@tonic-gate static void check_pinfo_for_inconsistency(); 110*7c478bd9Sstevel@tonic-gate static int str2blks(); 111*7c478bd9Sstevel@tonic-gate static int str2cyls(); 112*7c478bd9Sstevel@tonic-gate static struct chg_list *new_chg_list(); 113*7c478bd9Sstevel@tonic-gate static char *get_physical_name(); 114*7c478bd9Sstevel@tonic-gate static void sort_disk_list(); 115*7c478bd9Sstevel@tonic-gate static int disk_name_compare(); 116*7c478bd9Sstevel@tonic-gate static void make_controller_list(); 117*7c478bd9Sstevel@tonic-gate static void check_for_duplicate_disknames(); 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate #if defined(sparc) 122*7c478bd9Sstevel@tonic-gate static char *other_ctlrs[] = { 123*7c478bd9Sstevel@tonic-gate "ata" 124*7c478bd9Sstevel@tonic-gate }; 125*7c478bd9Sstevel@tonic-gate #define OTHER_CTLRS 1 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate #elif defined(i386) 128*7c478bd9Sstevel@tonic-gate static char *other_ctlrs[] = { 129*7c478bd9Sstevel@tonic-gate "ISP-80" 130*7c478bd9Sstevel@tonic-gate }; 131*7c478bd9Sstevel@tonic-gate #define OTHER_CTLRS 2 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate #else 134*7c478bd9Sstevel@tonic-gate #error No Platform defined. 135*7c478bd9Sstevel@tonic-gate #endif 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* 139*7c478bd9Sstevel@tonic-gate * This global is used to store the current line # in the data file. 140*7c478bd9Sstevel@tonic-gate * It must be global because the I/O routines are allowed to side 141*7c478bd9Sstevel@tonic-gate * effect it to keep track of backslashed newlines. 142*7c478bd9Sstevel@tonic-gate */ 143*7c478bd9Sstevel@tonic-gate int data_lineno; /* current line # in data file */ 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate /* 146*7c478bd9Sstevel@tonic-gate * Search path as defined in the format.dat files 147*7c478bd9Sstevel@tonic-gate */ 148*7c478bd9Sstevel@tonic-gate static char **search_path = NULL; 149*7c478bd9Sstevel@tonic-gate 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate static int name_represents_wholedisk(char *name); 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate /* 156*7c478bd9Sstevel@tonic-gate * This routine digests the options on the command line. It returns 157*7c478bd9Sstevel@tonic-gate * the index into argv of the first string that is not an option. If 158*7c478bd9Sstevel@tonic-gate * there are none, it returns -1. 159*7c478bd9Sstevel@tonic-gate */ 160*7c478bd9Sstevel@tonic-gate int 161*7c478bd9Sstevel@tonic-gate do_options(int argc, char *argv[]) 162*7c478bd9Sstevel@tonic-gate { 163*7c478bd9Sstevel@tonic-gate char *ptr; 164*7c478bd9Sstevel@tonic-gate int i; 165*7c478bd9Sstevel@tonic-gate int next; 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate /* 168*7c478bd9Sstevel@tonic-gate * Default is no extended messages. Can be enabled manually. 169*7c478bd9Sstevel@tonic-gate */ 170*7c478bd9Sstevel@tonic-gate option_msg = 0; 171*7c478bd9Sstevel@tonic-gate diag_msg = 0; 172*7c478bd9Sstevel@tonic-gate expert_mode = 0; 173*7c478bd9Sstevel@tonic-gate need_newline = 0; 174*7c478bd9Sstevel@tonic-gate dev_expert = 0; 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate /* 177*7c478bd9Sstevel@tonic-gate * Loop through the argument list, incrementing each time by 178*7c478bd9Sstevel@tonic-gate * an amount determined by the options found. 179*7c478bd9Sstevel@tonic-gate */ 180*7c478bd9Sstevel@tonic-gate for (i = 1; i < argc; i = next) { 181*7c478bd9Sstevel@tonic-gate /* 182*7c478bd9Sstevel@tonic-gate * Start out assuming an increment of 1. 183*7c478bd9Sstevel@tonic-gate */ 184*7c478bd9Sstevel@tonic-gate next = i + 1; 185*7c478bd9Sstevel@tonic-gate /* 186*7c478bd9Sstevel@tonic-gate * As soon as we hit a non-option, we're done. 187*7c478bd9Sstevel@tonic-gate */ 188*7c478bd9Sstevel@tonic-gate if (*argv[i] != '-') 189*7c478bd9Sstevel@tonic-gate return (i); 190*7c478bd9Sstevel@tonic-gate /* 191*7c478bd9Sstevel@tonic-gate * Loop through all the characters in this option string. 192*7c478bd9Sstevel@tonic-gate */ 193*7c478bd9Sstevel@tonic-gate for (ptr = argv[i] + 1; *ptr != '\0'; ptr++) { 194*7c478bd9Sstevel@tonic-gate /* 195*7c478bd9Sstevel@tonic-gate * Determine each option represented. For options 196*7c478bd9Sstevel@tonic-gate * that use a second string, increase the increment 197*7c478bd9Sstevel@tonic-gate * of the main loop so they aren't re-interpreted. 198*7c478bd9Sstevel@tonic-gate */ 199*7c478bd9Sstevel@tonic-gate switch (*ptr) { 200*7c478bd9Sstevel@tonic-gate case 's': 201*7c478bd9Sstevel@tonic-gate case 'S': 202*7c478bd9Sstevel@tonic-gate option_s = 1; 203*7c478bd9Sstevel@tonic-gate break; 204*7c478bd9Sstevel@tonic-gate case 'f': 205*7c478bd9Sstevel@tonic-gate case 'F': 206*7c478bd9Sstevel@tonic-gate option_f = argv[next++]; 207*7c478bd9Sstevel@tonic-gate if (next > argc) 208*7c478bd9Sstevel@tonic-gate goto badopt; 209*7c478bd9Sstevel@tonic-gate break; 210*7c478bd9Sstevel@tonic-gate case 'l': 211*7c478bd9Sstevel@tonic-gate case 'L': 212*7c478bd9Sstevel@tonic-gate option_l = argv[next++]; 213*7c478bd9Sstevel@tonic-gate if (next > argc) 214*7c478bd9Sstevel@tonic-gate goto badopt; 215*7c478bd9Sstevel@tonic-gate break; 216*7c478bd9Sstevel@tonic-gate case 'x': 217*7c478bd9Sstevel@tonic-gate case 'X': 218*7c478bd9Sstevel@tonic-gate option_x = argv[next++]; 219*7c478bd9Sstevel@tonic-gate if (next > argc) 220*7c478bd9Sstevel@tonic-gate goto badopt; 221*7c478bd9Sstevel@tonic-gate break; 222*7c478bd9Sstevel@tonic-gate case 'd': 223*7c478bd9Sstevel@tonic-gate case 'D': 224*7c478bd9Sstevel@tonic-gate option_d = argv[next++]; 225*7c478bd9Sstevel@tonic-gate if (next > argc) 226*7c478bd9Sstevel@tonic-gate goto badopt; 227*7c478bd9Sstevel@tonic-gate break; 228*7c478bd9Sstevel@tonic-gate case 't': 229*7c478bd9Sstevel@tonic-gate case 'T': 230*7c478bd9Sstevel@tonic-gate option_t = argv[next++]; 231*7c478bd9Sstevel@tonic-gate if (next > argc) 232*7c478bd9Sstevel@tonic-gate goto badopt; 233*7c478bd9Sstevel@tonic-gate break; 234*7c478bd9Sstevel@tonic-gate case 'p': 235*7c478bd9Sstevel@tonic-gate case 'P': 236*7c478bd9Sstevel@tonic-gate option_p = argv[next++]; 237*7c478bd9Sstevel@tonic-gate if (next > argc) 238*7c478bd9Sstevel@tonic-gate goto badopt; 239*7c478bd9Sstevel@tonic-gate break; 240*7c478bd9Sstevel@tonic-gate case 'm': 241*7c478bd9Sstevel@tonic-gate option_msg = 1; 242*7c478bd9Sstevel@tonic-gate break; 243*7c478bd9Sstevel@tonic-gate case 'M': 244*7c478bd9Sstevel@tonic-gate option_msg = 1; 245*7c478bd9Sstevel@tonic-gate diag_msg = 1; 246*7c478bd9Sstevel@tonic-gate break; 247*7c478bd9Sstevel@tonic-gate case 'e': 248*7c478bd9Sstevel@tonic-gate expert_mode = 1; 249*7c478bd9Sstevel@tonic-gate break; 250*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 251*7c478bd9Sstevel@tonic-gate case 'z': 252*7c478bd9Sstevel@tonic-gate dev_expert = 1; 253*7c478bd9Sstevel@tonic-gate break; 254*7c478bd9Sstevel@tonic-gate #endif 255*7c478bd9Sstevel@tonic-gate default: 256*7c478bd9Sstevel@tonic-gate badopt: 257*7c478bd9Sstevel@tonic-gate usage(); 258*7c478bd9Sstevel@tonic-gate break; 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate /* 263*7c478bd9Sstevel@tonic-gate * All the command line strings were options. Return that fact. 264*7c478bd9Sstevel@tonic-gate */ 265*7c478bd9Sstevel@tonic-gate return (-1); 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate static void 270*7c478bd9Sstevel@tonic-gate usage() 271*7c478bd9Sstevel@tonic-gate { 272*7c478bd9Sstevel@tonic-gate err_print("Usage: format [-s][-d disk_name]"); 273*7c478bd9Sstevel@tonic-gate err_print("[-t disk_type][-p partition_name]\n"); 274*7c478bd9Sstevel@tonic-gate err_print("\t[-f cmd_file][-l log_file]"); 275*7c478bd9Sstevel@tonic-gate err_print("[-x data_file] [-m] [-M] [-e] disk_list\n"); 276*7c478bd9Sstevel@tonic-gate fullabort(); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate 280*7c478bd9Sstevel@tonic-gate /* 281*7c478bd9Sstevel@tonic-gate * This routine reads in and digests the data file. The data file contains 282*7c478bd9Sstevel@tonic-gate * definitions for the search path, known disk types, and known partition 283*7c478bd9Sstevel@tonic-gate * maps. 284*7c478bd9Sstevel@tonic-gate * 285*7c478bd9Sstevel@tonic-gate * Note: for each file being processed, file_name is a pointer to that 286*7c478bd9Sstevel@tonic-gate * file's name. We are careful to make sure that file_name points to 287*7c478bd9Sstevel@tonic-gate * globally-accessible data, not data on the stack, because each 288*7c478bd9Sstevel@tonic-gate * disk/partition/controller definition now keeps a pointer to the 289*7c478bd9Sstevel@tonic-gate * filename in which it was defined. In the case of duplicate, 290*7c478bd9Sstevel@tonic-gate * conflicting definitions, we can thus tell the user exactly where 291*7c478bd9Sstevel@tonic-gate * the problem is occurring. 292*7c478bd9Sstevel@tonic-gate */ 293*7c478bd9Sstevel@tonic-gate void 294*7c478bd9Sstevel@tonic-gate sup_init() 295*7c478bd9Sstevel@tonic-gate { 296*7c478bd9Sstevel@tonic-gate int nopened_files = 0; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate #if defined(sparc) 299*7c478bd9Sstevel@tonic-gate char fname[MAXPATHLEN]; 300*7c478bd9Sstevel@tonic-gate char *path; 301*7c478bd9Sstevel@tonic-gate char *p; 302*7c478bd9Sstevel@tonic-gate struct stat stbuf; 303*7c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */ 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate /* 307*7c478bd9Sstevel@tonic-gate * Create a singly-linked list of controller types so that we may 308*7c478bd9Sstevel@tonic-gate * dynamically add unknown controllers to this for 3'rd 309*7c478bd9Sstevel@tonic-gate * party disk support. 310*7c478bd9Sstevel@tonic-gate */ 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate make_controller_list(); 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate /* 315*7c478bd9Sstevel@tonic-gate * If a data file was specified on the command line, use it first 316*7c478bd9Sstevel@tonic-gate * If the file cannot be opened, fail. We want to guarantee 317*7c478bd9Sstevel@tonic-gate * that, if the user explicitly names a file, they can 318*7c478bd9Sstevel@tonic-gate * access it. 319*7c478bd9Sstevel@tonic-gate * 320*7c478bd9Sstevel@tonic-gate * option_x is already global, no need to dup it on the heap. 321*7c478bd9Sstevel@tonic-gate */ 322*7c478bd9Sstevel@tonic-gate if (option_x) { 323*7c478bd9Sstevel@tonic-gate file_name = option_x; 324*7c478bd9Sstevel@tonic-gate if (sup_prxfile()) { 325*7c478bd9Sstevel@tonic-gate nopened_files++; 326*7c478bd9Sstevel@tonic-gate } else { 327*7c478bd9Sstevel@tonic-gate err_print("Unable to open data file '%s' - %s.\n", 328*7c478bd9Sstevel@tonic-gate file_name, strerror(errno)); 329*7c478bd9Sstevel@tonic-gate fullabort(); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate #if defined(sparc) 334*7c478bd9Sstevel@tonic-gate /* 335*7c478bd9Sstevel@tonic-gate * Now look for an environment variable FORMAT_PATH. 336*7c478bd9Sstevel@tonic-gate * If found, we use it as a colon-separated list 337*7c478bd9Sstevel@tonic-gate * of directories. If no such environment variable 338*7c478bd9Sstevel@tonic-gate * is defined, use a default path of "/etc". 339*7c478bd9Sstevel@tonic-gate */ 340*7c478bd9Sstevel@tonic-gate path = getenv("FORMAT_PATH"); 341*7c478bd9Sstevel@tonic-gate if (path == NULL) { 342*7c478bd9Sstevel@tonic-gate path = "/etc"; 343*7c478bd9Sstevel@tonic-gate } 344*7c478bd9Sstevel@tonic-gate /* 345*7c478bd9Sstevel@tonic-gate * Traverse the path one file at a time. Pick off 346*7c478bd9Sstevel@tonic-gate * the file name, and append the name "format.dat" 347*7c478bd9Sstevel@tonic-gate * at the end of the pathname. 348*7c478bd9Sstevel@tonic-gate * Whatever string we construct, duplicate it on the 349*7c478bd9Sstevel@tonic-gate * heap, so that file_name is globally accessible. 350*7c478bd9Sstevel@tonic-gate */ 351*7c478bd9Sstevel@tonic-gate while (*path != 0) { 352*7c478bd9Sstevel@tonic-gate p = fname; 353*7c478bd9Sstevel@tonic-gate while (*path != 0 && *path != ':') 354*7c478bd9Sstevel@tonic-gate *p++ = *path++; 355*7c478bd9Sstevel@tonic-gate if (p == fname) 356*7c478bd9Sstevel@tonic-gate continue; 357*7c478bd9Sstevel@tonic-gate *p = 0; 358*7c478bd9Sstevel@tonic-gate if (*path == ':') 359*7c478bd9Sstevel@tonic-gate path++; 360*7c478bd9Sstevel@tonic-gate /* 361*7c478bd9Sstevel@tonic-gate * If the path we have so far is a directory, 362*7c478bd9Sstevel@tonic-gate * look for a format.dat file in that directory, 363*7c478bd9Sstevel@tonic-gate * otherwise try using the path name specified. 364*7c478bd9Sstevel@tonic-gate * This permits arbitrary file names in the 365*7c478bd9Sstevel@tonic-gate * path specification, if this proves useful. 366*7c478bd9Sstevel@tonic-gate */ 367*7c478bd9Sstevel@tonic-gate if (stat(fname, &stbuf) == -1) { 368*7c478bd9Sstevel@tonic-gate err_print("Unable to access '%s' - %s.\n", 369*7c478bd9Sstevel@tonic-gate fname, strerror(errno)); 370*7c478bd9Sstevel@tonic-gate } else { 371*7c478bd9Sstevel@tonic-gate if (S_ISDIR(stbuf.st_mode)) { 372*7c478bd9Sstevel@tonic-gate if (*(p-1) != '/') 373*7c478bd9Sstevel@tonic-gate *p++ = '/'; 374*7c478bd9Sstevel@tonic-gate (void) strcpy(p, "format.dat"); 375*7c478bd9Sstevel@tonic-gate } 376*7c478bd9Sstevel@tonic-gate file_name = alloc_string(fname); 377*7c478bd9Sstevel@tonic-gate if (sup_prxfile()) { 378*7c478bd9Sstevel@tonic-gate nopened_files++; 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate } 381*7c478bd9Sstevel@tonic-gate } 382*7c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */ 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /* 385*7c478bd9Sstevel@tonic-gate * Check for duplicate disk or partitions definitions 386*7c478bd9Sstevel@tonic-gate * that are inconsistent - this would be very confusing. 387*7c478bd9Sstevel@tonic-gate */ 388*7c478bd9Sstevel@tonic-gate search_duplicate_dtypes(); 389*7c478bd9Sstevel@tonic-gate search_duplicate_pinfo(); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* 394*7c478bd9Sstevel@tonic-gate * Open and process a format data file. Unfortunately, we use 395*7c478bd9Sstevel@tonic-gate * globals: file_name for the file name, and data_file 396*7c478bd9Sstevel@tonic-gate * for the descriptor. Return true if able to open the file. 397*7c478bd9Sstevel@tonic-gate */ 398*7c478bd9Sstevel@tonic-gate static int 399*7c478bd9Sstevel@tonic-gate sup_prxfile() 400*7c478bd9Sstevel@tonic-gate { 401*7c478bd9Sstevel@tonic-gate int status; 402*7c478bd9Sstevel@tonic-gate TOKEN token; 403*7c478bd9Sstevel@tonic-gate TOKEN cleaned; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate /* 406*7c478bd9Sstevel@tonic-gate * Open the data file. Return 0 if unable to do so. 407*7c478bd9Sstevel@tonic-gate */ 408*7c478bd9Sstevel@tonic-gate data_file = fopen(file_name, "r"); 409*7c478bd9Sstevel@tonic-gate if (data_file == NULL) { 410*7c478bd9Sstevel@tonic-gate return (0); 411*7c478bd9Sstevel@tonic-gate } 412*7c478bd9Sstevel@tonic-gate /* 413*7c478bd9Sstevel@tonic-gate * Step through the data file a meta-line at a time. There are 414*7c478bd9Sstevel@tonic-gate * typically several backslashed newlines in each meta-line, 415*7c478bd9Sstevel@tonic-gate * so data_lineno will be getting side effected along the way. 416*7c478bd9Sstevel@tonic-gate */ 417*7c478bd9Sstevel@tonic-gate data_lineno = 0; 418*7c478bd9Sstevel@tonic-gate for (;;) { 419*7c478bd9Sstevel@tonic-gate data_lineno++; 420*7c478bd9Sstevel@tonic-gate /* 421*7c478bd9Sstevel@tonic-gate * Get the keyword. 422*7c478bd9Sstevel@tonic-gate */ 423*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 424*7c478bd9Sstevel@tonic-gate /* 425*7c478bd9Sstevel@tonic-gate * If we hit the end of the data file, we're done. 426*7c478bd9Sstevel@tonic-gate */ 427*7c478bd9Sstevel@tonic-gate if (status == SUP_EOF) 428*7c478bd9Sstevel@tonic-gate break; 429*7c478bd9Sstevel@tonic-gate /* 430*7c478bd9Sstevel@tonic-gate * If the line is blank, skip it. 431*7c478bd9Sstevel@tonic-gate */ 432*7c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 433*7c478bd9Sstevel@tonic-gate continue; 434*7c478bd9Sstevel@tonic-gate /* 435*7c478bd9Sstevel@tonic-gate * If the line starts with some key character, it's an error. 436*7c478bd9Sstevel@tonic-gate */ 437*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 438*7c478bd9Sstevel@tonic-gate datafile_error("Expecting keyword, found '%s'", token); 439*7c478bd9Sstevel@tonic-gate continue; 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate /* 442*7c478bd9Sstevel@tonic-gate * Clean up the token and see which keyword it is. Call 443*7c478bd9Sstevel@tonic-gate * the appropriate routine to process the rest of the line. 444*7c478bd9Sstevel@tonic-gate */ 445*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 446*7c478bd9Sstevel@tonic-gate if (strcmp(cleaned, "search_path") == 0) 447*7c478bd9Sstevel@tonic-gate sup_setpath(); 448*7c478bd9Sstevel@tonic-gate else if (strcmp(cleaned, "disk_type") == 0) 449*7c478bd9Sstevel@tonic-gate sup_setdtype(); 450*7c478bd9Sstevel@tonic-gate else if (strcmp(cleaned, "partition") == 0) 451*7c478bd9Sstevel@tonic-gate sup_setpart(); 452*7c478bd9Sstevel@tonic-gate else { 453*7c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", cleaned); 454*7c478bd9Sstevel@tonic-gate } 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate /* 457*7c478bd9Sstevel@tonic-gate * Close the data file. 458*7c478bd9Sstevel@tonic-gate */ 459*7c478bd9Sstevel@tonic-gate (void) fclose(data_file); 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate return (1); 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate 464*7c478bd9Sstevel@tonic-gate /* 465*7c478bd9Sstevel@tonic-gate * This routine processes a 'search_path' line in the data file. The 466*7c478bd9Sstevel@tonic-gate * search path is a list of disk names that will be searched for by the 467*7c478bd9Sstevel@tonic-gate * program. 468*7c478bd9Sstevel@tonic-gate * 469*7c478bd9Sstevel@tonic-gate * The static path_size and path_alloc are used to build up the 470*7c478bd9Sstevel@tonic-gate * list of files comprising the search path. The static definitions 471*7c478bd9Sstevel@tonic-gate * enable supporting multiple search path definitions. 472*7c478bd9Sstevel@tonic-gate */ 473*7c478bd9Sstevel@tonic-gate static void 474*7c478bd9Sstevel@tonic-gate sup_setpath() 475*7c478bd9Sstevel@tonic-gate { 476*7c478bd9Sstevel@tonic-gate TOKEN token; 477*7c478bd9Sstevel@tonic-gate TOKEN cleaned; 478*7c478bd9Sstevel@tonic-gate int status; 479*7c478bd9Sstevel@tonic-gate static int path_size; 480*7c478bd9Sstevel@tonic-gate static int path_alloc; 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate /* 483*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 484*7c478bd9Sstevel@tonic-gate */ 485*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 486*7c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 487*7c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 488*7c478bd9Sstevel@tonic-gate return; 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate /* 491*7c478bd9Sstevel@tonic-gate * Loop through the entries. 492*7c478bd9Sstevel@tonic-gate */ 493*7c478bd9Sstevel@tonic-gate for (;;) { 494*7c478bd9Sstevel@tonic-gate /* 495*7c478bd9Sstevel@tonic-gate * Pull in the disk name. 496*7c478bd9Sstevel@tonic-gate */ 497*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 498*7c478bd9Sstevel@tonic-gate /* 499*7c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 500*7c478bd9Sstevel@tonic-gate */ 501*7c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 502*7c478bd9Sstevel@tonic-gate break; 503*7c478bd9Sstevel@tonic-gate /* 504*7c478bd9Sstevel@tonic-gate * If we hit some key character, it's an error. 505*7c478bd9Sstevel@tonic-gate */ 506*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 507*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 508*7c478bd9Sstevel@tonic-gate break; 509*7c478bd9Sstevel@tonic-gate } 510*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 511*7c478bd9Sstevel@tonic-gate /* 512*7c478bd9Sstevel@tonic-gate * Build the string into an argvlist. This array 513*7c478bd9Sstevel@tonic-gate * is dynamically sized, as necessary, and terminated 514*7c478bd9Sstevel@tonic-gate * with a null. Each name is alloc'ed on the heap, 515*7c478bd9Sstevel@tonic-gate * so no dangling references. 516*7c478bd9Sstevel@tonic-gate */ 517*7c478bd9Sstevel@tonic-gate search_path = build_argvlist(search_path, &path_size, 518*7c478bd9Sstevel@tonic-gate &path_alloc, cleaned); 519*7c478bd9Sstevel@tonic-gate /* 520*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 521*7c478bd9Sstevel@tonic-gate */ 522*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 523*7c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 524*7c478bd9Sstevel@tonic-gate break; 525*7c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 526*7c478bd9Sstevel@tonic-gate datafile_error("Expecting ', ', found '%s'", token); 527*7c478bd9Sstevel@tonic-gate break; 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate /* 533*7c478bd9Sstevel@tonic-gate * This routine processes a 'disk_type' line in the data file. It defines 534*7c478bd9Sstevel@tonic-gate * the physical attributes of a brand of disk when connected to a specific 535*7c478bd9Sstevel@tonic-gate * controller type. 536*7c478bd9Sstevel@tonic-gate */ 537*7c478bd9Sstevel@tonic-gate static void 538*7c478bd9Sstevel@tonic-gate sup_setdtype() 539*7c478bd9Sstevel@tonic-gate { 540*7c478bd9Sstevel@tonic-gate TOKEN token, cleaned, ident; 541*7c478bd9Sstevel@tonic-gate int val, status, i; 542*7c478bd9Sstevel@tonic-gate ulong_t flags = 0; 543*7c478bd9Sstevel@tonic-gate struct disk_type *dtype, *type; 544*7c478bd9Sstevel@tonic-gate struct ctlr_type *ctype; 545*7c478bd9Sstevel@tonic-gate char *dtype_name, *ptr; 546*7c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 547*7c478bd9Sstevel@tonic-gate 548*7c478bd9Sstevel@tonic-gate /* 549*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 550*7c478bd9Sstevel@tonic-gate */ 551*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 552*7c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 553*7c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 554*7c478bd9Sstevel@tonic-gate return; 555*7c478bd9Sstevel@tonic-gate } 556*7c478bd9Sstevel@tonic-gate /* 557*7c478bd9Sstevel@tonic-gate * Pull in the name of the disk type. 558*7c478bd9Sstevel@tonic-gate */ 559*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 560*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 561*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 562*7c478bd9Sstevel@tonic-gate return; 563*7c478bd9Sstevel@tonic-gate } 564*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 565*7c478bd9Sstevel@tonic-gate /* 566*7c478bd9Sstevel@tonic-gate * Allocate space for the disk type and copy in the name. 567*7c478bd9Sstevel@tonic-gate */ 568*7c478bd9Sstevel@tonic-gate dtype_name = (char *)zalloc(strlen(cleaned) + 1); 569*7c478bd9Sstevel@tonic-gate (void) strcpy(dtype_name, cleaned); 570*7c478bd9Sstevel@tonic-gate dtype = (struct disk_type *)zalloc(sizeof (struct disk_type)); 571*7c478bd9Sstevel@tonic-gate dtype->dtype_asciilabel = dtype_name; 572*7c478bd9Sstevel@tonic-gate /* 573*7c478bd9Sstevel@tonic-gate * Save the filename/linenumber where this disk was defined 574*7c478bd9Sstevel@tonic-gate */ 575*7c478bd9Sstevel@tonic-gate dtype->dtype_filename = file_name; 576*7c478bd9Sstevel@tonic-gate dtype->dtype_lineno = data_lineno; 577*7c478bd9Sstevel@tonic-gate /* 578*7c478bd9Sstevel@tonic-gate * Loop for each attribute. 579*7c478bd9Sstevel@tonic-gate */ 580*7c478bd9Sstevel@tonic-gate for (;;) { 581*7c478bd9Sstevel@tonic-gate /* 582*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 583*7c478bd9Sstevel@tonic-gate */ 584*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 585*7c478bd9Sstevel@tonic-gate /* 586*7c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 587*7c478bd9Sstevel@tonic-gate */ 588*7c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 589*7c478bd9Sstevel@tonic-gate break; 590*7c478bd9Sstevel@tonic-gate if (status != SUP_COLON) { 591*7c478bd9Sstevel@tonic-gate datafile_error("Expecting ':', found '%s'", token); 592*7c478bd9Sstevel@tonic-gate return; 593*7c478bd9Sstevel@tonic-gate } 594*7c478bd9Sstevel@tonic-gate /* 595*7c478bd9Sstevel@tonic-gate * Pull in the attribute. 596*7c478bd9Sstevel@tonic-gate */ 597*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 598*7c478bd9Sstevel@tonic-gate /* 599*7c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 600*7c478bd9Sstevel@tonic-gate */ 601*7c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 602*7c478bd9Sstevel@tonic-gate break; 603*7c478bd9Sstevel@tonic-gate /* 604*7c478bd9Sstevel@tonic-gate * If we hit a key character, it's an error. 605*7c478bd9Sstevel@tonic-gate */ 606*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 607*7c478bd9Sstevel@tonic-gate datafile_error("Expecting keyword, found '%s'", token); 608*7c478bd9Sstevel@tonic-gate return; 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate clean_token(ident, token); 611*7c478bd9Sstevel@tonic-gate /* 612*7c478bd9Sstevel@tonic-gate * Check to see if we've got a change specification 613*7c478bd9Sstevel@tonic-gate * If so, this routine will parse the entire 614*7c478bd9Sstevel@tonic-gate * specification, so just restart at top of loop 615*7c478bd9Sstevel@tonic-gate */ 616*7c478bd9Sstevel@tonic-gate if (sup_change_spec(dtype, ident)) { 617*7c478bd9Sstevel@tonic-gate continue; 618*7c478bd9Sstevel@tonic-gate } 619*7c478bd9Sstevel@tonic-gate /* 620*7c478bd9Sstevel@tonic-gate * Pull in more grammar. 621*7c478bd9Sstevel@tonic-gate */ 622*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 623*7c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 624*7c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 625*7c478bd9Sstevel@tonic-gate return; 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate /* 628*7c478bd9Sstevel@tonic-gate * Pull in the value of the attribute. 629*7c478bd9Sstevel@tonic-gate */ 630*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 631*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 632*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 633*7c478bd9Sstevel@tonic-gate return; 634*7c478bd9Sstevel@tonic-gate } 635*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 636*7c478bd9Sstevel@tonic-gate /* 637*7c478bd9Sstevel@tonic-gate * If the attribute defined the ctlr... 638*7c478bd9Sstevel@tonic-gate */ 639*7c478bd9Sstevel@tonic-gate if (strcmp(ident, "ctlr") == 0) { 640*7c478bd9Sstevel@tonic-gate /* 641*7c478bd9Sstevel@tonic-gate * Match the value with a ctlr type. 642*7c478bd9Sstevel@tonic-gate */ 643*7c478bd9Sstevel@tonic-gate mlp = controlp; 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate while (mlp != NULL) { 646*7c478bd9Sstevel@tonic-gate if (strcmp(mlp->ctlr_type->ctype_name, 647*7c478bd9Sstevel@tonic-gate cleaned) == 0) 648*7c478bd9Sstevel@tonic-gate break; 649*7c478bd9Sstevel@tonic-gate mlp = mlp->next; 650*7c478bd9Sstevel@tonic-gate } 651*7c478bd9Sstevel@tonic-gate /* 652*7c478bd9Sstevel@tonic-gate * If we couldn't match it, it's an error. 653*7c478bd9Sstevel@tonic-gate */ 654*7c478bd9Sstevel@tonic-gate if (mlp == NULL) { 655*7c478bd9Sstevel@tonic-gate for (i = 0; i < OTHER_CTLRS; i++) { 656*7c478bd9Sstevel@tonic-gate if (strcmp(other_ctlrs[i], cleaned) 657*7c478bd9Sstevel@tonic-gate == 0) { 658*7c478bd9Sstevel@tonic-gate datafile_error(NULL, NULL); 659*7c478bd9Sstevel@tonic-gate return; 660*7c478bd9Sstevel@tonic-gate } 661*7c478bd9Sstevel@tonic-gate } 662*7c478bd9Sstevel@tonic-gate if (i == OTHER_CTLRS) { 663*7c478bd9Sstevel@tonic-gate datafile_error("Unknown controller '%s'", 664*7c478bd9Sstevel@tonic-gate cleaned); 665*7c478bd9Sstevel@tonic-gate return; 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate } 668*7c478bd9Sstevel@tonic-gate /* 669*7c478bd9Sstevel@tonic-gate * Found a match. Add this disk type to the list 670*7c478bd9Sstevel@tonic-gate * for the ctlr type if we can complete the 671*7c478bd9Sstevel@tonic-gate * disk specification correctly. 672*7c478bd9Sstevel@tonic-gate */ 673*7c478bd9Sstevel@tonic-gate ctype = mlp->ctlr_type; 674*7c478bd9Sstevel@tonic-gate flags |= SUP_CTLR; 675*7c478bd9Sstevel@tonic-gate continue; 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate /* 678*7c478bd9Sstevel@tonic-gate * All other attributes require a numeric value. Convert 679*7c478bd9Sstevel@tonic-gate * the value to a number. 680*7c478bd9Sstevel@tonic-gate */ 681*7c478bd9Sstevel@tonic-gate val = (int)strtol(cleaned, &ptr, 0); 682*7c478bd9Sstevel@tonic-gate if (*ptr != '\0') { 683*7c478bd9Sstevel@tonic-gate datafile_error("Expecting an integer, found '%s'", 684*7c478bd9Sstevel@tonic-gate cleaned); 685*7c478bd9Sstevel@tonic-gate return; 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate /* 688*7c478bd9Sstevel@tonic-gate * Figure out which attribute it was and fill in the 689*7c478bd9Sstevel@tonic-gate * appropriate value. Also note that the attribute 690*7c478bd9Sstevel@tonic-gate * has been defined. 691*7c478bd9Sstevel@tonic-gate */ 692*7c478bd9Sstevel@tonic-gate if (strcmp(ident, "ncyl") == 0) { 693*7c478bd9Sstevel@tonic-gate dtype->dtype_ncyl = val; 694*7c478bd9Sstevel@tonic-gate flags |= SUP_NCYL; 695*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "acyl") == 0) { 696*7c478bd9Sstevel@tonic-gate dtype->dtype_acyl = val; 697*7c478bd9Sstevel@tonic-gate flags |= SUP_ACYL; 698*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "pcyl") == 0) { 699*7c478bd9Sstevel@tonic-gate dtype->dtype_pcyl = val; 700*7c478bd9Sstevel@tonic-gate flags |= SUP_PCYL; 701*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "nhead") == 0) { 702*7c478bd9Sstevel@tonic-gate dtype->dtype_nhead = val; 703*7c478bd9Sstevel@tonic-gate flags |= SUP_NHEAD; 704*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "nsect") == 0) { 705*7c478bd9Sstevel@tonic-gate dtype->dtype_nsect = val; 706*7c478bd9Sstevel@tonic-gate flags |= SUP_NSECT; 707*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "rpm") == 0) { 708*7c478bd9Sstevel@tonic-gate dtype->dtype_rpm = val; 709*7c478bd9Sstevel@tonic-gate flags |= SUP_RPM; 710*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "bpt") == 0) { 711*7c478bd9Sstevel@tonic-gate dtype->dtype_bpt = val; 712*7c478bd9Sstevel@tonic-gate flags |= SUP_BPT; 713*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "bps") == 0) { 714*7c478bd9Sstevel@tonic-gate dtype->dtype_bps = val; 715*7c478bd9Sstevel@tonic-gate flags |= SUP_BPS; 716*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "drive_type") == 0) { 717*7c478bd9Sstevel@tonic-gate dtype->dtype_dr_type = val; 718*7c478bd9Sstevel@tonic-gate flags |= SUP_DRTYPE; 719*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "cache") == 0) { 720*7c478bd9Sstevel@tonic-gate dtype->dtype_cache = val; 721*7c478bd9Sstevel@tonic-gate flags |= SUP_CACHE; 722*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "prefetch") == 0) { 723*7c478bd9Sstevel@tonic-gate dtype->dtype_threshold = val; 724*7c478bd9Sstevel@tonic-gate flags |= SUP_PREFETCH; 725*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "read_retries") == 0) { 726*7c478bd9Sstevel@tonic-gate dtype->dtype_read_retries = val; 727*7c478bd9Sstevel@tonic-gate flags |= SUP_READ_RETRIES; 728*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "write_retries") == 0) { 729*7c478bd9Sstevel@tonic-gate dtype->dtype_write_retries = val; 730*7c478bd9Sstevel@tonic-gate flags |= SUP_WRITE_RETRIES; 731*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "min_prefetch") == 0) { 732*7c478bd9Sstevel@tonic-gate dtype->dtype_prefetch_min = val; 733*7c478bd9Sstevel@tonic-gate flags |= SUP_CACHE_MIN; 734*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "max_prefetch") == 0) { 735*7c478bd9Sstevel@tonic-gate dtype->dtype_prefetch_max = val; 736*7c478bd9Sstevel@tonic-gate flags |= SUP_CACHE_MAX; 737*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "trks_zone") == 0) { 738*7c478bd9Sstevel@tonic-gate dtype->dtype_trks_zone = val; 739*7c478bd9Sstevel@tonic-gate flags |= SUP_TRKS_ZONE; 740*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "atrks") == 0) { 741*7c478bd9Sstevel@tonic-gate dtype->dtype_atrks = val; 742*7c478bd9Sstevel@tonic-gate flags |= SUP_ATRKS; 743*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "asect") == 0) { 744*7c478bd9Sstevel@tonic-gate dtype->dtype_asect = val; 745*7c478bd9Sstevel@tonic-gate flags |= SUP_ASECT; 746*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "psect") == 0) { 747*7c478bd9Sstevel@tonic-gate dtype->dtype_psect = val; 748*7c478bd9Sstevel@tonic-gate flags |= SUP_PSECT; 749*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "phead") == 0) { 750*7c478bd9Sstevel@tonic-gate dtype->dtype_phead = val; 751*7c478bd9Sstevel@tonic-gate flags |= SUP_PHEAD; 752*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "fmt_time") == 0) { 753*7c478bd9Sstevel@tonic-gate dtype->dtype_fmt_time = val; 754*7c478bd9Sstevel@tonic-gate flags |= SUP_FMTTIME; 755*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "cyl_skew") == 0) { 756*7c478bd9Sstevel@tonic-gate dtype->dtype_cyl_skew = val; 757*7c478bd9Sstevel@tonic-gate flags |= SUP_CYLSKEW; 758*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "trk_skew") == 0) { 759*7c478bd9Sstevel@tonic-gate dtype->dtype_trk_skew = val; 760*7c478bd9Sstevel@tonic-gate flags |= SUP_TRKSKEW; 761*7c478bd9Sstevel@tonic-gate } else { 762*7c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 763*7c478bd9Sstevel@tonic-gate } 764*7c478bd9Sstevel@tonic-gate } 765*7c478bd9Sstevel@tonic-gate /* 766*7c478bd9Sstevel@tonic-gate * Check to be sure all the necessary attributes have been defined. 767*7c478bd9Sstevel@tonic-gate * If any are missing, it's an error. Also, log options for later 768*7c478bd9Sstevel@tonic-gate * use by specific driver. 769*7c478bd9Sstevel@tonic-gate */ 770*7c478bd9Sstevel@tonic-gate dtype->dtype_options = flags; 771*7c478bd9Sstevel@tonic-gate if ((flags & SUP_MIN_DRIVE) != SUP_MIN_DRIVE) { 772*7c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 773*7c478bd9Sstevel@tonic-gate return; 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate if ((!(ctype->ctype_flags & CF_SCSI)) && (!(flags & SUP_BPT)) && 776*7c478bd9Sstevel@tonic-gate (!(ctype->ctype_flags & CF_NOFORMAT))) { 777*7c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 778*7c478bd9Sstevel@tonic-gate return; 779*7c478bd9Sstevel@tonic-gate } 780*7c478bd9Sstevel@tonic-gate if ((ctype->ctype_flags & CF_SMD_DEFS) && (!(flags & SUP_BPS))) { 781*7c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 782*7c478bd9Sstevel@tonic-gate return; 783*7c478bd9Sstevel@tonic-gate } 784*7c478bd9Sstevel@tonic-gate /* 785*7c478bd9Sstevel@tonic-gate * Add this disk type to the list for the ctlr type 786*7c478bd9Sstevel@tonic-gate */ 787*7c478bd9Sstevel@tonic-gate assert(flags & SUP_CTLR); 788*7c478bd9Sstevel@tonic-gate type = ctype->ctype_dlist; 789*7c478bd9Sstevel@tonic-gate if (type == NULL) { 790*7c478bd9Sstevel@tonic-gate ctype->ctype_dlist = dtype; 791*7c478bd9Sstevel@tonic-gate } else { 792*7c478bd9Sstevel@tonic-gate while (type->dtype_next != NULL) 793*7c478bd9Sstevel@tonic-gate type = type->dtype_next; 794*7c478bd9Sstevel@tonic-gate type->dtype_next = dtype; 795*7c478bd9Sstevel@tonic-gate } 796*7c478bd9Sstevel@tonic-gate } 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate /* 800*7c478bd9Sstevel@tonic-gate * Parse a SCSI mode page change specification. 801*7c478bd9Sstevel@tonic-gate * 802*7c478bd9Sstevel@tonic-gate * Return: 803*7c478bd9Sstevel@tonic-gate * 0: not change specification, continue parsing 804*7c478bd9Sstevel@tonic-gate * 1: was change specification, it was ok, 805*7c478bd9Sstevel@tonic-gate * or we already handled the error. 806*7c478bd9Sstevel@tonic-gate */ 807*7c478bd9Sstevel@tonic-gate static int 808*7c478bd9Sstevel@tonic-gate sup_change_spec(struct disk_type *disk, char *id) 809*7c478bd9Sstevel@tonic-gate { 810*7c478bd9Sstevel@tonic-gate char *p; 811*7c478bd9Sstevel@tonic-gate char *p2; 812*7c478bd9Sstevel@tonic-gate int pageno; 813*7c478bd9Sstevel@tonic-gate int byteno; 814*7c478bd9Sstevel@tonic-gate int mode; 815*7c478bd9Sstevel@tonic-gate int value; 816*7c478bd9Sstevel@tonic-gate TOKEN token; 817*7c478bd9Sstevel@tonic-gate TOKEN ident; 818*7c478bd9Sstevel@tonic-gate struct chg_list *cp; 819*7c478bd9Sstevel@tonic-gate int tilde; 820*7c478bd9Sstevel@tonic-gate int i; 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate /* 823*7c478bd9Sstevel@tonic-gate * Syntax: p[<nn>|0x<xx>] 824*7c478bd9Sstevel@tonic-gate */ 825*7c478bd9Sstevel@tonic-gate if (*id != 'p') { 826*7c478bd9Sstevel@tonic-gate return (0); 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate pageno = (int)strtol(id+1, &p2, 0); 829*7c478bd9Sstevel@tonic-gate if (*p2 != 0) { 830*7c478bd9Sstevel@tonic-gate return (0); 831*7c478bd9Sstevel@tonic-gate } 832*7c478bd9Sstevel@tonic-gate /* 833*7c478bd9Sstevel@tonic-gate * Once we get this far, we know we have the 834*7c478bd9Sstevel@tonic-gate * beginnings of a change specification. 835*7c478bd9Sstevel@tonic-gate * If there's a problem now, report the problem, 836*7c478bd9Sstevel@tonic-gate * and return 1, so that the caller can restart 837*7c478bd9Sstevel@tonic-gate * parsing at the next expression. 838*7c478bd9Sstevel@tonic-gate */ 839*7c478bd9Sstevel@tonic-gate if (!scsi_supported_page(pageno)) { 840*7c478bd9Sstevel@tonic-gate datafile_error("Unsupported mode page '%s'", id); 841*7c478bd9Sstevel@tonic-gate return (1); 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate /* 844*7c478bd9Sstevel@tonic-gate * Next token should be the byte offset 845*7c478bd9Sstevel@tonic-gate */ 846*7c478bd9Sstevel@tonic-gate if (sup_gettoken(token) != SUP_STRING) { 847*7c478bd9Sstevel@tonic-gate datafile_error("Unexpected value '%s'", token); 848*7c478bd9Sstevel@tonic-gate return (1); 849*7c478bd9Sstevel@tonic-gate } 850*7c478bd9Sstevel@tonic-gate clean_token(ident, token); 851*7c478bd9Sstevel@tonic-gate 852*7c478bd9Sstevel@tonic-gate /* 853*7c478bd9Sstevel@tonic-gate * Syntax: b[<nn>|0x<xx>] 854*7c478bd9Sstevel@tonic-gate */ 855*7c478bd9Sstevel@tonic-gate p = ident; 856*7c478bd9Sstevel@tonic-gate if (*p++ != 'b') { 857*7c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 858*7c478bd9Sstevel@tonic-gate return (1); 859*7c478bd9Sstevel@tonic-gate } 860*7c478bd9Sstevel@tonic-gate byteno = (int)strtol(p, &p2, 10); 861*7c478bd9Sstevel@tonic-gate if (*p2 != 0) { 862*7c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 863*7c478bd9Sstevel@tonic-gate return (1); 864*7c478bd9Sstevel@tonic-gate } 865*7c478bd9Sstevel@tonic-gate if (byteno == 0 || byteno == 1) { 866*7c478bd9Sstevel@tonic-gate datafile_error("Unsupported byte offset '%s'", ident); 867*7c478bd9Sstevel@tonic-gate return (1); 868*7c478bd9Sstevel@tonic-gate } 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate /* 871*7c478bd9Sstevel@tonic-gate * Get the operator for this expression 872*7c478bd9Sstevel@tonic-gate */ 873*7c478bd9Sstevel@tonic-gate mode = CHG_MODE_UNDEFINED; 874*7c478bd9Sstevel@tonic-gate switch (sup_gettoken(token)) { 875*7c478bd9Sstevel@tonic-gate case SUP_EQL: 876*7c478bd9Sstevel@tonic-gate mode = CHG_MODE_ABS; 877*7c478bd9Sstevel@tonic-gate break; 878*7c478bd9Sstevel@tonic-gate case SUP_OR: 879*7c478bd9Sstevel@tonic-gate if (sup_gettoken(token) == SUP_EQL) 880*7c478bd9Sstevel@tonic-gate mode = CHG_MODE_SET; 881*7c478bd9Sstevel@tonic-gate break; 882*7c478bd9Sstevel@tonic-gate case SUP_AND: 883*7c478bd9Sstevel@tonic-gate if (sup_gettoken(token) == SUP_EQL) 884*7c478bd9Sstevel@tonic-gate mode = CHG_MODE_CLR; 885*7c478bd9Sstevel@tonic-gate break; 886*7c478bd9Sstevel@tonic-gate } 887*7c478bd9Sstevel@tonic-gate if (mode == CHG_MODE_UNDEFINED) { 888*7c478bd9Sstevel@tonic-gate datafile_error("Unexpected operator: '%s'", token); 889*7c478bd9Sstevel@tonic-gate return (1); 890*7c478bd9Sstevel@tonic-gate } 891*7c478bd9Sstevel@tonic-gate 892*7c478bd9Sstevel@tonic-gate /* 893*7c478bd9Sstevel@tonic-gate * Get right-hand of expression - accept optional tilde 894*7c478bd9Sstevel@tonic-gate */ 895*7c478bd9Sstevel@tonic-gate tilde = 0; 896*7c478bd9Sstevel@tonic-gate if ((i = sup_gettoken(token)) == SUP_TILDE) { 897*7c478bd9Sstevel@tonic-gate tilde = 1; 898*7c478bd9Sstevel@tonic-gate i = sup_gettoken(token); 899*7c478bd9Sstevel@tonic-gate } 900*7c478bd9Sstevel@tonic-gate if (i != SUP_STRING) { 901*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 902*7c478bd9Sstevel@tonic-gate return (1); 903*7c478bd9Sstevel@tonic-gate } 904*7c478bd9Sstevel@tonic-gate clean_token(ident, token); 905*7c478bd9Sstevel@tonic-gate value = (int)strtol(ident, &p, 0); 906*7c478bd9Sstevel@tonic-gate if (*p != 0) { 907*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 908*7c478bd9Sstevel@tonic-gate return (1); 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate 911*7c478bd9Sstevel@tonic-gate /* 912*7c478bd9Sstevel@tonic-gate * Apply the tilde operator, if found. 913*7c478bd9Sstevel@tonic-gate * Constrain to a byte value. 914*7c478bd9Sstevel@tonic-gate */ 915*7c478bd9Sstevel@tonic-gate if (tilde) { 916*7c478bd9Sstevel@tonic-gate value = ~value; 917*7c478bd9Sstevel@tonic-gate } 918*7c478bd9Sstevel@tonic-gate value &= 0xff; 919*7c478bd9Sstevel@tonic-gate 920*7c478bd9Sstevel@tonic-gate /* 921*7c478bd9Sstevel@tonic-gate * We parsed a successful change specification expression. 922*7c478bd9Sstevel@tonic-gate * Add it to the list for this disk type. 923*7c478bd9Sstevel@tonic-gate */ 924*7c478bd9Sstevel@tonic-gate cp = new_chg_list(disk); 925*7c478bd9Sstevel@tonic-gate cp->pageno = pageno; 926*7c478bd9Sstevel@tonic-gate cp->byteno = byteno; 927*7c478bd9Sstevel@tonic-gate cp->mode = mode; 928*7c478bd9Sstevel@tonic-gate cp->value = value; 929*7c478bd9Sstevel@tonic-gate return (1); 930*7c478bd9Sstevel@tonic-gate } 931*7c478bd9Sstevel@tonic-gate 932*7c478bd9Sstevel@tonic-gate 933*7c478bd9Sstevel@tonic-gate /* 934*7c478bd9Sstevel@tonic-gate * This routine processes a 'partition' line in the data file. It defines 935*7c478bd9Sstevel@tonic-gate * a known partition map for a particular disk type on a particular 936*7c478bd9Sstevel@tonic-gate * controller type. 937*7c478bd9Sstevel@tonic-gate */ 938*7c478bd9Sstevel@tonic-gate static void 939*7c478bd9Sstevel@tonic-gate sup_setpart() 940*7c478bd9Sstevel@tonic-gate { 941*7c478bd9Sstevel@tonic-gate TOKEN token, cleaned, disk, ctlr, ident; 942*7c478bd9Sstevel@tonic-gate struct disk_type *dtype = NULL; 943*7c478bd9Sstevel@tonic-gate struct ctlr_type *ctype = NULL; 944*7c478bd9Sstevel@tonic-gate struct partition_info *pinfo, *parts; 945*7c478bd9Sstevel@tonic-gate char *pinfo_name; 946*7c478bd9Sstevel@tonic-gate int i, index, status, val1, val2, flags = 0; 947*7c478bd9Sstevel@tonic-gate ushort_t vtoc_tag; 948*7c478bd9Sstevel@tonic-gate ushort_t vtoc_flag; 949*7c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 950*7c478bd9Sstevel@tonic-gate 951*7c478bd9Sstevel@tonic-gate /* 952*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 953*7c478bd9Sstevel@tonic-gate */ 954*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 955*7c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 956*7c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 957*7c478bd9Sstevel@tonic-gate return; 958*7c478bd9Sstevel@tonic-gate } 959*7c478bd9Sstevel@tonic-gate /* 960*7c478bd9Sstevel@tonic-gate * Pull in the name of the map. 961*7c478bd9Sstevel@tonic-gate */ 962*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 963*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 964*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 965*7c478bd9Sstevel@tonic-gate return; 966*7c478bd9Sstevel@tonic-gate } 967*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 968*7c478bd9Sstevel@tonic-gate /* 969*7c478bd9Sstevel@tonic-gate * Allocate space for the partition map and fill in the name. 970*7c478bd9Sstevel@tonic-gate */ 971*7c478bd9Sstevel@tonic-gate pinfo_name = (char *)zalloc(strlen(cleaned) + 1); 972*7c478bd9Sstevel@tonic-gate (void) strcpy(pinfo_name, cleaned); 973*7c478bd9Sstevel@tonic-gate pinfo = (struct partition_info *)zalloc(sizeof (struct partition_info)); 974*7c478bd9Sstevel@tonic-gate pinfo->pinfo_name = pinfo_name; 975*7c478bd9Sstevel@tonic-gate /* 976*7c478bd9Sstevel@tonic-gate * Save the filename/linenumber where this partition was defined 977*7c478bd9Sstevel@tonic-gate */ 978*7c478bd9Sstevel@tonic-gate pinfo->pinfo_filename = file_name; 979*7c478bd9Sstevel@tonic-gate pinfo->pinfo_lineno = data_lineno; 980*7c478bd9Sstevel@tonic-gate 981*7c478bd9Sstevel@tonic-gate /* 982*7c478bd9Sstevel@tonic-gate * Install default vtoc information into the new partition table 983*7c478bd9Sstevel@tonic-gate */ 984*7c478bd9Sstevel@tonic-gate set_vtoc_defaults(pinfo); 985*7c478bd9Sstevel@tonic-gate 986*7c478bd9Sstevel@tonic-gate /* 987*7c478bd9Sstevel@tonic-gate * Loop for each attribute in the line. 988*7c478bd9Sstevel@tonic-gate */ 989*7c478bd9Sstevel@tonic-gate for (;;) { 990*7c478bd9Sstevel@tonic-gate /* 991*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 992*7c478bd9Sstevel@tonic-gate */ 993*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 994*7c478bd9Sstevel@tonic-gate /* 995*7c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 996*7c478bd9Sstevel@tonic-gate */ 997*7c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 998*7c478bd9Sstevel@tonic-gate break; 999*7c478bd9Sstevel@tonic-gate if (status != SUP_COLON) { 1000*7c478bd9Sstevel@tonic-gate datafile_error("Expecting ':', found '%s'", token); 1001*7c478bd9Sstevel@tonic-gate return; 1002*7c478bd9Sstevel@tonic-gate } 1003*7c478bd9Sstevel@tonic-gate /* 1004*7c478bd9Sstevel@tonic-gate * Pull in the attribute. 1005*7c478bd9Sstevel@tonic-gate */ 1006*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1007*7c478bd9Sstevel@tonic-gate /* 1008*7c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 1009*7c478bd9Sstevel@tonic-gate */ 1010*7c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 1011*7c478bd9Sstevel@tonic-gate break; 1012*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 1013*7c478bd9Sstevel@tonic-gate datafile_error("Expecting keyword, found '%s'", token); 1014*7c478bd9Sstevel@tonic-gate return; 1015*7c478bd9Sstevel@tonic-gate } 1016*7c478bd9Sstevel@tonic-gate clean_token(ident, token); 1017*7c478bd9Sstevel@tonic-gate /* 1018*7c478bd9Sstevel@tonic-gate * Pull in more grammar. 1019*7c478bd9Sstevel@tonic-gate */ 1020*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1021*7c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 1022*7c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 1023*7c478bd9Sstevel@tonic-gate return; 1024*7c478bd9Sstevel@tonic-gate } 1025*7c478bd9Sstevel@tonic-gate /* 1026*7c478bd9Sstevel@tonic-gate * Pull in the value of the attribute. 1027*7c478bd9Sstevel@tonic-gate */ 1028*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1029*7c478bd9Sstevel@tonic-gate /* 1030*7c478bd9Sstevel@tonic-gate * If we hit a key character, it's an error. 1031*7c478bd9Sstevel@tonic-gate */ 1032*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 1033*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 1034*7c478bd9Sstevel@tonic-gate return; 1035*7c478bd9Sstevel@tonic-gate } 1036*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 1037*7c478bd9Sstevel@tonic-gate /* 1038*7c478bd9Sstevel@tonic-gate * If the attribute is the ctlr, save the ctlr name and 1039*7c478bd9Sstevel@tonic-gate * mark it defined. 1040*7c478bd9Sstevel@tonic-gate */ 1041*7c478bd9Sstevel@tonic-gate if (strcmp(ident, "ctlr") == 0) { 1042*7c478bd9Sstevel@tonic-gate (void) strcpy(ctlr, cleaned); 1043*7c478bd9Sstevel@tonic-gate flags |= SUP_CTLR; 1044*7c478bd9Sstevel@tonic-gate continue; 1045*7c478bd9Sstevel@tonic-gate /* 1046*7c478bd9Sstevel@tonic-gate * If the attribute is the disk, save the disk name and 1047*7c478bd9Sstevel@tonic-gate * mark it defined. 1048*7c478bd9Sstevel@tonic-gate */ 1049*7c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "disk") == 0) { 1050*7c478bd9Sstevel@tonic-gate (void) strcpy(disk, cleaned); 1051*7c478bd9Sstevel@tonic-gate flags |= SUP_DISK; 1052*7c478bd9Sstevel@tonic-gate continue; 1053*7c478bd9Sstevel@tonic-gate } 1054*7c478bd9Sstevel@tonic-gate /* 1055*7c478bd9Sstevel@tonic-gate * If we now know both the controller name and the 1056*7c478bd9Sstevel@tonic-gate * disk name, let's see if we can find the controller 1057*7c478bd9Sstevel@tonic-gate * and disk type. This will give us the geometry, 1058*7c478bd9Sstevel@tonic-gate * which can permit us to accept partitions specs 1059*7c478bd9Sstevel@tonic-gate * in cylinders or blocks. 1060*7c478bd9Sstevel@tonic-gate */ 1061*7c478bd9Sstevel@tonic-gate if (((flags & (SUP_DISK|SUP_CTLR)) == (SUP_DISK|SUP_CTLR)) && 1062*7c478bd9Sstevel@tonic-gate dtype == NULL && ctype == NULL) { 1063*7c478bd9Sstevel@tonic-gate /* 1064*7c478bd9Sstevel@tonic-gate * Attempt to match the specified ctlr to a known type. 1065*7c478bd9Sstevel@tonic-gate */ 1066*7c478bd9Sstevel@tonic-gate mlp = controlp; 1067*7c478bd9Sstevel@tonic-gate 1068*7c478bd9Sstevel@tonic-gate while (mlp != NULL) { 1069*7c478bd9Sstevel@tonic-gate if (strcmp(mlp->ctlr_type->ctype_name, 1070*7c478bd9Sstevel@tonic-gate ctlr) == 0) 1071*7c478bd9Sstevel@tonic-gate break; 1072*7c478bd9Sstevel@tonic-gate mlp = mlp->next; 1073*7c478bd9Sstevel@tonic-gate } 1074*7c478bd9Sstevel@tonic-gate /* 1075*7c478bd9Sstevel@tonic-gate * If no match is found, it's an error. 1076*7c478bd9Sstevel@tonic-gate */ 1077*7c478bd9Sstevel@tonic-gate if (mlp == NULL) { 1078*7c478bd9Sstevel@tonic-gate for (i = 0; i < OTHER_CTLRS; i++) { 1079*7c478bd9Sstevel@tonic-gate if (strcmp(other_ctlrs[i], ctlr) == 0) { 1080*7c478bd9Sstevel@tonic-gate datafile_error(NULL, NULL); 1081*7c478bd9Sstevel@tonic-gate return; 1082*7c478bd9Sstevel@tonic-gate } 1083*7c478bd9Sstevel@tonic-gate } 1084*7c478bd9Sstevel@tonic-gate if (i == OTHER_CTLRS) { 1085*7c478bd9Sstevel@tonic-gate datafile_error( 1086*7c478bd9Sstevel@tonic-gate "Unknown controller '%s'", ctlr); 1087*7c478bd9Sstevel@tonic-gate return; 1088*7c478bd9Sstevel@tonic-gate } 1089*7c478bd9Sstevel@tonic-gate } 1090*7c478bd9Sstevel@tonic-gate ctype = mlp->ctlr_type; 1091*7c478bd9Sstevel@tonic-gate /* 1092*7c478bd9Sstevel@tonic-gate * Attempt to match the specified disk to a known type. 1093*7c478bd9Sstevel@tonic-gate */ 1094*7c478bd9Sstevel@tonic-gate for (dtype = ctype->ctype_dlist; dtype != NULL; 1095*7c478bd9Sstevel@tonic-gate dtype = dtype->dtype_next) { 1096*7c478bd9Sstevel@tonic-gate if (strcmp(dtype->dtype_asciilabel, disk) == 0) 1097*7c478bd9Sstevel@tonic-gate break; 1098*7c478bd9Sstevel@tonic-gate } 1099*7c478bd9Sstevel@tonic-gate /* 1100*7c478bd9Sstevel@tonic-gate * If no match is found, it's an error. 1101*7c478bd9Sstevel@tonic-gate */ 1102*7c478bd9Sstevel@tonic-gate if (dtype == NULL) { 1103*7c478bd9Sstevel@tonic-gate datafile_error("Unknown disk '%s'", disk); 1104*7c478bd9Sstevel@tonic-gate return; 1105*7c478bd9Sstevel@tonic-gate } 1106*7c478bd9Sstevel@tonic-gate /* 1107*7c478bd9Sstevel@tonic-gate * Now that we know the disk type, set up the 1108*7c478bd9Sstevel@tonic-gate * globals that let that magic macro "spc()" 1109*7c478bd9Sstevel@tonic-gate * do it's thing. Sorry that this is glued 1110*7c478bd9Sstevel@tonic-gate * together so poorly... 1111*7c478bd9Sstevel@tonic-gate */ 1112*7c478bd9Sstevel@tonic-gate nhead = dtype->dtype_nhead; 1113*7c478bd9Sstevel@tonic-gate nsect = dtype->dtype_nsect; 1114*7c478bd9Sstevel@tonic-gate acyl = dtype->dtype_acyl; 1115*7c478bd9Sstevel@tonic-gate ncyl = dtype->dtype_ncyl; 1116*7c478bd9Sstevel@tonic-gate } 1117*7c478bd9Sstevel@tonic-gate /* 1118*7c478bd9Sstevel@tonic-gate * By now, the disk and controller type must be defined 1119*7c478bd9Sstevel@tonic-gate */ 1120*7c478bd9Sstevel@tonic-gate if (dtype == NULL || ctype == NULL) { 1121*7c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 1122*7c478bd9Sstevel@tonic-gate return; 1123*7c478bd9Sstevel@tonic-gate } 1124*7c478bd9Sstevel@tonic-gate /* 1125*7c478bd9Sstevel@tonic-gate * The rest of the attributes are all single letters. 1126*7c478bd9Sstevel@tonic-gate * Make sure the specified attribute is a single letter. 1127*7c478bd9Sstevel@tonic-gate */ 1128*7c478bd9Sstevel@tonic-gate if (strlen(ident) != 1) { 1129*7c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 1130*7c478bd9Sstevel@tonic-gate return; 1131*7c478bd9Sstevel@tonic-gate } 1132*7c478bd9Sstevel@tonic-gate /* 1133*7c478bd9Sstevel@tonic-gate * Also make sure it is within the legal range of letters. 1134*7c478bd9Sstevel@tonic-gate */ 1135*7c478bd9Sstevel@tonic-gate if (ident[0] < PARTITION_BASE || ident[0] > PARTITION_BASE+9) { 1136*7c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 1137*7c478bd9Sstevel@tonic-gate return; 1138*7c478bd9Sstevel@tonic-gate } 1139*7c478bd9Sstevel@tonic-gate /* 1140*7c478bd9Sstevel@tonic-gate * Here's the index of the partition we're dealing with 1141*7c478bd9Sstevel@tonic-gate */ 1142*7c478bd9Sstevel@tonic-gate index = ident[0] - PARTITION_BASE; 1143*7c478bd9Sstevel@tonic-gate /* 1144*7c478bd9Sstevel@tonic-gate * For SunOS 5.0, we support the additional syntax: 1145*7c478bd9Sstevel@tonic-gate * [<tag>, ] [<flag>, ] <start>, <end> 1146*7c478bd9Sstevel@tonic-gate * instead of: 1147*7c478bd9Sstevel@tonic-gate * <start>, <end> 1148*7c478bd9Sstevel@tonic-gate * 1149*7c478bd9Sstevel@tonic-gate * <tag> may be one of: boot, root, swap, etc. 1150*7c478bd9Sstevel@tonic-gate * <flag> consists of two characters: 1151*7c478bd9Sstevel@tonic-gate * W (writable) or R (read-only) 1152*7c478bd9Sstevel@tonic-gate * M (mountable) or U (unmountable) 1153*7c478bd9Sstevel@tonic-gate * 1154*7c478bd9Sstevel@tonic-gate * Start with the defaults assigned above: 1155*7c478bd9Sstevel@tonic-gate */ 1156*7c478bd9Sstevel@tonic-gate vtoc_tag = pinfo->vtoc.v_part[index].p_tag; 1157*7c478bd9Sstevel@tonic-gate vtoc_flag = pinfo->vtoc.v_part[index].p_flag; 1158*7c478bd9Sstevel@tonic-gate 1159*7c478bd9Sstevel@tonic-gate /* 1160*7c478bd9Sstevel@tonic-gate * First try to match token against possible tag values 1161*7c478bd9Sstevel@tonic-gate */ 1162*7c478bd9Sstevel@tonic-gate if (find_value(ptag_choices, cleaned, &i) == 1) { 1163*7c478bd9Sstevel@tonic-gate /* 1164*7c478bd9Sstevel@tonic-gate * Found valid tag. Use it and advance parser 1165*7c478bd9Sstevel@tonic-gate */ 1166*7c478bd9Sstevel@tonic-gate vtoc_tag = (ushort_t)i; 1167*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1168*7c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 1169*7c478bd9Sstevel@tonic-gate datafile_error( 1170*7c478bd9Sstevel@tonic-gate "Expecting ', ', found '%s'", 1171*7c478bd9Sstevel@tonic-gate token); 1172*7c478bd9Sstevel@tonic-gate return; 1173*7c478bd9Sstevel@tonic-gate } 1174*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1175*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 1176*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", 1177*7c478bd9Sstevel@tonic-gate token); 1178*7c478bd9Sstevel@tonic-gate return; 1179*7c478bd9Sstevel@tonic-gate } 1180*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 1181*7c478bd9Sstevel@tonic-gate } 1182*7c478bd9Sstevel@tonic-gate 1183*7c478bd9Sstevel@tonic-gate /* 1184*7c478bd9Sstevel@tonic-gate * Try to match token against possible flag values 1185*7c478bd9Sstevel@tonic-gate */ 1186*7c478bd9Sstevel@tonic-gate if (find_value(pflag_choices, cleaned, &i) == 1) { 1187*7c478bd9Sstevel@tonic-gate /* 1188*7c478bd9Sstevel@tonic-gate * Found valid flag. Use it and advance parser 1189*7c478bd9Sstevel@tonic-gate */ 1190*7c478bd9Sstevel@tonic-gate vtoc_flag = (ushort_t)i; 1191*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1192*7c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 1193*7c478bd9Sstevel@tonic-gate datafile_error("Expecting ', ', found '%s'", 1194*7c478bd9Sstevel@tonic-gate token); 1195*7c478bd9Sstevel@tonic-gate return; 1196*7c478bd9Sstevel@tonic-gate } 1197*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1198*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 1199*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", 1200*7c478bd9Sstevel@tonic-gate token); 1201*7c478bd9Sstevel@tonic-gate return; 1202*7c478bd9Sstevel@tonic-gate } 1203*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 1204*7c478bd9Sstevel@tonic-gate } 1205*7c478bd9Sstevel@tonic-gate /* 1206*7c478bd9Sstevel@tonic-gate * All other attributes have a pair of numeric values. 1207*7c478bd9Sstevel@tonic-gate * Convert the first value to a number. This value 1208*7c478bd9Sstevel@tonic-gate * is the starting cylinder number of the partition. 1209*7c478bd9Sstevel@tonic-gate */ 1210*7c478bd9Sstevel@tonic-gate val1 = str2cyls(cleaned); 1211*7c478bd9Sstevel@tonic-gate if (val1 == -1) { 1212*7c478bd9Sstevel@tonic-gate datafile_error("Expecting an integer, found '%s'", 1213*7c478bd9Sstevel@tonic-gate cleaned); 1214*7c478bd9Sstevel@tonic-gate return; 1215*7c478bd9Sstevel@tonic-gate } 1216*7c478bd9Sstevel@tonic-gate /* 1217*7c478bd9Sstevel@tonic-gate * Pull in some grammar. 1218*7c478bd9Sstevel@tonic-gate */ 1219*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1220*7c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 1221*7c478bd9Sstevel@tonic-gate datafile_error("Expecting ', ', found '%s'", token); 1222*7c478bd9Sstevel@tonic-gate return; 1223*7c478bd9Sstevel@tonic-gate } 1224*7c478bd9Sstevel@tonic-gate /* 1225*7c478bd9Sstevel@tonic-gate * Pull in the second value. 1226*7c478bd9Sstevel@tonic-gate */ 1227*7c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 1228*7c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 1229*7c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 1230*7c478bd9Sstevel@tonic-gate return; 1231*7c478bd9Sstevel@tonic-gate } 1232*7c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 1233*7c478bd9Sstevel@tonic-gate /* 1234*7c478bd9Sstevel@tonic-gate * Convert the second value to a number. This value 1235*7c478bd9Sstevel@tonic-gate * is the number of blocks composing the partition. 1236*7c478bd9Sstevel@tonic-gate * If the token is terminated with a 'c', the units 1237*7c478bd9Sstevel@tonic-gate * are cylinders, not blocks. Also accept a 'b', if 1238*7c478bd9Sstevel@tonic-gate * they choose to be so specific. 1239*7c478bd9Sstevel@tonic-gate */ 1240*7c478bd9Sstevel@tonic-gate val2 = str2blks(cleaned); 1241*7c478bd9Sstevel@tonic-gate if (val2 == -1) { 1242*7c478bd9Sstevel@tonic-gate datafile_error("Expecting an integer, found '%s'", 1243*7c478bd9Sstevel@tonic-gate cleaned); 1244*7c478bd9Sstevel@tonic-gate return; 1245*7c478bd9Sstevel@tonic-gate } 1246*7c478bd9Sstevel@tonic-gate /* 1247*7c478bd9Sstevel@tonic-gate * Fill in the appropriate map entry with the values. 1248*7c478bd9Sstevel@tonic-gate */ 1249*7c478bd9Sstevel@tonic-gate pinfo->pinfo_map[index].dkl_cylno = val1; 1250*7c478bd9Sstevel@tonic-gate pinfo->pinfo_map[index].dkl_nblk = val2; 1251*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_tag = vtoc_tag; 1252*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_flag = vtoc_flag; 1253*7c478bd9Sstevel@tonic-gate 1254*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 1255*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_start = val1 * (nhead * nsect); 1256*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_size = val2; 1257*7c478bd9Sstevel@tonic-gate 1258*7c478bd9Sstevel@tonic-gate if (val2 == 0) { 1259*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_tag = 0; 1260*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_flag = 0; 1261*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_start = 0; 1262*7c478bd9Sstevel@tonic-gate pinfo->pinfo_map[index].dkl_cylno = 0; 1263*7c478bd9Sstevel@tonic-gate } 1264*7c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 1265*7c478bd9Sstevel@tonic-gate 1266*7c478bd9Sstevel@tonic-gate } 1267*7c478bd9Sstevel@tonic-gate /* 1268*7c478bd9Sstevel@tonic-gate * Check to be sure that all necessary attributes were defined. 1269*7c478bd9Sstevel@tonic-gate */ 1270*7c478bd9Sstevel@tonic-gate if ((flags & SUP_MIN_PART) != SUP_MIN_PART) { 1271*7c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 1272*7c478bd9Sstevel@tonic-gate return; 1273*7c478bd9Sstevel@tonic-gate } 1274*7c478bd9Sstevel@tonic-gate /* 1275*7c478bd9Sstevel@tonic-gate * Add this partition map to the list of known maps for the 1276*7c478bd9Sstevel@tonic-gate * specified disk/ctlr. 1277*7c478bd9Sstevel@tonic-gate */ 1278*7c478bd9Sstevel@tonic-gate parts = dtype->dtype_plist; 1279*7c478bd9Sstevel@tonic-gate if (parts == NULL) 1280*7c478bd9Sstevel@tonic-gate dtype->dtype_plist = pinfo; 1281*7c478bd9Sstevel@tonic-gate else { 1282*7c478bd9Sstevel@tonic-gate while (parts->pinfo_next != NULL) 1283*7c478bd9Sstevel@tonic-gate parts = parts->pinfo_next; 1284*7c478bd9Sstevel@tonic-gate parts->pinfo_next = pinfo; 1285*7c478bd9Sstevel@tonic-gate } 1286*7c478bd9Sstevel@tonic-gate } 1287*7c478bd9Sstevel@tonic-gate 1288*7c478bd9Sstevel@tonic-gate /* 1289*7c478bd9Sstevel@tonic-gate * Open the disk device - just a wrapper for open. 1290*7c478bd9Sstevel@tonic-gate */ 1291*7c478bd9Sstevel@tonic-gate int 1292*7c478bd9Sstevel@tonic-gate open_disk(char *diskname, int flags) 1293*7c478bd9Sstevel@tonic-gate { 1294*7c478bd9Sstevel@tonic-gate return (open(diskname, flags)); 1295*7c478bd9Sstevel@tonic-gate } 1296*7c478bd9Sstevel@tonic-gate 1297*7c478bd9Sstevel@tonic-gate /* 1298*7c478bd9Sstevel@tonic-gate * This routine performs the disk search during startup. It looks for 1299*7c478bd9Sstevel@tonic-gate * all the disks in the search path, and creates a list of those that 1300*7c478bd9Sstevel@tonic-gate * are found. 1301*7c478bd9Sstevel@tonic-gate */ 1302*7c478bd9Sstevel@tonic-gate void 1303*7c478bd9Sstevel@tonic-gate do_search(char *arglist[]) 1304*7c478bd9Sstevel@tonic-gate { 1305*7c478bd9Sstevel@tonic-gate char **sp; 1306*7c478bd9Sstevel@tonic-gate DIR *dir; 1307*7c478bd9Sstevel@tonic-gate struct dirent *dp; 1308*7c478bd9Sstevel@tonic-gate char s[MAXPATHLEN]; 1309*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 1310*7c478bd9Sstevel@tonic-gate char curdir[MAXPATHLEN]; 1311*7c478bd9Sstevel@tonic-gate char *directory = "/dev/rdsk"; 1312*7c478bd9Sstevel@tonic-gate struct disk_info *disk; 1313*7c478bd9Sstevel@tonic-gate int i; 1314*7c478bd9Sstevel@tonic-gate 1315*7c478bd9Sstevel@tonic-gate /* 1316*7c478bd9Sstevel@tonic-gate * Change directory to the device directory. This 1317*7c478bd9Sstevel@tonic-gate * gives us the most efficient access to that directory. 1318*7c478bd9Sstevel@tonic-gate * Remember where we were, and return there when finished. 1319*7c478bd9Sstevel@tonic-gate */ 1320*7c478bd9Sstevel@tonic-gate if (getcwd(curdir, sizeof (curdir)) == NULL) { 1321*7c478bd9Sstevel@tonic-gate err_print("Cannot get current directory - %s\n", 1322*7c478bd9Sstevel@tonic-gate strerror(errno)); 1323*7c478bd9Sstevel@tonic-gate fullabort(); 1324*7c478bd9Sstevel@tonic-gate } 1325*7c478bd9Sstevel@tonic-gate if (chdir(directory) == -1) { 1326*7c478bd9Sstevel@tonic-gate err_print("Cannot set directory to %s - %s\n", 1327*7c478bd9Sstevel@tonic-gate directory, strerror(errno)); 1328*7c478bd9Sstevel@tonic-gate fullabort(); 1329*7c478bd9Sstevel@tonic-gate } 1330*7c478bd9Sstevel@tonic-gate 1331*7c478bd9Sstevel@tonic-gate /* 1332*7c478bd9Sstevel@tonic-gate * If there were disks specified on the command line, 1333*7c478bd9Sstevel@tonic-gate * use those disks, and nothing but those disks. 1334*7c478bd9Sstevel@tonic-gate */ 1335*7c478bd9Sstevel@tonic-gate if (arglist != NULL) { 1336*7c478bd9Sstevel@tonic-gate check_for_duplicate_disknames(arglist); 1337*7c478bd9Sstevel@tonic-gate for (; *arglist != NULL; arglist++) { 1338*7c478bd9Sstevel@tonic-gate search_for_logical_dev(*arglist); 1339*7c478bd9Sstevel@tonic-gate } 1340*7c478bd9Sstevel@tonic-gate } else { 1341*7c478bd9Sstevel@tonic-gate /* 1342*7c478bd9Sstevel@tonic-gate * If there were no disks specified on the command line, 1343*7c478bd9Sstevel@tonic-gate * search for all disks attached to the system. 1344*7c478bd9Sstevel@tonic-gate */ 1345*7c478bd9Sstevel@tonic-gate fmt_print("Searching for disks..."); 1346*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 1347*7c478bd9Sstevel@tonic-gate need_newline = 1; 1348*7c478bd9Sstevel@tonic-gate 1349*7c478bd9Sstevel@tonic-gate /* 1350*7c478bd9Sstevel@tonic-gate * Find all disks specified in search_path definitions 1351*7c478bd9Sstevel@tonic-gate * in whatever format.dat files were processed. 1352*7c478bd9Sstevel@tonic-gate */ 1353*7c478bd9Sstevel@tonic-gate sp = search_path; 1354*7c478bd9Sstevel@tonic-gate if (sp != NULL) { 1355*7c478bd9Sstevel@tonic-gate while (*sp != NULL) { 1356*7c478bd9Sstevel@tonic-gate search_for_logical_dev(*sp++); 1357*7c478bd9Sstevel@tonic-gate } 1358*7c478bd9Sstevel@tonic-gate } 1359*7c478bd9Sstevel@tonic-gate 1360*7c478bd9Sstevel@tonic-gate /* 1361*7c478bd9Sstevel@tonic-gate * Open the device directory 1362*7c478bd9Sstevel@tonic-gate */ 1363*7c478bd9Sstevel@tonic-gate if ((dir = opendir(".")) == NULL) { 1364*7c478bd9Sstevel@tonic-gate err_print("Cannot open %s - %s\n", 1365*7c478bd9Sstevel@tonic-gate directory, strerror(errno)); 1366*7c478bd9Sstevel@tonic-gate fullabort(); 1367*7c478bd9Sstevel@tonic-gate } 1368*7c478bd9Sstevel@tonic-gate 1369*7c478bd9Sstevel@tonic-gate /* 1370*7c478bd9Sstevel@tonic-gate * Now find all usable nodes in /dev/rdsk (or /dev, if 4.x) 1371*7c478bd9Sstevel@tonic-gate * First find all nodes which do not conform to 1372*7c478bd9Sstevel@tonic-gate * standard disk naming conventions. This permits 1373*7c478bd9Sstevel@tonic-gate * all user-defined names to override the default names. 1374*7c478bd9Sstevel@tonic-gate */ 1375*7c478bd9Sstevel@tonic-gate while ((dp = readdir(dir)) != NULL) { 1376*7c478bd9Sstevel@tonic-gate if (strcmp(dp->d_name, ".") == 0 || 1377*7c478bd9Sstevel@tonic-gate strcmp(dp->d_name, "..") == 0) 1378*7c478bd9Sstevel@tonic-gate continue; 1379*7c478bd9Sstevel@tonic-gate if (!conventional_name(dp->d_name)) { 1380*7c478bd9Sstevel@tonic-gate if (!fdisk_physical_name(dp->d_name)) { 1381*7c478bd9Sstevel@tonic-gate /* 1382*7c478bd9Sstevel@tonic-gate * If non-conventional name represents 1383*7c478bd9Sstevel@tonic-gate * a link to non-s2 slice , ignore it. 1384*7c478bd9Sstevel@tonic-gate */ 1385*7c478bd9Sstevel@tonic-gate if (!name_represents_wholedisk 1386*7c478bd9Sstevel@tonic-gate (dp->d_name)) { 1387*7c478bd9Sstevel@tonic-gate (void) strcpy(path, directory); 1388*7c478bd9Sstevel@tonic-gate (void) strcat(path, "/"); 1389*7c478bd9Sstevel@tonic-gate (void) strcat(path, dp->d_name); 1390*7c478bd9Sstevel@tonic-gate add_device_to_disklist(dp->d_name, 1391*7c478bd9Sstevel@tonic-gate path); 1392*7c478bd9Sstevel@tonic-gate } 1393*7c478bd9Sstevel@tonic-gate } 1394*7c478bd9Sstevel@tonic-gate } 1395*7c478bd9Sstevel@tonic-gate 1396*7c478bd9Sstevel@tonic-gate } 1397*7c478bd9Sstevel@tonic-gate rewinddir(dir); 1398*7c478bd9Sstevel@tonic-gate 1399*7c478bd9Sstevel@tonic-gate 1400*7c478bd9Sstevel@tonic-gate /* 1401*7c478bd9Sstevel@tonic-gate * Now find all nodes corresponding to the standard 1402*7c478bd9Sstevel@tonic-gate * device naming conventions. 1403*7c478bd9Sstevel@tonic-gate */ 1404*7c478bd9Sstevel@tonic-gate while ((dp = readdir(dir)) != NULL) { 1405*7c478bd9Sstevel@tonic-gate if (strcmp(dp->d_name, ".") == 0 || 1406*7c478bd9Sstevel@tonic-gate strcmp(dp->d_name, "..") == 0) 1407*7c478bd9Sstevel@tonic-gate continue; 1408*7c478bd9Sstevel@tonic-gate if (whole_disk_name(dp->d_name)) { 1409*7c478bd9Sstevel@tonic-gate (void) strcpy(path, directory); 1410*7c478bd9Sstevel@tonic-gate (void) strcat(path, "/"); 1411*7c478bd9Sstevel@tonic-gate (void) strcat(path, dp->d_name); 1412*7c478bd9Sstevel@tonic-gate canonicalize_name(s, dp->d_name); 1413*7c478bd9Sstevel@tonic-gate add_device_to_disklist(s, path); 1414*7c478bd9Sstevel@tonic-gate } 1415*7c478bd9Sstevel@tonic-gate } 1416*7c478bd9Sstevel@tonic-gate /* 1417*7c478bd9Sstevel@tonic-gate * Close the directory 1418*7c478bd9Sstevel@tonic-gate */ 1419*7c478bd9Sstevel@tonic-gate if (closedir(dir) == -1) { 1420*7c478bd9Sstevel@tonic-gate err_print("Cannot close directory %s - %s\n", 1421*7c478bd9Sstevel@tonic-gate directory, strerror(errno)); 1422*7c478bd9Sstevel@tonic-gate fullabort(); 1423*7c478bd9Sstevel@tonic-gate } 1424*7c478bd9Sstevel@tonic-gate 1425*7c478bd9Sstevel@tonic-gate need_newline = 0; 1426*7c478bd9Sstevel@tonic-gate fmt_print("done\n"); 1427*7c478bd9Sstevel@tonic-gate } 1428*7c478bd9Sstevel@tonic-gate 1429*7c478bd9Sstevel@tonic-gate /* 1430*7c478bd9Sstevel@tonic-gate * Return to whence we came 1431*7c478bd9Sstevel@tonic-gate */ 1432*7c478bd9Sstevel@tonic-gate if (chdir(curdir) == -1) { 1433*7c478bd9Sstevel@tonic-gate err_print("Cannot set directory to %s - %s\n", 1434*7c478bd9Sstevel@tonic-gate curdir, strerror(errno)); 1435*7c478bd9Sstevel@tonic-gate fullabort(); 1436*7c478bd9Sstevel@tonic-gate } 1437*7c478bd9Sstevel@tonic-gate 1438*7c478bd9Sstevel@tonic-gate /* 1439*7c478bd9Sstevel@tonic-gate * If we didn't find any disks, give up. 1440*7c478bd9Sstevel@tonic-gate */ 1441*7c478bd9Sstevel@tonic-gate if (disk_list == NULL) { 1442*7c478bd9Sstevel@tonic-gate if (geteuid() == 0) { 1443*7c478bd9Sstevel@tonic-gate err_print("No disks found!\n"); 1444*7c478bd9Sstevel@tonic-gate } else { 1445*7c478bd9Sstevel@tonic-gate err_print("No permission (or no disks found)!\n"); 1446*7c478bd9Sstevel@tonic-gate } 1447*7c478bd9Sstevel@tonic-gate (void) fflush(stdout); 1448*7c478bd9Sstevel@tonic-gate fullabort(); 1449*7c478bd9Sstevel@tonic-gate } 1450*7c478bd9Sstevel@tonic-gate 1451*7c478bd9Sstevel@tonic-gate sort_disk_list(); 1452*7c478bd9Sstevel@tonic-gate 1453*7c478bd9Sstevel@tonic-gate /* 1454*7c478bd9Sstevel@tonic-gate * Tell user the results of the auto-configure process 1455*7c478bd9Sstevel@tonic-gate */ 1456*7c478bd9Sstevel@tonic-gate i = 0; 1457*7c478bd9Sstevel@tonic-gate for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 1458*7c478bd9Sstevel@tonic-gate float scaled; 1459*7c478bd9Sstevel@tonic-gate long nblks; 1460*7c478bd9Sstevel@tonic-gate struct disk_type *type; 1461*7c478bd9Sstevel@tonic-gate if (disk->disk_flags & DSK_AUTO_CONFIG) { 1462*7c478bd9Sstevel@tonic-gate if (i++ == 0) { 1463*7c478bd9Sstevel@tonic-gate fmt_print("\n"); 1464*7c478bd9Sstevel@tonic-gate } 1465*7c478bd9Sstevel@tonic-gate fmt_print("%s: ", disk->disk_name); 1466*7c478bd9Sstevel@tonic-gate if (disk->disk_flags & DSK_LABEL_DIRTY) { 1467*7c478bd9Sstevel@tonic-gate fmt_print("configured "); 1468*7c478bd9Sstevel@tonic-gate } else { 1469*7c478bd9Sstevel@tonic-gate fmt_print("configured and labeled "); 1470*7c478bd9Sstevel@tonic-gate } 1471*7c478bd9Sstevel@tonic-gate type = disk->disk_type; 1472*7c478bd9Sstevel@tonic-gate nblks = type->dtype_ncyl * type->dtype_nhead * 1473*7c478bd9Sstevel@tonic-gate type->dtype_nsect; 1474*7c478bd9Sstevel@tonic-gate if (disk->label_type == L_TYPE_SOLARIS) 1475*7c478bd9Sstevel@tonic-gate scaled = bn2mb(nblks); 1476*7c478bd9Sstevel@tonic-gate else 1477*7c478bd9Sstevel@tonic-gate scaled = bn2mb(type->capacity); 1478*7c478bd9Sstevel@tonic-gate fmt_print("with capacity of "); 1479*7c478bd9Sstevel@tonic-gate if (scaled > 1024.0) { 1480*7c478bd9Sstevel@tonic-gate fmt_print("%1.2fGB\n", scaled/1024.0); 1481*7c478bd9Sstevel@tonic-gate } else { 1482*7c478bd9Sstevel@tonic-gate fmt_print("%1.2fMB\n", scaled); 1483*7c478bd9Sstevel@tonic-gate } 1484*7c478bd9Sstevel@tonic-gate } 1485*7c478bd9Sstevel@tonic-gate } 1486*7c478bd9Sstevel@tonic-gate } 1487*7c478bd9Sstevel@tonic-gate 1488*7c478bd9Sstevel@tonic-gate 1489*7c478bd9Sstevel@tonic-gate /* 1490*7c478bd9Sstevel@tonic-gate * For a given "logical" disk name as specified in a format.dat 1491*7c478bd9Sstevel@tonic-gate * search path, try to find the device it actually refers to. 1492*7c478bd9Sstevel@tonic-gate * Since we are trying to maintain 4.x naming convention 1493*7c478bd9Sstevel@tonic-gate * compatibility in 5.0, this involves a little bit of work. 1494*7c478bd9Sstevel@tonic-gate * We also want to be able to function under 4.x, if needed. 1495*7c478bd9Sstevel@tonic-gate * 1496*7c478bd9Sstevel@tonic-gate * canonical: standard name reference. append a partition 1497*7c478bd9Sstevel@tonic-gate * reference, and open that file in the device directory. 1498*7c478bd9Sstevel@tonic-gate * examples: SVR4: c0t0d0 1499*7c478bd9Sstevel@tonic-gate * 4.x: sd0 1500*7c478bd9Sstevel@tonic-gate * 1501*7c478bd9Sstevel@tonic-gate * absolute: begins with a '/', and is assumed to be an 1502*7c478bd9Sstevel@tonic-gate * absolute pathname to some node. 1503*7c478bd9Sstevel@tonic-gate * 1504*7c478bd9Sstevel@tonic-gate * relative: non-canonical, doesn't begin with a '/'. 1505*7c478bd9Sstevel@tonic-gate * assumed to be the name of a file in the appropriate 1506*7c478bd9Sstevel@tonic-gate * device directory. 1507*7c478bd9Sstevel@tonic-gate */ 1508*7c478bd9Sstevel@tonic-gate static void 1509*7c478bd9Sstevel@tonic-gate search_for_logical_dev(char *devname) 1510*7c478bd9Sstevel@tonic-gate { 1511*7c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 1512*7c478bd9Sstevel@tonic-gate char *directory = "/dev/rdsk/"; 1513*7c478bd9Sstevel@tonic-gate char *partition = "s2"; 1514*7c478bd9Sstevel@tonic-gate 1515*7c478bd9Sstevel@tonic-gate /* 1516*7c478bd9Sstevel@tonic-gate * If the name is an absolute path name, accept it as is 1517*7c478bd9Sstevel@tonic-gate */ 1518*7c478bd9Sstevel@tonic-gate if (*devname == '/') { 1519*7c478bd9Sstevel@tonic-gate (void) strcpy(path, devname); 1520*7c478bd9Sstevel@tonic-gate } else if (canonical_name(devname)) { 1521*7c478bd9Sstevel@tonic-gate /* 1522*7c478bd9Sstevel@tonic-gate * If canonical name, construct a standard path name. 1523*7c478bd9Sstevel@tonic-gate */ 1524*7c478bd9Sstevel@tonic-gate (void) strcpy(path, directory); 1525*7c478bd9Sstevel@tonic-gate (void) strcat(path, devname); 1526*7c478bd9Sstevel@tonic-gate (void) strcat(path, partition); 1527*7c478bd9Sstevel@tonic-gate } else if (canonical4x_name(devname)) { 1528*7c478bd9Sstevel@tonic-gate /* 1529*7c478bd9Sstevel@tonic-gate * Check to see if it's a 4.x file name in the /dev 1530*7c478bd9Sstevel@tonic-gate * directory on 5.0. Here, we only accept the 1531*7c478bd9Sstevel@tonic-gate * canonicalized form: sd0. 1532*7c478bd9Sstevel@tonic-gate */ 1533*7c478bd9Sstevel@tonic-gate (void) strcpy(path, "/dev/r"); 1534*7c478bd9Sstevel@tonic-gate (void) strcat(path, devname); 1535*7c478bd9Sstevel@tonic-gate (void) strcat(path, "c"); 1536*7c478bd9Sstevel@tonic-gate } else { 1537*7c478bd9Sstevel@tonic-gate /* 1538*7c478bd9Sstevel@tonic-gate * If it's not a canonical name, then it may be a 1539*7c478bd9Sstevel@tonic-gate * reference to an actual file name in the device 1540*7c478bd9Sstevel@tonic-gate * directory itself. 1541*7c478bd9Sstevel@tonic-gate */ 1542*7c478bd9Sstevel@tonic-gate (void) strcpy(path, directory); 1543*7c478bd9Sstevel@tonic-gate (void) strcat(path, devname); 1544*7c478bd9Sstevel@tonic-gate } 1545*7c478bd9Sstevel@tonic-gate 1546*7c478bd9Sstevel@tonic-gate /* now add the device */ 1547*7c478bd9Sstevel@tonic-gate add_device_to_disklist(devname, path); 1548*7c478bd9Sstevel@tonic-gate } 1549*7c478bd9Sstevel@tonic-gate 1550*7c478bd9Sstevel@tonic-gate 1551*7c478bd9Sstevel@tonic-gate /* 1552*7c478bd9Sstevel@tonic-gate * Add a device to the disk list, if it appears to be a disk, 1553*7c478bd9Sstevel@tonic-gate * and we haven't already found it under some other name. 1554*7c478bd9Sstevel@tonic-gate */ 1555*7c478bd9Sstevel@tonic-gate static void 1556*7c478bd9Sstevel@tonic-gate add_device_to_disklist(char *devname, char *devpath) 1557*7c478bd9Sstevel@tonic-gate { 1558*7c478bd9Sstevel@tonic-gate struct disk_info *search_disk; 1559*7c478bd9Sstevel@tonic-gate struct ctlr_info *search_ctlr; 1560*7c478bd9Sstevel@tonic-gate struct disk_type *search_dtype, *efi_disk; 1561*7c478bd9Sstevel@tonic-gate struct partition_info *search_parts; 1562*7c478bd9Sstevel@tonic-gate struct disk_info *dptr; 1563*7c478bd9Sstevel@tonic-gate struct ctlr_info *cptr; 1564*7c478bd9Sstevel@tonic-gate struct disk_type *type; 1565*7c478bd9Sstevel@tonic-gate struct partition_info *parts; 1566*7c478bd9Sstevel@tonic-gate struct dk_label search_label; 1567*7c478bd9Sstevel@tonic-gate struct dk_cinfo dkinfo; 1568*7c478bd9Sstevel@tonic-gate struct stat stbuf; 1569*7c478bd9Sstevel@tonic-gate struct ctlr_type *ctlr, *tctlr; 1570*7c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 1571*7c478bd9Sstevel@tonic-gate struct efi_info efi_info; 1572*7c478bd9Sstevel@tonic-gate int search_file; 1573*7c478bd9Sstevel@tonic-gate int status; 1574*7c478bd9Sstevel@tonic-gate int i; 1575*7c478bd9Sstevel@tonic-gate int access_flags = 0; 1576*7c478bd9Sstevel@tonic-gate 1577*7c478bd9Sstevel@tonic-gate /* 1578*7c478bd9Sstevel@tonic-gate * Attempt to open the disk. If it fails, skip it. 1579*7c478bd9Sstevel@tonic-gate */ 1580*7c478bd9Sstevel@tonic-gate if ((search_file = open_disk(devpath, O_RDWR | O_NDELAY)) < 0) { 1581*7c478bd9Sstevel@tonic-gate return; 1582*7c478bd9Sstevel@tonic-gate } 1583*7c478bd9Sstevel@tonic-gate /* 1584*7c478bd9Sstevel@tonic-gate * Must be a character device 1585*7c478bd9Sstevel@tonic-gate */ 1586*7c478bd9Sstevel@tonic-gate if (fstat(search_file, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) { 1587*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1588*7c478bd9Sstevel@tonic-gate return; 1589*7c478bd9Sstevel@tonic-gate } 1590*7c478bd9Sstevel@tonic-gate /* 1591*7c478bd9Sstevel@tonic-gate * Attempt to read the configuration info on the disk. 1592*7c478bd9Sstevel@tonic-gate * Again, if it fails, we assume the disk's not there. 1593*7c478bd9Sstevel@tonic-gate * Note we must close the file for the disk before we 1594*7c478bd9Sstevel@tonic-gate * continue. 1595*7c478bd9Sstevel@tonic-gate */ 1596*7c478bd9Sstevel@tonic-gate if (ioctl(search_file, DKIOCINFO, &dkinfo) < 0) { 1597*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1598*7c478bd9Sstevel@tonic-gate return; 1599*7c478bd9Sstevel@tonic-gate } 1600*7c478bd9Sstevel@tonic-gate 1601*7c478bd9Sstevel@tonic-gate /* If it is a removable media, skip it. */ 1602*7c478bd9Sstevel@tonic-gate 1603*7c478bd9Sstevel@tonic-gate if (!expert_mode) { 1604*7c478bd9Sstevel@tonic-gate int isremovable, ret; 1605*7c478bd9Sstevel@tonic-gate ret = ioctl(search_file, DKIOCREMOVABLE, &isremovable); 1606*7c478bd9Sstevel@tonic-gate if ((ret >= 0) && (isremovable != 0)) { 1607*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1608*7c478bd9Sstevel@tonic-gate return; 1609*7c478bd9Sstevel@tonic-gate } 1610*7c478bd9Sstevel@tonic-gate } 1611*7c478bd9Sstevel@tonic-gate 1612*7c478bd9Sstevel@tonic-gate /* 1613*7c478bd9Sstevel@tonic-gate * If the type of disk is one we don't know about, 1614*7c478bd9Sstevel@tonic-gate * add it to the list. 1615*7c478bd9Sstevel@tonic-gate */ 1616*7c478bd9Sstevel@tonic-gate mlp = controlp; 1617*7c478bd9Sstevel@tonic-gate 1618*7c478bd9Sstevel@tonic-gate while (mlp != NULL) { 1619*7c478bd9Sstevel@tonic-gate if (mlp->ctlr_type->ctype_ctype == dkinfo.dki_ctype && 1620*7c478bd9Sstevel@tonic-gate strcmp(mlp->ctlr_type->ctype_name, dkinfo.dki_cname) == 0) { 1621*7c478bd9Sstevel@tonic-gate break; 1622*7c478bd9Sstevel@tonic-gate } 1623*7c478bd9Sstevel@tonic-gate mlp = mlp->next; 1624*7c478bd9Sstevel@tonic-gate } 1625*7c478bd9Sstevel@tonic-gate 1626*7c478bd9Sstevel@tonic-gate if (mlp == NULL) { 1627*7c478bd9Sstevel@tonic-gate /* 1628*7c478bd9Sstevel@tonic-gate * Skip CDROM devices, they are read only. 1629*7c478bd9Sstevel@tonic-gate * Also skip PCMCIA memory card device since 1630*7c478bd9Sstevel@tonic-gate * it is used as a pseudo floppy disk drive 1631*7c478bd9Sstevel@tonic-gate * at the present time (BugID 1201473) 1632*7c478bd9Sstevel@tonic-gate */ 1633*7c478bd9Sstevel@tonic-gate if ((dkinfo.dki_ctype == DKC_CDROM) || 1634*7c478bd9Sstevel@tonic-gate (dkinfo.dki_ctype == DKC_PCMCIA_MEM)) { 1635*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1636*7c478bd9Sstevel@tonic-gate return; 1637*7c478bd9Sstevel@tonic-gate } 1638*7c478bd9Sstevel@tonic-gate /* 1639*7c478bd9Sstevel@tonic-gate * create the new ctlr_type structure and fill it in. 1640*7c478bd9Sstevel@tonic-gate */ 1641*7c478bd9Sstevel@tonic-gate tctlr = zalloc(sizeof (struct ctlr_type)); 1642*7c478bd9Sstevel@tonic-gate tctlr->ctype_ctype = dkinfo.dki_ctype; 1643*7c478bd9Sstevel@tonic-gate tctlr->ctype_name = zalloc(DK_DEVLEN); 1644*7c478bd9Sstevel@tonic-gate if (strlcpy(tctlr->ctype_name, dkinfo.dki_cname, 1645*7c478bd9Sstevel@tonic-gate DK_DEVLEN) > DK_DEVLEN) { 1646*7c478bd9Sstevel@tonic-gate /* 1647*7c478bd9Sstevel@tonic-gate * DKIOCINFO returned a controller name longer 1648*7c478bd9Sstevel@tonic-gate * than DK_DEVLEN bytes, which means more of the 1649*7c478bd9Sstevel@tonic-gate * dk_cinfo structure may be corrupt. We don't 1650*7c478bd9Sstevel@tonic-gate * allow the user to perform any operations on 1651*7c478bd9Sstevel@tonic-gate * the device in this case 1652*7c478bd9Sstevel@tonic-gate */ 1653*7c478bd9Sstevel@tonic-gate err_print("\nError: Device %s: controller " 1654*7c478bd9Sstevel@tonic-gate "name (%s)\nis invalid. Device will not " 1655*7c478bd9Sstevel@tonic-gate "be displayed.\n", devname, dkinfo.dki_cname); 1656*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1657*7c478bd9Sstevel@tonic-gate destroy_data(tctlr->ctype_name); 1658*7c478bd9Sstevel@tonic-gate destroy_data((char *)tctlr); 1659*7c478bd9Sstevel@tonic-gate return; 1660*7c478bd9Sstevel@tonic-gate } else { 1661*7c478bd9Sstevel@tonic-gate tctlr->ctype_ops = zalloc(sizeof (struct ctlr_ops)); 1662*7c478bd9Sstevel@tonic-gate 1663*7c478bd9Sstevel@tonic-gate /* 1664*7c478bd9Sstevel@tonic-gate * copy the generic disk ops structure into local copy. 1665*7c478bd9Sstevel@tonic-gate */ 1666*7c478bd9Sstevel@tonic-gate *(tctlr->ctype_ops) = genericops; 1667*7c478bd9Sstevel@tonic-gate 1668*7c478bd9Sstevel@tonic-gate tctlr->ctype_flags = CF_WLIST; 1669*7c478bd9Sstevel@tonic-gate 1670*7c478bd9Sstevel@tonic-gate mlp = controlp; 1671*7c478bd9Sstevel@tonic-gate 1672*7c478bd9Sstevel@tonic-gate while (mlp->next != NULL) { 1673*7c478bd9Sstevel@tonic-gate mlp = mlp->next; 1674*7c478bd9Sstevel@tonic-gate } 1675*7c478bd9Sstevel@tonic-gate 1676*7c478bd9Sstevel@tonic-gate mlp->next = zalloc(sizeof (struct mctlr_list)); 1677*7c478bd9Sstevel@tonic-gate mlp->next->ctlr_type = tctlr; 1678*7c478bd9Sstevel@tonic-gate } 1679*7c478bd9Sstevel@tonic-gate } 1680*7c478bd9Sstevel@tonic-gate 1681*7c478bd9Sstevel@tonic-gate /* 1682*7c478bd9Sstevel@tonic-gate * Search through all disks known at this time, to 1683*7c478bd9Sstevel@tonic-gate * determine if we're already identified this disk. 1684*7c478bd9Sstevel@tonic-gate * If so, then there's no need to include it a 1685*7c478bd9Sstevel@tonic-gate * second time. This permits the user-defined names 1686*7c478bd9Sstevel@tonic-gate * to supercede the standard conventional names. 1687*7c478bd9Sstevel@tonic-gate */ 1688*7c478bd9Sstevel@tonic-gate if (disk_is_known(&dkinfo)) { 1689*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1690*7c478bd9Sstevel@tonic-gate return; 1691*7c478bd9Sstevel@tonic-gate } 1692*7c478bd9Sstevel@tonic-gate #if defined(sparc) 1693*7c478bd9Sstevel@tonic-gate /* 1694*7c478bd9Sstevel@tonic-gate * Because opening id with FNDELAY always succeeds, 1695*7c478bd9Sstevel@tonic-gate * read the label early on to see whether the device 1696*7c478bd9Sstevel@tonic-gate * really exists. A result of DSK_RESERVED 1697*7c478bd9Sstevel@tonic-gate * means the disk may be reserved. 1698*7c478bd9Sstevel@tonic-gate * In the future, it will be good 1699*7c478bd9Sstevel@tonic-gate * to move these into controller specific files and have a common 1700*7c478bd9Sstevel@tonic-gate * generic check for reserved disks here, including intel disks. 1701*7c478bd9Sstevel@tonic-gate */ 1702*7c478bd9Sstevel@tonic-gate if (dkinfo.dki_ctype == DKC_SCSI_CCS) { 1703*7c478bd9Sstevel@tonic-gate i = scsi_rdwr(DIR_READ, search_file, (daddr_t)0, 1704*7c478bd9Sstevel@tonic-gate 1, (char *)&search_label, F_SILENT, NULL); 1705*7c478bd9Sstevel@tonic-gate switch (i) { 1706*7c478bd9Sstevel@tonic-gate case DSK_RESERVED: 1707*7c478bd9Sstevel@tonic-gate access_flags |= DSK_RESERVED; 1708*7c478bd9Sstevel@tonic-gate break; 1709*7c478bd9Sstevel@tonic-gate case DSK_UNAVAILABLE: 1710*7c478bd9Sstevel@tonic-gate access_flags |= DSK_UNAVAILABLE; 1711*7c478bd9Sstevel@tonic-gate break; 1712*7c478bd9Sstevel@tonic-gate default: 1713*7c478bd9Sstevel@tonic-gate break; 1714*7c478bd9Sstevel@tonic-gate } 1715*7c478bd9Sstevel@tonic-gate } 1716*7c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */ 1717*7c478bd9Sstevel@tonic-gate 1718*7c478bd9Sstevel@tonic-gate /* 1719*7c478bd9Sstevel@tonic-gate * The disk appears to be present. Allocate space for the 1720*7c478bd9Sstevel@tonic-gate * disk structure and add it to the list of found disks. 1721*7c478bd9Sstevel@tonic-gate */ 1722*7c478bd9Sstevel@tonic-gate search_disk = (struct disk_info *)zalloc(sizeof (struct disk_info)); 1723*7c478bd9Sstevel@tonic-gate if (disk_list == NULL) 1724*7c478bd9Sstevel@tonic-gate disk_list = search_disk; 1725*7c478bd9Sstevel@tonic-gate else { 1726*7c478bd9Sstevel@tonic-gate for (dptr = disk_list; dptr->disk_next != NULL; 1727*7c478bd9Sstevel@tonic-gate dptr = dptr->disk_next) 1728*7c478bd9Sstevel@tonic-gate ; 1729*7c478bd9Sstevel@tonic-gate dptr->disk_next = search_disk; 1730*7c478bd9Sstevel@tonic-gate } 1731*7c478bd9Sstevel@tonic-gate /* 1732*7c478bd9Sstevel@tonic-gate * Fill in some info from the ioctls. 1733*7c478bd9Sstevel@tonic-gate */ 1734*7c478bd9Sstevel@tonic-gate search_disk->disk_dkinfo = dkinfo; 1735*7c478bd9Sstevel@tonic-gate if (is_efi_type(search_file)) { 1736*7c478bd9Sstevel@tonic-gate search_disk->label_type = L_TYPE_EFI; 1737*7c478bd9Sstevel@tonic-gate } else { 1738*7c478bd9Sstevel@tonic-gate search_disk->label_type = L_TYPE_SOLARIS; 1739*7c478bd9Sstevel@tonic-gate } 1740*7c478bd9Sstevel@tonic-gate /* 1741*7c478bd9Sstevel@tonic-gate * Remember the names of the disk 1742*7c478bd9Sstevel@tonic-gate */ 1743*7c478bd9Sstevel@tonic-gate search_disk->disk_name = alloc_string(devname); 1744*7c478bd9Sstevel@tonic-gate search_disk->disk_path = alloc_string(devpath); 1745*7c478bd9Sstevel@tonic-gate 1746*7c478bd9Sstevel@tonic-gate (void) strcpy(x86_devname, devname); 1747*7c478bd9Sstevel@tonic-gate 1748*7c478bd9Sstevel@tonic-gate /* 1749*7c478bd9Sstevel@tonic-gate * Determine if this device is linked to a physical name. 1750*7c478bd9Sstevel@tonic-gate */ 1751*7c478bd9Sstevel@tonic-gate search_disk->devfs_name = get_physical_name(devpath); 1752*7c478bd9Sstevel@tonic-gate 1753*7c478bd9Sstevel@tonic-gate /* 1754*7c478bd9Sstevel@tonic-gate * Try to match the ctlr for this disk with a ctlr we 1755*7c478bd9Sstevel@tonic-gate * have already found. A match is assumed if the ctlrs 1756*7c478bd9Sstevel@tonic-gate * are at the same address && ctypes agree 1757*7c478bd9Sstevel@tonic-gate */ 1758*7c478bd9Sstevel@tonic-gate for (search_ctlr = ctlr_list; search_ctlr != NULL; 1759*7c478bd9Sstevel@tonic-gate search_ctlr = search_ctlr->ctlr_next) 1760*7c478bd9Sstevel@tonic-gate if (search_ctlr->ctlr_addr == dkinfo.dki_addr && 1761*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_space == dkinfo.dki_space && 1762*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_ctype->ctype_ctype == 1763*7c478bd9Sstevel@tonic-gate dkinfo.dki_ctype) 1764*7c478bd9Sstevel@tonic-gate break; 1765*7c478bd9Sstevel@tonic-gate /* 1766*7c478bd9Sstevel@tonic-gate * If no match was found, we need to identify this ctlr. 1767*7c478bd9Sstevel@tonic-gate */ 1768*7c478bd9Sstevel@tonic-gate if (search_ctlr == NULL) { 1769*7c478bd9Sstevel@tonic-gate /* 1770*7c478bd9Sstevel@tonic-gate * Match the type of the ctlr to a known type. 1771*7c478bd9Sstevel@tonic-gate */ 1772*7c478bd9Sstevel@tonic-gate mlp = controlp; 1773*7c478bd9Sstevel@tonic-gate 1774*7c478bd9Sstevel@tonic-gate while (mlp != NULL) { 1775*7c478bd9Sstevel@tonic-gate if (mlp->ctlr_type->ctype_ctype == dkinfo.dki_ctype) 1776*7c478bd9Sstevel@tonic-gate break; 1777*7c478bd9Sstevel@tonic-gate mlp = mlp->next; 1778*7c478bd9Sstevel@tonic-gate } 1779*7c478bd9Sstevel@tonic-gate /* 1780*7c478bd9Sstevel@tonic-gate * If no match was found, it's an error. 1781*7c478bd9Sstevel@tonic-gate * Close the disk and report the error. 1782*7c478bd9Sstevel@tonic-gate */ 1783*7c478bd9Sstevel@tonic-gate if (mlp == NULL) { 1784*7c478bd9Sstevel@tonic-gate err_print("\nError: found disk attached to "); 1785*7c478bd9Sstevel@tonic-gate err_print("unsupported controller type '%d'.\n", 1786*7c478bd9Sstevel@tonic-gate dkinfo.dki_ctype); 1787*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1788*7c478bd9Sstevel@tonic-gate return; 1789*7c478bd9Sstevel@tonic-gate } 1790*7c478bd9Sstevel@tonic-gate /* 1791*7c478bd9Sstevel@tonic-gate * Allocate space for the ctlr structure and add it 1792*7c478bd9Sstevel@tonic-gate * to the list of found ctlrs. 1793*7c478bd9Sstevel@tonic-gate */ 1794*7c478bd9Sstevel@tonic-gate search_ctlr = (struct ctlr_info *) 1795*7c478bd9Sstevel@tonic-gate zalloc(sizeof (struct ctlr_info)); 1796*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_ctype = mlp->ctlr_type; 1797*7c478bd9Sstevel@tonic-gate if (ctlr_list == NULL) 1798*7c478bd9Sstevel@tonic-gate ctlr_list = search_ctlr; 1799*7c478bd9Sstevel@tonic-gate else { 1800*7c478bd9Sstevel@tonic-gate for (cptr = ctlr_list; cptr->ctlr_next != NULL; 1801*7c478bd9Sstevel@tonic-gate cptr = cptr->ctlr_next) 1802*7c478bd9Sstevel@tonic-gate ; 1803*7c478bd9Sstevel@tonic-gate cptr->ctlr_next = search_ctlr; 1804*7c478bd9Sstevel@tonic-gate } 1805*7c478bd9Sstevel@tonic-gate /* 1806*7c478bd9Sstevel@tonic-gate * Fill in info from the ioctl. 1807*7c478bd9Sstevel@tonic-gate */ 1808*7c478bd9Sstevel@tonic-gate for (i = 0; i < DK_DEVLEN; i++) { 1809*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_cname[i] = dkinfo.dki_cname[i]; 1810*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_dname[i] = dkinfo.dki_dname[i]; 1811*7c478bd9Sstevel@tonic-gate } 1812*7c478bd9Sstevel@tonic-gate /* 1813*7c478bd9Sstevel@tonic-gate * Make sure these can be used as simple strings 1814*7c478bd9Sstevel@tonic-gate */ 1815*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_cname[i] = 0; 1816*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_dname[i] = 0; 1817*7c478bd9Sstevel@tonic-gate 1818*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_flags = dkinfo.dki_flags; 1819*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_num = dkinfo.dki_cnum; 1820*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_addr = dkinfo.dki_addr; 1821*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_space = dkinfo.dki_space; 1822*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_prio = dkinfo.dki_prio; 1823*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_vec = dkinfo.dki_vec; 1824*7c478bd9Sstevel@tonic-gate } 1825*7c478bd9Sstevel@tonic-gate /* 1826*7c478bd9Sstevel@tonic-gate * By this point, we have a known ctlr. Link the disk 1827*7c478bd9Sstevel@tonic-gate * to the ctlr. 1828*7c478bd9Sstevel@tonic-gate */ 1829*7c478bd9Sstevel@tonic-gate search_disk->disk_ctlr = search_ctlr; 1830*7c478bd9Sstevel@tonic-gate if (access_flags & (DSK_RESERVED | DSK_UNAVAILABLE)) { 1831*7c478bd9Sstevel@tonic-gate if (access_flags & DSK_RESERVED) 1832*7c478bd9Sstevel@tonic-gate search_disk->disk_flags |= DSK_RESERVED; 1833*7c478bd9Sstevel@tonic-gate else 1834*7c478bd9Sstevel@tonic-gate search_disk->disk_flags |= DSK_UNAVAILABLE; 1835*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1836*7c478bd9Sstevel@tonic-gate return; 1837*7c478bd9Sstevel@tonic-gate } else { 1838*7c478bd9Sstevel@tonic-gate search_disk->disk_flags &= ~(DSK_RESERVED | DSK_UNAVAILABLE); 1839*7c478bd9Sstevel@tonic-gate } 1840*7c478bd9Sstevel@tonic-gate 1841*7c478bd9Sstevel@tonic-gate /* 1842*7c478bd9Sstevel@tonic-gate * Attempt to read the primary label. 1843*7c478bd9Sstevel@tonic-gate * (Note that this is really through the DKIOCGVTOC 1844*7c478bd9Sstevel@tonic-gate * ioctl, then converted from vtoc to label.) 1845*7c478bd9Sstevel@tonic-gate */ 1846*7c478bd9Sstevel@tonic-gate if (search_disk->label_type == L_TYPE_SOLARIS) { 1847*7c478bd9Sstevel@tonic-gate status = read_label(search_file, &search_label); 1848*7c478bd9Sstevel@tonic-gate } else { 1849*7c478bd9Sstevel@tonic-gate status = read_efi_label(search_file, &efi_info); 1850*7c478bd9Sstevel@tonic-gate } 1851*7c478bd9Sstevel@tonic-gate /* 1852*7c478bd9Sstevel@tonic-gate * If reading the label failed, and this is a SCSI 1853*7c478bd9Sstevel@tonic-gate * disk, we can attempt to auto-sense the disk 1854*7c478bd9Sstevel@tonic-gate * configuration. 1855*7c478bd9Sstevel@tonic-gate */ 1856*7c478bd9Sstevel@tonic-gate ctlr = search_ctlr->ctlr_ctype; 1857*7c478bd9Sstevel@tonic-gate if ((status == -1) && (ctlr->ctype_ctype == DKC_SCSI_CCS)) { 1858*7c478bd9Sstevel@tonic-gate if (option_msg && diag_msg) { 1859*7c478bd9Sstevel@tonic-gate err_print("%s: attempting auto configuration\n", 1860*7c478bd9Sstevel@tonic-gate search_disk->disk_name); 1861*7c478bd9Sstevel@tonic-gate } 1862*7c478bd9Sstevel@tonic-gate switch (search_disk->label_type) { 1863*7c478bd9Sstevel@tonic-gate case (L_TYPE_SOLARIS): 1864*7c478bd9Sstevel@tonic-gate if (auto_sense(search_file, 0, &search_label) != NULL) { 1865*7c478bd9Sstevel@tonic-gate /* 1866*7c478bd9Sstevel@tonic-gate * Auto config worked, so we now have 1867*7c478bd9Sstevel@tonic-gate * a valid label for the disk. Mark 1868*7c478bd9Sstevel@tonic-gate * the disk as needing the label flushed. 1869*7c478bd9Sstevel@tonic-gate */ 1870*7c478bd9Sstevel@tonic-gate status = 0; 1871*7c478bd9Sstevel@tonic-gate search_disk->disk_flags |= 1872*7c478bd9Sstevel@tonic-gate (DSK_LABEL_DIRTY | DSK_AUTO_CONFIG); 1873*7c478bd9Sstevel@tonic-gate } 1874*7c478bd9Sstevel@tonic-gate break; 1875*7c478bd9Sstevel@tonic-gate case (L_TYPE_EFI): 1876*7c478bd9Sstevel@tonic-gate efi_disk = auto_efi_sense(search_file, &efi_info); 1877*7c478bd9Sstevel@tonic-gate if (efi_disk != NULL) { 1878*7c478bd9Sstevel@tonic-gate /* 1879*7c478bd9Sstevel@tonic-gate * Auto config worked, so we now have 1880*7c478bd9Sstevel@tonic-gate * a valid label for the disk. 1881*7c478bd9Sstevel@tonic-gate */ 1882*7c478bd9Sstevel@tonic-gate status = 0; 1883*7c478bd9Sstevel@tonic-gate search_disk->disk_flags |= 1884*7c478bd9Sstevel@tonic-gate (DSK_LABEL_DIRTY | DSK_AUTO_CONFIG); 1885*7c478bd9Sstevel@tonic-gate } 1886*7c478bd9Sstevel@tonic-gate break; 1887*7c478bd9Sstevel@tonic-gate default: 1888*7c478bd9Sstevel@tonic-gate /* Should never happen */ 1889*7c478bd9Sstevel@tonic-gate break; 1890*7c478bd9Sstevel@tonic-gate } 1891*7c478bd9Sstevel@tonic-gate } 1892*7c478bd9Sstevel@tonic-gate /* 1893*7c478bd9Sstevel@tonic-gate * Close the file for this disk. 1894*7c478bd9Sstevel@tonic-gate */ 1895*7c478bd9Sstevel@tonic-gate (void) close(search_file); 1896*7c478bd9Sstevel@tonic-gate /* 1897*7c478bd9Sstevel@tonic-gate * If we didn't successfully read the label, or the label 1898*7c478bd9Sstevel@tonic-gate * appears corrupt, just leave the disk as an unknown type. 1899*7c478bd9Sstevel@tonic-gate */ 1900*7c478bd9Sstevel@tonic-gate if (status == -1) { 1901*7c478bd9Sstevel@tonic-gate return; 1902*7c478bd9Sstevel@tonic-gate } 1903*7c478bd9Sstevel@tonic-gate 1904*7c478bd9Sstevel@tonic-gate if (search_disk->label_type == L_TYPE_SOLARIS) { 1905*7c478bd9Sstevel@tonic-gate if (!checklabel(&search_label)) { 1906*7c478bd9Sstevel@tonic-gate return; 1907*7c478bd9Sstevel@tonic-gate } 1908*7c478bd9Sstevel@tonic-gate if (trim_id(search_label.dkl_asciilabel)) { 1909*7c478bd9Sstevel@tonic-gate return; 1910*7c478bd9Sstevel@tonic-gate } 1911*7c478bd9Sstevel@tonic-gate } 1912*7c478bd9Sstevel@tonic-gate /* 1913*7c478bd9Sstevel@tonic-gate * The label looks ok. Mark the disk as labeled. 1914*7c478bd9Sstevel@tonic-gate */ 1915*7c478bd9Sstevel@tonic-gate search_disk->disk_flags |= DSK_LABEL; 1916*7c478bd9Sstevel@tonic-gate 1917*7c478bd9Sstevel@tonic-gate if (search_disk->label_type == L_TYPE_EFI) { 1918*7c478bd9Sstevel@tonic-gate search_dtype = (struct disk_type *) 1919*7c478bd9Sstevel@tonic-gate zalloc(sizeof (struct disk_type)); 1920*7c478bd9Sstevel@tonic-gate type = search_ctlr->ctlr_ctype->ctype_dlist; 1921*7c478bd9Sstevel@tonic-gate if (type == NULL) { 1922*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_ctype->ctype_dlist = 1923*7c478bd9Sstevel@tonic-gate search_dtype; 1924*7c478bd9Sstevel@tonic-gate } else { 1925*7c478bd9Sstevel@tonic-gate while (type->dtype_next != NULL) { 1926*7c478bd9Sstevel@tonic-gate type = type->dtype_next; 1927*7c478bd9Sstevel@tonic-gate } 1928*7c478bd9Sstevel@tonic-gate type->dtype_next = search_dtype; 1929*7c478bd9Sstevel@tonic-gate } 1930*7c478bd9Sstevel@tonic-gate 1931*7c478bd9Sstevel@tonic-gate (void) strlcpy(search_dtype->vendor, efi_info.vendor, 9); 1932*7c478bd9Sstevel@tonic-gate (void) strlcpy(search_dtype->product, efi_info.product, 17); 1933*7c478bd9Sstevel@tonic-gate (void) strlcpy(search_dtype->revision, efi_info.revision, 5); 1934*7c478bd9Sstevel@tonic-gate search_dtype->capacity = efi_info.capacity; 1935*7c478bd9Sstevel@tonic-gate search_disk->disk_type = search_dtype; 1936*7c478bd9Sstevel@tonic-gate 1937*7c478bd9Sstevel@tonic-gate search_parts = (struct partition_info *) 1938*7c478bd9Sstevel@tonic-gate zalloc(sizeof (struct partition_info)); 1939*7c478bd9Sstevel@tonic-gate search_dtype->dtype_plist = search_parts; 1940*7c478bd9Sstevel@tonic-gate 1941*7c478bd9Sstevel@tonic-gate search_parts->pinfo_name = alloc_string("original"); 1942*7c478bd9Sstevel@tonic-gate search_parts->pinfo_next = NULL; 1943*7c478bd9Sstevel@tonic-gate search_parts->etoc = efi_info.e_parts; 1944*7c478bd9Sstevel@tonic-gate search_disk->disk_parts = search_parts; 1945*7c478bd9Sstevel@tonic-gate 1946*7c478bd9Sstevel@tonic-gate /* 1947*7c478bd9Sstevel@tonic-gate * Copy the volume name, if present 1948*7c478bd9Sstevel@tonic-gate */ 1949*7c478bd9Sstevel@tonic-gate for (i = 0; i < search_parts->etoc->efi_nparts; i++) { 1950*7c478bd9Sstevel@tonic-gate if (search_parts->etoc->efi_parts[i].p_tag == 1951*7c478bd9Sstevel@tonic-gate V_RESERVED) { 1952*7c478bd9Sstevel@tonic-gate if (search_parts->etoc->efi_parts[i].p_name) { 1953*7c478bd9Sstevel@tonic-gate bcopy(search_parts->etoc->efi_parts[i].p_name, 1954*7c478bd9Sstevel@tonic-gate search_disk->v_volume, LEN_DKL_VVOL); 1955*7c478bd9Sstevel@tonic-gate } else { 1956*7c478bd9Sstevel@tonic-gate bzero(search_disk->v_volume, LEN_DKL_VVOL); 1957*7c478bd9Sstevel@tonic-gate } 1958*7c478bd9Sstevel@tonic-gate break; 1959*7c478bd9Sstevel@tonic-gate } 1960*7c478bd9Sstevel@tonic-gate } 1961*7c478bd9Sstevel@tonic-gate return; 1962*7c478bd9Sstevel@tonic-gate } 1963*7c478bd9Sstevel@tonic-gate 1964*7c478bd9Sstevel@tonic-gate /* 1965*7c478bd9Sstevel@tonic-gate * Attempt to match the disk type in the label with a 1966*7c478bd9Sstevel@tonic-gate * known disk type. 1967*7c478bd9Sstevel@tonic-gate */ 1968*7c478bd9Sstevel@tonic-gate for (search_dtype = search_ctlr->ctlr_ctype->ctype_dlist; 1969*7c478bd9Sstevel@tonic-gate search_dtype != NULL; 1970*7c478bd9Sstevel@tonic-gate search_dtype = search_dtype->dtype_next) 1971*7c478bd9Sstevel@tonic-gate if (dtype_match(&search_label, search_dtype)) 1972*7c478bd9Sstevel@tonic-gate break; 1973*7c478bd9Sstevel@tonic-gate /* 1974*7c478bd9Sstevel@tonic-gate * If no match was found, we need to create a disk type 1975*7c478bd9Sstevel@tonic-gate * for this disk. 1976*7c478bd9Sstevel@tonic-gate */ 1977*7c478bd9Sstevel@tonic-gate if (search_dtype == NULL) { 1978*7c478bd9Sstevel@tonic-gate /* 1979*7c478bd9Sstevel@tonic-gate * Allocate space for the disk type and add it 1980*7c478bd9Sstevel@tonic-gate * to the list of disk types for this ctlr type. 1981*7c478bd9Sstevel@tonic-gate */ 1982*7c478bd9Sstevel@tonic-gate search_dtype = (struct disk_type *) 1983*7c478bd9Sstevel@tonic-gate zalloc(sizeof (struct disk_type)); 1984*7c478bd9Sstevel@tonic-gate type = search_ctlr->ctlr_ctype->ctype_dlist; 1985*7c478bd9Sstevel@tonic-gate if (type == NULL) 1986*7c478bd9Sstevel@tonic-gate search_ctlr->ctlr_ctype->ctype_dlist = 1987*7c478bd9Sstevel@tonic-gate search_dtype; 1988*7c478bd9Sstevel@tonic-gate else { 1989*7c478bd9Sstevel@tonic-gate while (type->dtype_next != NULL) 1990*7c478bd9Sstevel@tonic-gate type = type->dtype_next; 1991*7c478bd9Sstevel@tonic-gate type->dtype_next = search_dtype; 1992*7c478bd9Sstevel@tonic-gate } 1993*7c478bd9Sstevel@tonic-gate /* 1994*7c478bd9Sstevel@tonic-gate * Fill in the drive info from the disk label. 1995*7c478bd9Sstevel@tonic-gate */ 1996*7c478bd9Sstevel@tonic-gate search_dtype->dtype_next = NULL; 1997*7c478bd9Sstevel@tonic-gate search_dtype->dtype_asciilabel = (char *) 1998*7c478bd9Sstevel@tonic-gate zalloc(strlen(search_label.dkl_asciilabel) + 1); 1999*7c478bd9Sstevel@tonic-gate (void) strcpy(search_dtype->dtype_asciilabel, 2000*7c478bd9Sstevel@tonic-gate search_label.dkl_asciilabel); 2001*7c478bd9Sstevel@tonic-gate search_dtype->dtype_pcyl = search_label.dkl_pcyl; 2002*7c478bd9Sstevel@tonic-gate search_dtype->dtype_ncyl = search_label.dkl_ncyl; 2003*7c478bd9Sstevel@tonic-gate search_dtype->dtype_acyl = search_label.dkl_acyl; 2004*7c478bd9Sstevel@tonic-gate search_dtype->dtype_nhead = search_label.dkl_nhead; 2005*7c478bd9Sstevel@tonic-gate search_dtype->dtype_nsect = search_label.dkl_nsect; 2006*7c478bd9Sstevel@tonic-gate search_dtype->dtype_rpm = search_label.dkl_rpm; 2007*7c478bd9Sstevel@tonic-gate /* 2008*7c478bd9Sstevel@tonic-gate * Mark the disk as needing specification of 2009*7c478bd9Sstevel@tonic-gate * ctlr specific attributes. This is necessary 2010*7c478bd9Sstevel@tonic-gate * because the label doesn't contain these attributes, 2011*7c478bd9Sstevel@tonic-gate * and they aren't known at this point. They will 2012*7c478bd9Sstevel@tonic-gate * be asked for if this disk is ever selected by 2013*7c478bd9Sstevel@tonic-gate * the user. 2014*7c478bd9Sstevel@tonic-gate * Note: for SCSI, we believe the label. 2015*7c478bd9Sstevel@tonic-gate */ 2016*7c478bd9Sstevel@tonic-gate if ((search_ctlr->ctlr_ctype->ctype_ctype != DKC_SCSI_CCS) && 2017*7c478bd9Sstevel@tonic-gate (search_ctlr->ctlr_ctype->ctype_ctype != DKC_DIRECT) && 2018*7c478bd9Sstevel@tonic-gate (search_ctlr->ctlr_ctype->ctype_ctype != DKC_PCMCIA_ATA)) { 2019*7c478bd9Sstevel@tonic-gate search_dtype->dtype_flags |= DT_NEED_SPEFS; 2020*7c478bd9Sstevel@tonic-gate } 2021*7c478bd9Sstevel@tonic-gate } 2022*7c478bd9Sstevel@tonic-gate /* 2023*7c478bd9Sstevel@tonic-gate * By this time we have a known disk type. Link the disk 2024*7c478bd9Sstevel@tonic-gate * to the disk type. 2025*7c478bd9Sstevel@tonic-gate */ 2026*7c478bd9Sstevel@tonic-gate search_disk->disk_type = search_dtype; 2027*7c478bd9Sstevel@tonic-gate /* 2028*7c478bd9Sstevel@tonic-gate * Attempt to match the partition map in the label with 2029*7c478bd9Sstevel@tonic-gate * a known partition map for this disk type. 2030*7c478bd9Sstevel@tonic-gate */ 2031*7c478bd9Sstevel@tonic-gate for (search_parts = search_dtype->dtype_plist; 2032*7c478bd9Sstevel@tonic-gate search_parts != NULL; 2033*7c478bd9Sstevel@tonic-gate search_parts = search_parts->pinfo_next) 2034*7c478bd9Sstevel@tonic-gate if (parts_match(&search_label, search_parts)) { 2035*7c478bd9Sstevel@tonic-gate break; 2036*7c478bd9Sstevel@tonic-gate } 2037*7c478bd9Sstevel@tonic-gate /* 2038*7c478bd9Sstevel@tonic-gate * If no match was made, we need to create a partition 2039*7c478bd9Sstevel@tonic-gate * map for this disk. 2040*7c478bd9Sstevel@tonic-gate */ 2041*7c478bd9Sstevel@tonic-gate if (search_parts == NULL) { 2042*7c478bd9Sstevel@tonic-gate /* 2043*7c478bd9Sstevel@tonic-gate * Allocate space for the partition map and add 2044*7c478bd9Sstevel@tonic-gate * it to the list of maps for this disk type. 2045*7c478bd9Sstevel@tonic-gate */ 2046*7c478bd9Sstevel@tonic-gate search_parts = (struct partition_info *) 2047*7c478bd9Sstevel@tonic-gate zalloc(sizeof (struct partition_info)); 2048*7c478bd9Sstevel@tonic-gate parts = search_dtype->dtype_plist; 2049*7c478bd9Sstevel@tonic-gate if (parts == NULL) 2050*7c478bd9Sstevel@tonic-gate search_dtype->dtype_plist = search_parts; 2051*7c478bd9Sstevel@tonic-gate else { 2052*7c478bd9Sstevel@tonic-gate while (parts->pinfo_next != NULL) 2053*7c478bd9Sstevel@tonic-gate parts = parts->pinfo_next; 2054*7c478bd9Sstevel@tonic-gate parts->pinfo_next = search_parts; 2055*7c478bd9Sstevel@tonic-gate } 2056*7c478bd9Sstevel@tonic-gate search_parts->pinfo_next = NULL; 2057*7c478bd9Sstevel@tonic-gate /* 2058*7c478bd9Sstevel@tonic-gate * Fill in the name of the map with a name derived 2059*7c478bd9Sstevel@tonic-gate * from the name of this disk. This is necessary 2060*7c478bd9Sstevel@tonic-gate * because the label contains no name for the 2061*7c478bd9Sstevel@tonic-gate * partition map. 2062*7c478bd9Sstevel@tonic-gate */ 2063*7c478bd9Sstevel@tonic-gate search_parts->pinfo_name = alloc_string("original"); 2064*7c478bd9Sstevel@tonic-gate /* 2065*7c478bd9Sstevel@tonic-gate * Fill in the partition info from the disk label. 2066*7c478bd9Sstevel@tonic-gate */ 2067*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 2068*7c478bd9Sstevel@tonic-gate 2069*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 2070*7c478bd9Sstevel@tonic-gate search_parts->pinfo_map[i] = 2071*7c478bd9Sstevel@tonic-gate search_label.dkl_map[i]; 2072*7c478bd9Sstevel@tonic-gate 2073*7c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 2074*7c478bd9Sstevel@tonic-gate search_parts->pinfo_map[i].dkl_cylno = 2075*7c478bd9Sstevel@tonic-gate search_label.dkl_vtoc.v_part[i].p_start / 2076*7c478bd9Sstevel@tonic-gate ((int)(search_label.dkl_nhead * 2077*7c478bd9Sstevel@tonic-gate search_label.dkl_nsect)); 2078*7c478bd9Sstevel@tonic-gate search_parts->pinfo_map[i].dkl_nblk = 2079*7c478bd9Sstevel@tonic-gate search_label.dkl_vtoc.v_part[i].p_size; 2080*7c478bd9Sstevel@tonic-gate 2081*7c478bd9Sstevel@tonic-gate #else 2082*7c478bd9Sstevel@tonic-gate #error No VTOC format defined. 2083*7c478bd9Sstevel@tonic-gate #endif 2084*7c478bd9Sstevel@tonic-gate } 2085*7c478bd9Sstevel@tonic-gate } 2086*7c478bd9Sstevel@tonic-gate /* 2087*7c478bd9Sstevel@tonic-gate * If the vtoc looks valid, copy the volume name and vtoc 2088*7c478bd9Sstevel@tonic-gate * info from the label. Otherwise, install a default vtoc. 2089*7c478bd9Sstevel@tonic-gate * This permits vtoc info to automatically appear in the sun 2090*7c478bd9Sstevel@tonic-gate * label, without requiring an upgrade procedure. 2091*7c478bd9Sstevel@tonic-gate */ 2092*7c478bd9Sstevel@tonic-gate if (search_label.dkl_vtoc.v_version == V_VERSION) { 2093*7c478bd9Sstevel@tonic-gate bcopy(search_label.dkl_vtoc.v_volume, 2094*7c478bd9Sstevel@tonic-gate search_disk->v_volume, LEN_DKL_VVOL); 2095*7c478bd9Sstevel@tonic-gate search_parts->vtoc = search_label.dkl_vtoc; 2096*7c478bd9Sstevel@tonic-gate } else { 2097*7c478bd9Sstevel@tonic-gate bzero(search_disk->v_volume, LEN_DKL_VVOL); 2098*7c478bd9Sstevel@tonic-gate set_vtoc_defaults(search_parts); 2099*7c478bd9Sstevel@tonic-gate } 2100*7c478bd9Sstevel@tonic-gate /* 2101*7c478bd9Sstevel@tonic-gate * By this time we have a known partitition map. Link the 2102*7c478bd9Sstevel@tonic-gate * disk to the partition map. 2103*7c478bd9Sstevel@tonic-gate */ 2104*7c478bd9Sstevel@tonic-gate search_disk->disk_parts = search_parts; 2105*7c478bd9Sstevel@tonic-gate } 2106*7c478bd9Sstevel@tonic-gate 2107*7c478bd9Sstevel@tonic-gate 2108*7c478bd9Sstevel@tonic-gate /* 2109*7c478bd9Sstevel@tonic-gate * Search the disk list for a disk with the identical configuration. 2110*7c478bd9Sstevel@tonic-gate * Return true if one is found. 2111*7c478bd9Sstevel@tonic-gate */ 2112*7c478bd9Sstevel@tonic-gate static int 2113*7c478bd9Sstevel@tonic-gate disk_is_known(struct dk_cinfo *dkinfo) 2114*7c478bd9Sstevel@tonic-gate { 2115*7c478bd9Sstevel@tonic-gate struct disk_info *dp; 2116*7c478bd9Sstevel@tonic-gate 2117*7c478bd9Sstevel@tonic-gate dp = disk_list; 2118*7c478bd9Sstevel@tonic-gate while (dp != NULL) { 2119*7c478bd9Sstevel@tonic-gate if (dp->disk_dkinfo.dki_ctype == dkinfo->dki_ctype && 2120*7c478bd9Sstevel@tonic-gate dp->disk_dkinfo.dki_cnum == dkinfo->dki_cnum && 2121*7c478bd9Sstevel@tonic-gate dp->disk_dkinfo.dki_unit == dkinfo->dki_unit && 2122*7c478bd9Sstevel@tonic-gate strcmp(dp->disk_dkinfo.dki_dname, 2123*7c478bd9Sstevel@tonic-gate dkinfo->dki_dname) == 0) { 2124*7c478bd9Sstevel@tonic-gate return (1); 2125*7c478bd9Sstevel@tonic-gate } 2126*7c478bd9Sstevel@tonic-gate dp = dp->disk_next; 2127*7c478bd9Sstevel@tonic-gate } 2128*7c478bd9Sstevel@tonic-gate return (0); 2129*7c478bd9Sstevel@tonic-gate } 2130*7c478bd9Sstevel@tonic-gate 2131*7c478bd9Sstevel@tonic-gate 2132*7c478bd9Sstevel@tonic-gate /* 2133*7c478bd9Sstevel@tonic-gate * This routine checks to see if a given disk type matches the type 2134*7c478bd9Sstevel@tonic-gate * in the disk label. 2135*7c478bd9Sstevel@tonic-gate */ 2136*7c478bd9Sstevel@tonic-gate int 2137*7c478bd9Sstevel@tonic-gate dtype_match(label, dtype) 2138*7c478bd9Sstevel@tonic-gate register struct dk_label *label; 2139*7c478bd9Sstevel@tonic-gate register struct disk_type *dtype; 2140*7c478bd9Sstevel@tonic-gate { 2141*7c478bd9Sstevel@tonic-gate 2142*7c478bd9Sstevel@tonic-gate if (dtype->dtype_asciilabel == NULL) { 2143*7c478bd9Sstevel@tonic-gate return (0); 2144*7c478bd9Sstevel@tonic-gate } 2145*7c478bd9Sstevel@tonic-gate 2146*7c478bd9Sstevel@tonic-gate /* 2147*7c478bd9Sstevel@tonic-gate * If the any of the physical characteristics are different, or 2148*7c478bd9Sstevel@tonic-gate * the name is different, it doesn't match. 2149*7c478bd9Sstevel@tonic-gate */ 2150*7c478bd9Sstevel@tonic-gate if ((strcmp(label->dkl_asciilabel, dtype->dtype_asciilabel) != 0) || 2151*7c478bd9Sstevel@tonic-gate (label->dkl_ncyl != dtype->dtype_ncyl) || 2152*7c478bd9Sstevel@tonic-gate (label->dkl_acyl != dtype->dtype_acyl) || 2153*7c478bd9Sstevel@tonic-gate (label->dkl_nhead != dtype->dtype_nhead) || 2154*7c478bd9Sstevel@tonic-gate (label->dkl_nsect != dtype->dtype_nsect)) { 2155*7c478bd9Sstevel@tonic-gate return (0); 2156*7c478bd9Sstevel@tonic-gate } 2157*7c478bd9Sstevel@tonic-gate /* 2158*7c478bd9Sstevel@tonic-gate * If those are all identical, assume it's a match. 2159*7c478bd9Sstevel@tonic-gate */ 2160*7c478bd9Sstevel@tonic-gate return (1); 2161*7c478bd9Sstevel@tonic-gate } 2162*7c478bd9Sstevel@tonic-gate 2163*7c478bd9Sstevel@tonic-gate /* 2164*7c478bd9Sstevel@tonic-gate * This routine checks to see if a given partition map matches the map 2165*7c478bd9Sstevel@tonic-gate * in the disk label. 2166*7c478bd9Sstevel@tonic-gate */ 2167*7c478bd9Sstevel@tonic-gate int 2168*7c478bd9Sstevel@tonic-gate parts_match(label, pinfo) 2169*7c478bd9Sstevel@tonic-gate register struct dk_label *label; 2170*7c478bd9Sstevel@tonic-gate register struct partition_info *pinfo; 2171*7c478bd9Sstevel@tonic-gate { 2172*7c478bd9Sstevel@tonic-gate int i; 2173*7c478bd9Sstevel@tonic-gate 2174*7c478bd9Sstevel@tonic-gate /* 2175*7c478bd9Sstevel@tonic-gate * If any of the partition entries is different, it doesn't match. 2176*7c478bd9Sstevel@tonic-gate */ 2177*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) 2178*7c478bd9Sstevel@tonic-gate 2179*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 2180*7c478bd9Sstevel@tonic-gate if ((label->dkl_map[i].dkl_cylno != 2181*7c478bd9Sstevel@tonic-gate pinfo->pinfo_map[i].dkl_cylno) || 2182*7c478bd9Sstevel@tonic-gate (label->dkl_map[i].dkl_nblk != 2183*7c478bd9Sstevel@tonic-gate pinfo->pinfo_map[i].dkl_nblk)) 2184*7c478bd9Sstevel@tonic-gate 2185*7c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 2186*7c478bd9Sstevel@tonic-gate if ((pinfo->pinfo_map[i].dkl_cylno != 2187*7c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_start / 2188*7c478bd9Sstevel@tonic-gate (label->dkl_nhead * label->dkl_nsect)) || 2189*7c478bd9Sstevel@tonic-gate (pinfo->pinfo_map[i].dkl_nblk != 2190*7c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_size)) 2191*7c478bd9Sstevel@tonic-gate #else 2192*7c478bd9Sstevel@tonic-gate #error No VTOC format defined. 2193*7c478bd9Sstevel@tonic-gate #endif 2194*7c478bd9Sstevel@tonic-gate return (0); 2195*7c478bd9Sstevel@tonic-gate /* 2196*7c478bd9Sstevel@tonic-gate * Compare the vtoc information for a match 2197*7c478bd9Sstevel@tonic-gate * Do not require the volume name to be equal, for a match! 2198*7c478bd9Sstevel@tonic-gate */ 2199*7c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_version != pinfo->vtoc.v_version) 2200*7c478bd9Sstevel@tonic-gate return (0); 2201*7c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_nparts != pinfo->vtoc.v_nparts) 2202*7c478bd9Sstevel@tonic-gate return (0); 2203*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 2204*7c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_part[i].p_tag != 2205*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[i].p_tag) 2206*7c478bd9Sstevel@tonic-gate return (0); 2207*7c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_part[i].p_flag != 2208*7c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[i].p_flag) 2209*7c478bd9Sstevel@tonic-gate return (0); 2210*7c478bd9Sstevel@tonic-gate } 2211*7c478bd9Sstevel@tonic-gate /* 2212*7c478bd9Sstevel@tonic-gate * If they are all identical, it's a match. 2213*7c478bd9Sstevel@tonic-gate */ 2214*7c478bd9Sstevel@tonic-gate return (1); 2215*7c478bd9Sstevel@tonic-gate } 2216*7c478bd9Sstevel@tonic-gate 2217*7c478bd9Sstevel@tonic-gate /* 2218*7c478bd9Sstevel@tonic-gate * This routine checks to see if the given disk name refers to the disk 2219*7c478bd9Sstevel@tonic-gate * in the given disk structure. 2220*7c478bd9Sstevel@tonic-gate */ 2221*7c478bd9Sstevel@tonic-gate int 2222*7c478bd9Sstevel@tonic-gate diskname_match(char *name, struct disk_info *disk) 2223*7c478bd9Sstevel@tonic-gate { 2224*7c478bd9Sstevel@tonic-gate struct dk_cinfo dkinfo; 2225*7c478bd9Sstevel@tonic-gate char s[MAXPATHLEN]; 2226*7c478bd9Sstevel@tonic-gate int fd; 2227*7c478bd9Sstevel@tonic-gate 2228*7c478bd9Sstevel@tonic-gate /* 2229*7c478bd9Sstevel@tonic-gate * Match the name of the disk in the disk_info structure 2230*7c478bd9Sstevel@tonic-gate */ 2231*7c478bd9Sstevel@tonic-gate if (strcmp(name, disk->disk_name) == 0) { 2232*7c478bd9Sstevel@tonic-gate return (1); 2233*7c478bd9Sstevel@tonic-gate } 2234*7c478bd9Sstevel@tonic-gate 2235*7c478bd9Sstevel@tonic-gate /* 2236*7c478bd9Sstevel@tonic-gate * Check to see if it's a 4.x file name in the /dev 2237*7c478bd9Sstevel@tonic-gate * directory on 5.0. Here, we only accept the 2238*7c478bd9Sstevel@tonic-gate * canonicalized form: sd0. 2239*7c478bd9Sstevel@tonic-gate */ 2240*7c478bd9Sstevel@tonic-gate if (canonical4x_name(name) == 0) { 2241*7c478bd9Sstevel@tonic-gate return (0); 2242*7c478bd9Sstevel@tonic-gate } 2243*7c478bd9Sstevel@tonic-gate 2244*7c478bd9Sstevel@tonic-gate (void) strcpy(s, "/dev/r"); 2245*7c478bd9Sstevel@tonic-gate (void) strcat(s, name); 2246*7c478bd9Sstevel@tonic-gate (void) strcat(s, "c"); 2247*7c478bd9Sstevel@tonic-gate 2248*7c478bd9Sstevel@tonic-gate if ((fd = open_disk(s, O_RDWR | O_NDELAY)) < 0) { 2249*7c478bd9Sstevel@tonic-gate return (0); 2250*7c478bd9Sstevel@tonic-gate } 2251*7c478bd9Sstevel@tonic-gate 2252*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) { 2253*7c478bd9Sstevel@tonic-gate (void) close(fd); 2254*7c478bd9Sstevel@tonic-gate return (0); 2255*7c478bd9Sstevel@tonic-gate } 2256*7c478bd9Sstevel@tonic-gate (void) close(fd); 2257*7c478bd9Sstevel@tonic-gate 2258*7c478bd9Sstevel@tonic-gate if (disk->disk_dkinfo.dki_ctype == dkinfo.dki_ctype && 2259*7c478bd9Sstevel@tonic-gate disk->disk_dkinfo.dki_cnum == dkinfo.dki_cnum && 2260*7c478bd9Sstevel@tonic-gate disk->disk_dkinfo.dki_unit == dkinfo.dki_unit && 2261*7c478bd9Sstevel@tonic-gate strcmp(disk->disk_dkinfo.dki_dname, 2262*7c478bd9Sstevel@tonic-gate dkinfo.dki_dname) == 0) { 2263*7c478bd9Sstevel@tonic-gate return (1); 2264*7c478bd9Sstevel@tonic-gate } 2265*7c478bd9Sstevel@tonic-gate return (0); 2266*7c478bd9Sstevel@tonic-gate } 2267*7c478bd9Sstevel@tonic-gate 2268*7c478bd9Sstevel@tonic-gate 2269*7c478bd9Sstevel@tonic-gate static void 2270*7c478bd9Sstevel@tonic-gate datafile_error(char *errmsg, char *token) 2271*7c478bd9Sstevel@tonic-gate { 2272*7c478bd9Sstevel@tonic-gate int token_type; 2273*7c478bd9Sstevel@tonic-gate TOKEN token_buf; 2274*7c478bd9Sstevel@tonic-gate 2275*7c478bd9Sstevel@tonic-gate /* 2276*7c478bd9Sstevel@tonic-gate * Allow us to get by controllers that the other platforms don't 2277*7c478bd9Sstevel@tonic-gate * know about. 2278*7c478bd9Sstevel@tonic-gate */ 2279*7c478bd9Sstevel@tonic-gate if (errmsg != NULL) { 2280*7c478bd9Sstevel@tonic-gate err_print(errmsg, token); 2281*7c478bd9Sstevel@tonic-gate err_print(" - %s (%d)\n", file_name, data_lineno); 2282*7c478bd9Sstevel@tonic-gate } 2283*7c478bd9Sstevel@tonic-gate 2284*7c478bd9Sstevel@tonic-gate /* 2285*7c478bd9Sstevel@tonic-gate * Re-sync the parsing at the beginning of the next line 2286*7c478bd9Sstevel@tonic-gate * unless of course we're already there. 2287*7c478bd9Sstevel@tonic-gate */ 2288*7c478bd9Sstevel@tonic-gate if (last_token_type != SUP_EOF && last_token_type != SUP_EOL) { 2289*7c478bd9Sstevel@tonic-gate do { 2290*7c478bd9Sstevel@tonic-gate token_type = sup_gettoken(token_buf); 2291*7c478bd9Sstevel@tonic-gate } while (token_type != SUP_EOF && token_type != SUP_EOL); 2292*7c478bd9Sstevel@tonic-gate 2293*7c478bd9Sstevel@tonic-gate if (token_type == SUP_EOF) { 2294*7c478bd9Sstevel@tonic-gate sup_pushtoken(token_buf, token_type); 2295*7c478bd9Sstevel@tonic-gate } 2296*7c478bd9Sstevel@tonic-gate } 2297*7c478bd9Sstevel@tonic-gate } 2298*7c478bd9Sstevel@tonic-gate 2299*7c478bd9Sstevel@tonic-gate 2300*7c478bd9Sstevel@tonic-gate /* 2301*7c478bd9Sstevel@tonic-gate * Search through all defined disk types for duplicate entries 2302*7c478bd9Sstevel@tonic-gate * that are inconsistent with each other. Disks with different 2303*7c478bd9Sstevel@tonic-gate * characteristics should be named differently. 2304*7c478bd9Sstevel@tonic-gate * Note that this function only checks for duplicate disks 2305*7c478bd9Sstevel@tonic-gate * for the same controller. It's possible to have two disks with 2306*7c478bd9Sstevel@tonic-gate * the same name, but defined for different controllers. 2307*7c478bd9Sstevel@tonic-gate * That may or may not be a problem... 2308*7c478bd9Sstevel@tonic-gate */ 2309*7c478bd9Sstevel@tonic-gate static void 2310*7c478bd9Sstevel@tonic-gate search_duplicate_dtypes() 2311*7c478bd9Sstevel@tonic-gate { 2312*7c478bd9Sstevel@tonic-gate struct disk_type *dp1; 2313*7c478bd9Sstevel@tonic-gate struct disk_type *dp2; 2314*7c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 2315*7c478bd9Sstevel@tonic-gate 2316*7c478bd9Sstevel@tonic-gate mlp = controlp; 2317*7c478bd9Sstevel@tonic-gate 2318*7c478bd9Sstevel@tonic-gate while (mlp != NULL) { 2319*7c478bd9Sstevel@tonic-gate dp1 = mlp->ctlr_type->ctype_dlist; 2320*7c478bd9Sstevel@tonic-gate while (dp1 != NULL) { 2321*7c478bd9Sstevel@tonic-gate dp2 = dp1->dtype_next; 2322*7c478bd9Sstevel@tonic-gate while (dp2 != NULL) { 2323*7c478bd9Sstevel@tonic-gate check_dtypes_for_inconsistency(dp1, dp2); 2324*7c478bd9Sstevel@tonic-gate dp2 = dp2->dtype_next; 2325*7c478bd9Sstevel@tonic-gate } 2326*7c478bd9Sstevel@tonic-gate dp1 = dp1->dtype_next; 2327*7c478bd9Sstevel@tonic-gate } 2328*7c478bd9Sstevel@tonic-gate mlp = mlp->next; 2329*7c478bd9Sstevel@tonic-gate } 2330*7c478bd9Sstevel@tonic-gate } 2331*7c478bd9Sstevel@tonic-gate 2332*7c478bd9Sstevel@tonic-gate 2333*7c478bd9Sstevel@tonic-gate /* 2334*7c478bd9Sstevel@tonic-gate * Search through all defined partition types for duplicate entries 2335*7c478bd9Sstevel@tonic-gate * that are inconsistent with each other. Partitions with different 2336*7c478bd9Sstevel@tonic-gate * characteristics should be named differently. 2337*7c478bd9Sstevel@tonic-gate * Note that this function only checks for duplicate partitions 2338*7c478bd9Sstevel@tonic-gate * for the same disk. It's possible to have two partitions with 2339*7c478bd9Sstevel@tonic-gate * the same name, but defined for different disks. 2340*7c478bd9Sstevel@tonic-gate * That may or may not be a problem... 2341*7c478bd9Sstevel@tonic-gate */ 2342*7c478bd9Sstevel@tonic-gate static void 2343*7c478bd9Sstevel@tonic-gate search_duplicate_pinfo() 2344*7c478bd9Sstevel@tonic-gate { 2345*7c478bd9Sstevel@tonic-gate struct disk_type *dp; 2346*7c478bd9Sstevel@tonic-gate struct partition_info *pp1; 2347*7c478bd9Sstevel@tonic-gate struct partition_info *pp2; 2348*7c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 2349*7c478bd9Sstevel@tonic-gate 2350*7c478bd9Sstevel@tonic-gate mlp = controlp; 2351*7c478bd9Sstevel@tonic-gate 2352*7c478bd9Sstevel@tonic-gate while (mlp != NULL) { 2353*7c478bd9Sstevel@tonic-gate dp = mlp->ctlr_type->ctype_dlist; 2354*7c478bd9Sstevel@tonic-gate while (dp != NULL) { 2355*7c478bd9Sstevel@tonic-gate pp1 = dp->dtype_plist; 2356*7c478bd9Sstevel@tonic-gate while (pp1 != NULL) { 2357*7c478bd9Sstevel@tonic-gate pp2 = pp1->pinfo_next; 2358*7c478bd9Sstevel@tonic-gate while (pp2 != NULL) { 2359*7c478bd9Sstevel@tonic-gate check_pinfo_for_inconsistency(pp1, pp2); 2360*7c478bd9Sstevel@tonic-gate pp2 = pp2->pinfo_next; 2361*7c478bd9Sstevel@tonic-gate } 2362*7c478bd9Sstevel@tonic-gate pp1 = pp1->pinfo_next; 2363*7c478bd9Sstevel@tonic-gate } 2364*7c478bd9Sstevel@tonic-gate dp = dp->dtype_next; 2365*7c478bd9Sstevel@tonic-gate } 2366*7c478bd9Sstevel@tonic-gate mlp = mlp->next; 2367*7c478bd9Sstevel@tonic-gate } 2368*7c478bd9Sstevel@tonic-gate } 2369*7c478bd9Sstevel@tonic-gate 2370*7c478bd9Sstevel@tonic-gate 2371*7c478bd9Sstevel@tonic-gate /* 2372*7c478bd9Sstevel@tonic-gate * Determine if two particular disk definitions are inconsistent. 2373*7c478bd9Sstevel@tonic-gate * Ie: same name, but different characteristics. 2374*7c478bd9Sstevel@tonic-gate * If so, print an error message and abort. 2375*7c478bd9Sstevel@tonic-gate */ 2376*7c478bd9Sstevel@tonic-gate static void 2377*7c478bd9Sstevel@tonic-gate check_dtypes_for_inconsistency(dp1, dp2) 2378*7c478bd9Sstevel@tonic-gate struct disk_type *dp1; 2379*7c478bd9Sstevel@tonic-gate struct disk_type *dp2; 2380*7c478bd9Sstevel@tonic-gate { 2381*7c478bd9Sstevel@tonic-gate int i; 2382*7c478bd9Sstevel@tonic-gate int result; 2383*7c478bd9Sstevel@tonic-gate struct chg_list *cp1; 2384*7c478bd9Sstevel@tonic-gate struct chg_list *cp2; 2385*7c478bd9Sstevel@tonic-gate 2386*7c478bd9Sstevel@tonic-gate 2387*7c478bd9Sstevel@tonic-gate /* 2388*7c478bd9Sstevel@tonic-gate * If the name's different, we're ok 2389*7c478bd9Sstevel@tonic-gate */ 2390*7c478bd9Sstevel@tonic-gate if (strcmp(dp1->dtype_asciilabel, dp2->dtype_asciilabel) != 0) { 2391*7c478bd9Sstevel@tonic-gate return; 2392*7c478bd9Sstevel@tonic-gate } 2393*7c478bd9Sstevel@tonic-gate 2394*7c478bd9Sstevel@tonic-gate /* 2395*7c478bd9Sstevel@tonic-gate * Compare all the disks' characteristics 2396*7c478bd9Sstevel@tonic-gate */ 2397*7c478bd9Sstevel@tonic-gate result = 0; 2398*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_flags != dp2->dtype_flags); 2399*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_options != dp2->dtype_options); 2400*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_fmt_time != dp2->dtype_fmt_time); 2401*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_bpt != dp2->dtype_bpt); 2402*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_ncyl != dp2->dtype_ncyl); 2403*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_acyl != dp2->dtype_acyl); 2404*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_pcyl != dp2->dtype_pcyl); 2405*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_nhead != dp2->dtype_nhead); 2406*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_nsect != dp2->dtype_nsect); 2407*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_rpm != dp2->dtype_rpm); 2408*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_cyl_skew != dp2->dtype_cyl_skew); 2409*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_trk_skew != dp2->dtype_trk_skew); 2410*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_trks_zone != dp2->dtype_trks_zone); 2411*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_atrks != dp2->dtype_atrks); 2412*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_asect != dp2->dtype_asect); 2413*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_cache != dp2->dtype_cache); 2414*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_threshold != dp2->dtype_threshold); 2415*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_read_retries != dp2->dtype_read_retries); 2416*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_write_retries != dp2->dtype_write_retries); 2417*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_prefetch_min != dp2->dtype_prefetch_min); 2418*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_prefetch_max != dp2->dtype_prefetch_max); 2419*7c478bd9Sstevel@tonic-gate for (i = 0; i < NSPECIFICS; i++) { 2420*7c478bd9Sstevel@tonic-gate result |= (dp1->dtype_specifics[i] != dp2->dtype_specifics[i]); 2421*7c478bd9Sstevel@tonic-gate } 2422*7c478bd9Sstevel@tonic-gate 2423*7c478bd9Sstevel@tonic-gate cp1 = dp1->dtype_chglist; 2424*7c478bd9Sstevel@tonic-gate cp2 = dp2->dtype_chglist; 2425*7c478bd9Sstevel@tonic-gate while (cp1 != NULL && cp2 != NULL) { 2426*7c478bd9Sstevel@tonic-gate if (cp1 == NULL || cp2 == NULL) { 2427*7c478bd9Sstevel@tonic-gate result = 1; 2428*7c478bd9Sstevel@tonic-gate break; 2429*7c478bd9Sstevel@tonic-gate } 2430*7c478bd9Sstevel@tonic-gate result |= (cp1->pageno != cp2->pageno); 2431*7c478bd9Sstevel@tonic-gate result |= (cp1->byteno != cp2->byteno); 2432*7c478bd9Sstevel@tonic-gate result |= (cp1->mode != cp2->mode); 2433*7c478bd9Sstevel@tonic-gate result |= (cp1->value != cp2->value); 2434*7c478bd9Sstevel@tonic-gate cp1 = cp1->next; 2435*7c478bd9Sstevel@tonic-gate cp2 = cp2->next; 2436*7c478bd9Sstevel@tonic-gate } 2437*7c478bd9Sstevel@tonic-gate 2438*7c478bd9Sstevel@tonic-gate if (result) { 2439*7c478bd9Sstevel@tonic-gate err_print("Inconsistent definitions for disk type '%s'\n", 2440*7c478bd9Sstevel@tonic-gate dp1->dtype_asciilabel); 2441*7c478bd9Sstevel@tonic-gate if (dp1->dtype_filename != NULL && 2442*7c478bd9Sstevel@tonic-gate dp2->dtype_filename != NULL) { 2443*7c478bd9Sstevel@tonic-gate err_print("%s (%d) - %s (%d)\n", 2444*7c478bd9Sstevel@tonic-gate dp1->dtype_filename, dp1->dtype_lineno, 2445*7c478bd9Sstevel@tonic-gate dp2->dtype_filename, dp2->dtype_lineno); 2446*7c478bd9Sstevel@tonic-gate } 2447*7c478bd9Sstevel@tonic-gate fullabort(); 2448*7c478bd9Sstevel@tonic-gate } 2449*7c478bd9Sstevel@tonic-gate } 2450*7c478bd9Sstevel@tonic-gate 2451*7c478bd9Sstevel@tonic-gate 2452*7c478bd9Sstevel@tonic-gate /* 2453*7c478bd9Sstevel@tonic-gate * Determine if two particular partition definitions are inconsistent. 2454*7c478bd9Sstevel@tonic-gate * Ie: same name, but different characteristics. 2455*7c478bd9Sstevel@tonic-gate * If so, print an error message and abort. 2456*7c478bd9Sstevel@tonic-gate */ 2457*7c478bd9Sstevel@tonic-gate static void 2458*7c478bd9Sstevel@tonic-gate check_pinfo_for_inconsistency(pp1, pp2) 2459*7c478bd9Sstevel@tonic-gate struct partition_info *pp1; 2460*7c478bd9Sstevel@tonic-gate struct partition_info *pp2; 2461*7c478bd9Sstevel@tonic-gate { 2462*7c478bd9Sstevel@tonic-gate int i; 2463*7c478bd9Sstevel@tonic-gate int result; 2464*7c478bd9Sstevel@tonic-gate struct dk_map32 *map1; 2465*7c478bd9Sstevel@tonic-gate struct dk_map32 *map2; 2466*7c478bd9Sstevel@tonic-gate 2467*7c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 2468*7c478bd9Sstevel@tonic-gate struct dk_map2 *vp1; 2469*7c478bd9Sstevel@tonic-gate struct dk_map2 *vp2; 2470*7c478bd9Sstevel@tonic-gate 2471*7c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 2472*7c478bd9Sstevel@tonic-gate struct dkl_partition *vp1; 2473*7c478bd9Sstevel@tonic-gate struct dkl_partition *vp2; 2474*7c478bd9Sstevel@tonic-gate #else 2475*7c478bd9Sstevel@tonic-gate #error No VTOC layout defined. 2476*7c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 2477*7c478bd9Sstevel@tonic-gate 2478*7c478bd9Sstevel@tonic-gate /* 2479*7c478bd9Sstevel@tonic-gate * If the name's different, we're ok 2480*7c478bd9Sstevel@tonic-gate */ 2481*7c478bd9Sstevel@tonic-gate if (strcmp(pp1->pinfo_name, pp2->pinfo_name) != 0) { 2482*7c478bd9Sstevel@tonic-gate return; 2483*7c478bd9Sstevel@tonic-gate } 2484*7c478bd9Sstevel@tonic-gate 2485*7c478bd9Sstevel@tonic-gate /* 2486*7c478bd9Sstevel@tonic-gate * Compare all the partitions' characteristics 2487*7c478bd9Sstevel@tonic-gate */ 2488*7c478bd9Sstevel@tonic-gate result = 0; 2489*7c478bd9Sstevel@tonic-gate map1 = pp1->pinfo_map; 2490*7c478bd9Sstevel@tonic-gate map2 = pp2->pinfo_map; 2491*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++, map1++, map2++) { 2492*7c478bd9Sstevel@tonic-gate result |= (map1->dkl_cylno != map2->dkl_cylno); 2493*7c478bd9Sstevel@tonic-gate result |= (map1->dkl_nblk != map2->dkl_nblk); 2494*7c478bd9Sstevel@tonic-gate } 2495*7c478bd9Sstevel@tonic-gate 2496*7c478bd9Sstevel@tonic-gate /* 2497*7c478bd9Sstevel@tonic-gate * Compare the significant portions of the vtoc information 2498*7c478bd9Sstevel@tonic-gate */ 2499*7c478bd9Sstevel@tonic-gate vp1 = pp1->vtoc.v_part; 2500*7c478bd9Sstevel@tonic-gate vp2 = pp2->vtoc.v_part; 2501*7c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++, vp1++, vp2++) { 2502*7c478bd9Sstevel@tonic-gate result |= (vp1->p_tag != vp2->p_tag); 2503*7c478bd9Sstevel@tonic-gate result |= (vp1->p_flag != vp2->p_flag); 2504*7c478bd9Sstevel@tonic-gate } 2505*7c478bd9Sstevel@tonic-gate 2506*7c478bd9Sstevel@tonic-gate if (result) { 2507*7c478bd9Sstevel@tonic-gate err_print("Inconsistent definitions for partition type '%s'\n", 2508*7c478bd9Sstevel@tonic-gate pp1->pinfo_name); 2509*7c478bd9Sstevel@tonic-gate if (pp1->pinfo_filename != NULL && 2510*7c478bd9Sstevel@tonic-gate pp2->pinfo_filename != NULL) { 2511*7c478bd9Sstevel@tonic-gate err_print("%s (%d) - %s (%d)\n", 2512*7c478bd9Sstevel@tonic-gate pp1->pinfo_filename, pp1->pinfo_lineno, 2513*7c478bd9Sstevel@tonic-gate pp2->pinfo_filename, pp2->pinfo_lineno); 2514*7c478bd9Sstevel@tonic-gate } 2515*7c478bd9Sstevel@tonic-gate fullabort(); 2516*7c478bd9Sstevel@tonic-gate } 2517*7c478bd9Sstevel@tonic-gate } 2518*7c478bd9Sstevel@tonic-gate 2519*7c478bd9Sstevel@tonic-gate /* 2520*7c478bd9Sstevel@tonic-gate * Convert a string of digits into a block number. 2521*7c478bd9Sstevel@tonic-gate * The digits are assumed to be a block number unless the 2522*7c478bd9Sstevel@tonic-gate * the string is terminated by 'c', in which case it is 2523*7c478bd9Sstevel@tonic-gate * assumed to be in units of cylinders. Accept a 'b' 2524*7c478bd9Sstevel@tonic-gate * to explictly specify blocks, for consistency. 2525*7c478bd9Sstevel@tonic-gate * 2526*7c478bd9Sstevel@tonic-gate * NB: uses the macro spc(), which requires that the 2527*7c478bd9Sstevel@tonic-gate * globals nhead/nsect/acyl be set up correctly. 2528*7c478bd9Sstevel@tonic-gate * 2529*7c478bd9Sstevel@tonic-gate * Returns -1 in the case of an error. 2530*7c478bd9Sstevel@tonic-gate */ 2531*7c478bd9Sstevel@tonic-gate static int 2532*7c478bd9Sstevel@tonic-gate str2blks(char *str) 2533*7c478bd9Sstevel@tonic-gate { 2534*7c478bd9Sstevel@tonic-gate int blks; 2535*7c478bd9Sstevel@tonic-gate char *p; 2536*7c478bd9Sstevel@tonic-gate 2537*7c478bd9Sstevel@tonic-gate blks = (int)strtol(str, &p, 0); 2538*7c478bd9Sstevel@tonic-gate /* 2539*7c478bd9Sstevel@tonic-gate * Check what terminated the conversion. 2540*7c478bd9Sstevel@tonic-gate */ 2541*7c478bd9Sstevel@tonic-gate if (*p != 0) { 2542*7c478bd9Sstevel@tonic-gate /* 2543*7c478bd9Sstevel@tonic-gate * Units specifier of 'c': convert cylinders to blocks 2544*7c478bd9Sstevel@tonic-gate */ 2545*7c478bd9Sstevel@tonic-gate if (*p == 'c') { 2546*7c478bd9Sstevel@tonic-gate p++; 2547*7c478bd9Sstevel@tonic-gate blks = blks * spc(); 2548*7c478bd9Sstevel@tonic-gate /* 2549*7c478bd9Sstevel@tonic-gate * Ignore a 'b' specifier. 2550*7c478bd9Sstevel@tonic-gate */ 2551*7c478bd9Sstevel@tonic-gate } else if (*p == 'b') { 2552*7c478bd9Sstevel@tonic-gate p++; 2553*7c478bd9Sstevel@tonic-gate } 2554*7c478bd9Sstevel@tonic-gate /* 2555*7c478bd9Sstevel@tonic-gate * Anthing left over is an error 2556*7c478bd9Sstevel@tonic-gate */ 2557*7c478bd9Sstevel@tonic-gate if (*p != 0) { 2558*7c478bd9Sstevel@tonic-gate blks = -1; 2559*7c478bd9Sstevel@tonic-gate } 2560*7c478bd9Sstevel@tonic-gate } 2561*7c478bd9Sstevel@tonic-gate 2562*7c478bd9Sstevel@tonic-gate return (blks); 2563*7c478bd9Sstevel@tonic-gate } 2564*7c478bd9Sstevel@tonic-gate /* 2565*7c478bd9Sstevel@tonic-gate * Convert a string of digits into a cylinder number. 2566*7c478bd9Sstevel@tonic-gate * Accept a an optional 'c' specifier, for consistency. 2567*7c478bd9Sstevel@tonic-gate * 2568*7c478bd9Sstevel@tonic-gate * Returns -1 in the case of an error. 2569*7c478bd9Sstevel@tonic-gate */ 2570*7c478bd9Sstevel@tonic-gate int 2571*7c478bd9Sstevel@tonic-gate str2cyls(char *str) 2572*7c478bd9Sstevel@tonic-gate { 2573*7c478bd9Sstevel@tonic-gate int cyls; 2574*7c478bd9Sstevel@tonic-gate char *p; 2575*7c478bd9Sstevel@tonic-gate 2576*7c478bd9Sstevel@tonic-gate cyls = (int)strtol(str, &p, 0); 2577*7c478bd9Sstevel@tonic-gate /* 2578*7c478bd9Sstevel@tonic-gate * Check what terminated the conversion. 2579*7c478bd9Sstevel@tonic-gate */ 2580*7c478bd9Sstevel@tonic-gate if (*p != 0) { 2581*7c478bd9Sstevel@tonic-gate /* 2582*7c478bd9Sstevel@tonic-gate * Units specifier of 'c': convert cylinders to blocks 2583*7c478bd9Sstevel@tonic-gate */ 2584*7c478bd9Sstevel@tonic-gate if (*p == 'c') { 2585*7c478bd9Sstevel@tonic-gate p++; 2586*7c478bd9Sstevel@tonic-gate } 2587*7c478bd9Sstevel@tonic-gate /* 2588*7c478bd9Sstevel@tonic-gate * Anthing left over is an error 2589*7c478bd9Sstevel@tonic-gate */ 2590*7c478bd9Sstevel@tonic-gate if (*p != 0) { 2591*7c478bd9Sstevel@tonic-gate cyls = -1; 2592*7c478bd9Sstevel@tonic-gate } 2593*7c478bd9Sstevel@tonic-gate } 2594*7c478bd9Sstevel@tonic-gate 2595*7c478bd9Sstevel@tonic-gate return (cyls); 2596*7c478bd9Sstevel@tonic-gate } 2597*7c478bd9Sstevel@tonic-gate 2598*7c478bd9Sstevel@tonic-gate 2599*7c478bd9Sstevel@tonic-gate /* 2600*7c478bd9Sstevel@tonic-gate * Create a new chg_list structure, and append it onto the 2601*7c478bd9Sstevel@tonic-gate * end of the current chg_list under construction. By 2602*7c478bd9Sstevel@tonic-gate * applying changes in the order in which listed in the 2603*7c478bd9Sstevel@tonic-gate * data file, the changes we make are deterministic. 2604*7c478bd9Sstevel@tonic-gate * Return a pointer to the new structure, so that the 2605*7c478bd9Sstevel@tonic-gate * caller can fill in the appropriate information. 2606*7c478bd9Sstevel@tonic-gate */ 2607*7c478bd9Sstevel@tonic-gate static struct chg_list * 2608*7c478bd9Sstevel@tonic-gate new_chg_list(struct disk_type *disk) 2609*7c478bd9Sstevel@tonic-gate { 2610*7c478bd9Sstevel@tonic-gate struct chg_list *cp; 2611*7c478bd9Sstevel@tonic-gate struct chg_list *nc; 2612*7c478bd9Sstevel@tonic-gate 2613*7c478bd9Sstevel@tonic-gate nc = zalloc(sizeof (struct chg_list)); 2614*7c478bd9Sstevel@tonic-gate 2615*7c478bd9Sstevel@tonic-gate if (disk->dtype_chglist == NULL) { 2616*7c478bd9Sstevel@tonic-gate disk->dtype_chglist = nc; 2617*7c478bd9Sstevel@tonic-gate } else { 2618*7c478bd9Sstevel@tonic-gate for (cp = disk->dtype_chglist; cp->next; cp = cp->next) 2619*7c478bd9Sstevel@tonic-gate ; 2620*7c478bd9Sstevel@tonic-gate cp->next = nc; 2621*7c478bd9Sstevel@tonic-gate } 2622*7c478bd9Sstevel@tonic-gate nc->next = NULL; 2623*7c478bd9Sstevel@tonic-gate return (nc); 2624*7c478bd9Sstevel@tonic-gate } 2625*7c478bd9Sstevel@tonic-gate 2626*7c478bd9Sstevel@tonic-gate 2627*7c478bd9Sstevel@tonic-gate /* 2628*7c478bd9Sstevel@tonic-gate * Follow symbolic links from the logical device name to 2629*7c478bd9Sstevel@tonic-gate * the /devfs physical device name. To be complete, we 2630*7c478bd9Sstevel@tonic-gate * handle the case of multiple links. This function 2631*7c478bd9Sstevel@tonic-gate * either returns NULL (no links, or some other error), 2632*7c478bd9Sstevel@tonic-gate * or the physical device name, alloc'ed on the heap. 2633*7c478bd9Sstevel@tonic-gate * 2634*7c478bd9Sstevel@tonic-gate * Note that the standard /devices prefix is stripped from 2635*7c478bd9Sstevel@tonic-gate * the final pathname, if present. The trailing options 2636*7c478bd9Sstevel@tonic-gate * are also removed (":c, raw"). 2637*7c478bd9Sstevel@tonic-gate */ 2638*7c478bd9Sstevel@tonic-gate static char * 2639*7c478bd9Sstevel@tonic-gate get_physical_name(char *path) 2640*7c478bd9Sstevel@tonic-gate { 2641*7c478bd9Sstevel@tonic-gate struct stat stbuf; 2642*7c478bd9Sstevel@tonic-gate int i; 2643*7c478bd9Sstevel@tonic-gate int level; 2644*7c478bd9Sstevel@tonic-gate char *p; 2645*7c478bd9Sstevel@tonic-gate char s[MAXPATHLEN]; 2646*7c478bd9Sstevel@tonic-gate char buf[MAXPATHLEN]; 2647*7c478bd9Sstevel@tonic-gate char dir[MAXPATHLEN]; 2648*7c478bd9Sstevel@tonic-gate char savedir[MAXPATHLEN]; 2649*7c478bd9Sstevel@tonic-gate char *result = NULL; 2650*7c478bd9Sstevel@tonic-gate 2651*7c478bd9Sstevel@tonic-gate if (getcwd(savedir, sizeof (savedir)) == NULL) { 2652*7c478bd9Sstevel@tonic-gate err_print("getcwd() failed - %s\n", strerror(errno)); 2653*7c478bd9Sstevel@tonic-gate return (NULL); 2654*7c478bd9Sstevel@tonic-gate } 2655*7c478bd9Sstevel@tonic-gate 2656*7c478bd9Sstevel@tonic-gate (void) strcpy(s, path); 2657*7c478bd9Sstevel@tonic-gate if ((p = strrchr(s, '/')) != NULL) { 2658*7c478bd9Sstevel@tonic-gate *p = 0; 2659*7c478bd9Sstevel@tonic-gate } 2660*7c478bd9Sstevel@tonic-gate if (s[0] == 0) { 2661*7c478bd9Sstevel@tonic-gate (void) strcpy(s, "/"); 2662*7c478bd9Sstevel@tonic-gate } 2663*7c478bd9Sstevel@tonic-gate if (chdir(s) == -1) { 2664*7c478bd9Sstevel@tonic-gate err_print("cannot chdir() to %s - %s\n", 2665*7c478bd9Sstevel@tonic-gate s, strerror(errno)); 2666*7c478bd9Sstevel@tonic-gate goto exit; 2667*7c478bd9Sstevel@tonic-gate } 2668*7c478bd9Sstevel@tonic-gate 2669*7c478bd9Sstevel@tonic-gate level = 0; 2670*7c478bd9Sstevel@tonic-gate (void) strcpy(s, path); 2671*7c478bd9Sstevel@tonic-gate for (;;) { 2672*7c478bd9Sstevel@tonic-gate /* 2673*7c478bd9Sstevel@tonic-gate * See if there's a real file out there. If not, 2674*7c478bd9Sstevel@tonic-gate * we have a dangling link and we ignore it. 2675*7c478bd9Sstevel@tonic-gate */ 2676*7c478bd9Sstevel@tonic-gate if (stat(s, &stbuf) == -1) { 2677*7c478bd9Sstevel@tonic-gate goto exit; 2678*7c478bd9Sstevel@tonic-gate } 2679*7c478bd9Sstevel@tonic-gate if (lstat(s, &stbuf) == -1) { 2680*7c478bd9Sstevel@tonic-gate err_print("%s: lstat() failed - %s\n", 2681*7c478bd9Sstevel@tonic-gate s, strerror(errno)); 2682*7c478bd9Sstevel@tonic-gate goto exit; 2683*7c478bd9Sstevel@tonic-gate } 2684*7c478bd9Sstevel@tonic-gate /* 2685*7c478bd9Sstevel@tonic-gate * If the file is not a link, we're done one 2686*7c478bd9Sstevel@tonic-gate * way or the other. If there were links, 2687*7c478bd9Sstevel@tonic-gate * return the full pathname of the resulting 2688*7c478bd9Sstevel@tonic-gate * file. 2689*7c478bd9Sstevel@tonic-gate */ 2690*7c478bd9Sstevel@tonic-gate if (!S_ISLNK(stbuf.st_mode)) { 2691*7c478bd9Sstevel@tonic-gate if (level > 0) { 2692*7c478bd9Sstevel@tonic-gate /* 2693*7c478bd9Sstevel@tonic-gate * Strip trailing options from the 2694*7c478bd9Sstevel@tonic-gate * physical device name 2695*7c478bd9Sstevel@tonic-gate */ 2696*7c478bd9Sstevel@tonic-gate if ((p = strrchr(s, ':')) != NULL) { 2697*7c478bd9Sstevel@tonic-gate *p = 0; 2698*7c478bd9Sstevel@tonic-gate } 2699*7c478bd9Sstevel@tonic-gate /* 2700*7c478bd9Sstevel@tonic-gate * Get the current directory, and 2701*7c478bd9Sstevel@tonic-gate * glue the pieces together. 2702*7c478bd9Sstevel@tonic-gate */ 2703*7c478bd9Sstevel@tonic-gate if (getcwd(dir, sizeof (dir)) == NULL) { 2704*7c478bd9Sstevel@tonic-gate err_print("getcwd() failed - %s\n", 2705*7c478bd9Sstevel@tonic-gate strerror(errno)); 2706*7c478bd9Sstevel@tonic-gate goto exit; 2707*7c478bd9Sstevel@tonic-gate } 2708*7c478bd9Sstevel@tonic-gate (void) strcat(dir, "/"); 2709*7c478bd9Sstevel@tonic-gate (void) strcat(dir, s); 2710*7c478bd9Sstevel@tonic-gate /* 2711*7c478bd9Sstevel@tonic-gate * If we have the standard fixed 2712*7c478bd9Sstevel@tonic-gate * /devices prefix, remove it. 2713*7c478bd9Sstevel@tonic-gate */ 2714*7c478bd9Sstevel@tonic-gate p = (strstr(dir, DEVFS_PREFIX) == dir) ? 2715*7c478bd9Sstevel@tonic-gate dir+strlen(DEVFS_PREFIX) : dir; 2716*7c478bd9Sstevel@tonic-gate result = alloc_string(p); 2717*7c478bd9Sstevel@tonic-gate } 2718*7c478bd9Sstevel@tonic-gate goto exit; 2719*7c478bd9Sstevel@tonic-gate } 2720*7c478bd9Sstevel@tonic-gate i = readlink(s, buf, sizeof (buf)); 2721*7c478bd9Sstevel@tonic-gate if (i == -1) { 2722*7c478bd9Sstevel@tonic-gate err_print("%s: readlink() failed - %s\n", 2723*7c478bd9Sstevel@tonic-gate s, strerror(errno)); 2724*7c478bd9Sstevel@tonic-gate goto exit; 2725*7c478bd9Sstevel@tonic-gate } 2726*7c478bd9Sstevel@tonic-gate level++; 2727*7c478bd9Sstevel@tonic-gate buf[i] = 0; 2728*7c478bd9Sstevel@tonic-gate 2729*7c478bd9Sstevel@tonic-gate /* 2730*7c478bd9Sstevel@tonic-gate * Break up the pathname into the directory 2731*7c478bd9Sstevel@tonic-gate * reference, if applicable and simple filename. 2732*7c478bd9Sstevel@tonic-gate * chdir()'ing to the directory allows us to 2733*7c478bd9Sstevel@tonic-gate * handle links with relative pathnames correctly. 2734*7c478bd9Sstevel@tonic-gate */ 2735*7c478bd9Sstevel@tonic-gate (void) strcpy(dir, buf); 2736*7c478bd9Sstevel@tonic-gate if ((p = strrchr(dir, '/')) != NULL) { 2737*7c478bd9Sstevel@tonic-gate *p = 0; 2738*7c478bd9Sstevel@tonic-gate if (chdir(dir) == -1) { 2739*7c478bd9Sstevel@tonic-gate err_print("cannot chdir() to %s - %s\n", 2740*7c478bd9Sstevel@tonic-gate dir, strerror(errno)); 2741*7c478bd9Sstevel@tonic-gate goto exit; 2742*7c478bd9Sstevel@tonic-gate } 2743*7c478bd9Sstevel@tonic-gate (void) strcpy(s, p+1); 2744*7c478bd9Sstevel@tonic-gate } else { 2745*7c478bd9Sstevel@tonic-gate (void) strcpy(s, buf); 2746*7c478bd9Sstevel@tonic-gate } 2747*7c478bd9Sstevel@tonic-gate } 2748*7c478bd9Sstevel@tonic-gate 2749*7c478bd9Sstevel@tonic-gate exit: 2750*7c478bd9Sstevel@tonic-gate if (chdir(savedir) == -1) { 2751*7c478bd9Sstevel@tonic-gate err_print("cannot chdir() to %s - %s\n", 2752*7c478bd9Sstevel@tonic-gate savedir, strerror(errno)); 2753*7c478bd9Sstevel@tonic-gate } 2754*7c478bd9Sstevel@tonic-gate 2755*7c478bd9Sstevel@tonic-gate return (result); 2756*7c478bd9Sstevel@tonic-gate } 2757*7c478bd9Sstevel@tonic-gate 2758*7c478bd9Sstevel@tonic-gate 2759*7c478bd9Sstevel@tonic-gate static void 2760*7c478bd9Sstevel@tonic-gate sort_disk_list() 2761*7c478bd9Sstevel@tonic-gate { 2762*7c478bd9Sstevel@tonic-gate int n; 2763*7c478bd9Sstevel@tonic-gate struct disk_info **disks; 2764*7c478bd9Sstevel@tonic-gate struct disk_info *d; 2765*7c478bd9Sstevel@tonic-gate struct disk_info **dp; 2766*7c478bd9Sstevel@tonic-gate struct disk_info **dp2; 2767*7c478bd9Sstevel@tonic-gate 2768*7c478bd9Sstevel@tonic-gate /* 2769*7c478bd9Sstevel@tonic-gate * Count the number of disks in the list 2770*7c478bd9Sstevel@tonic-gate */ 2771*7c478bd9Sstevel@tonic-gate n = 0; 2772*7c478bd9Sstevel@tonic-gate for (d = disk_list; d != NULL; d = d->disk_next) { 2773*7c478bd9Sstevel@tonic-gate n++; 2774*7c478bd9Sstevel@tonic-gate } 2775*7c478bd9Sstevel@tonic-gate if (n == 0) { 2776*7c478bd9Sstevel@tonic-gate return; 2777*7c478bd9Sstevel@tonic-gate } 2778*7c478bd9Sstevel@tonic-gate 2779*7c478bd9Sstevel@tonic-gate /* 2780*7c478bd9Sstevel@tonic-gate * Allocate a simple disk list array and fill it in 2781*7c478bd9Sstevel@tonic-gate */ 2782*7c478bd9Sstevel@tonic-gate disks = (struct disk_info **) 2783*7c478bd9Sstevel@tonic-gate zalloc((n+1) * sizeof (struct disk_info *)); 2784*7c478bd9Sstevel@tonic-gate 2785*7c478bd9Sstevel@tonic-gate dp = disks; 2786*7c478bd9Sstevel@tonic-gate for (d = disk_list; d != NULL; d = d->disk_next) { 2787*7c478bd9Sstevel@tonic-gate *dp++ = d; 2788*7c478bd9Sstevel@tonic-gate } 2789*7c478bd9Sstevel@tonic-gate *dp = NULL; 2790*7c478bd9Sstevel@tonic-gate 2791*7c478bd9Sstevel@tonic-gate /* 2792*7c478bd9Sstevel@tonic-gate * Sort the disk list array 2793*7c478bd9Sstevel@tonic-gate */ 2794*7c478bd9Sstevel@tonic-gate qsort((void *) disks, n, sizeof (struct disk_info *), 2795*7c478bd9Sstevel@tonic-gate disk_name_compare); 2796*7c478bd9Sstevel@tonic-gate 2797*7c478bd9Sstevel@tonic-gate /* 2798*7c478bd9Sstevel@tonic-gate * Rebuild the linked list disk list structure 2799*7c478bd9Sstevel@tonic-gate */ 2800*7c478bd9Sstevel@tonic-gate dp = disks; 2801*7c478bd9Sstevel@tonic-gate disk_list = *dp; 2802*7c478bd9Sstevel@tonic-gate dp2 = dp + 1; 2803*7c478bd9Sstevel@tonic-gate do { 2804*7c478bd9Sstevel@tonic-gate (*dp++)->disk_next = *dp2++; 2805*7c478bd9Sstevel@tonic-gate } while (*dp != NULL); 2806*7c478bd9Sstevel@tonic-gate 2807*7c478bd9Sstevel@tonic-gate /* 2808*7c478bd9Sstevel@tonic-gate * Clean up 2809*7c478bd9Sstevel@tonic-gate */ 2810*7c478bd9Sstevel@tonic-gate (void) destroy_data((void *)disks); 2811*7c478bd9Sstevel@tonic-gate } 2812*7c478bd9Sstevel@tonic-gate 2813*7c478bd9Sstevel@tonic-gate 2814*7c478bd9Sstevel@tonic-gate /* 2815*7c478bd9Sstevel@tonic-gate * Compare two disk names 2816*7c478bd9Sstevel@tonic-gate */ 2817*7c478bd9Sstevel@tonic-gate static int 2818*7c478bd9Sstevel@tonic-gate disk_name_compare( 2819*7c478bd9Sstevel@tonic-gate const void *arg1, 2820*7c478bd9Sstevel@tonic-gate const void *arg2) 2821*7c478bd9Sstevel@tonic-gate { 2822*7c478bd9Sstevel@tonic-gate char *s1; 2823*7c478bd9Sstevel@tonic-gate char *s2; 2824*7c478bd9Sstevel@tonic-gate int n1; 2825*7c478bd9Sstevel@tonic-gate int n2; 2826*7c478bd9Sstevel@tonic-gate char *p1; 2827*7c478bd9Sstevel@tonic-gate char *p2; 2828*7c478bd9Sstevel@tonic-gate 2829*7c478bd9Sstevel@tonic-gate s1 = (*((struct disk_info **)arg1))->disk_name; 2830*7c478bd9Sstevel@tonic-gate s2 = (*((struct disk_info **)arg2))->disk_name; 2831*7c478bd9Sstevel@tonic-gate 2832*7c478bd9Sstevel@tonic-gate for (;;) { 2833*7c478bd9Sstevel@tonic-gate if (*s1 == 0 || *s2 == 0) 2834*7c478bd9Sstevel@tonic-gate break; 2835*7c478bd9Sstevel@tonic-gate if (isdigit(*s1) && isdigit(*s2)) { 2836*7c478bd9Sstevel@tonic-gate n1 = strtol(s1, &p1, 10); 2837*7c478bd9Sstevel@tonic-gate n2 = strtol(s2, &p2, 10); 2838*7c478bd9Sstevel@tonic-gate if (n1 != n2) { 2839*7c478bd9Sstevel@tonic-gate return (n1 - n2); 2840*7c478bd9Sstevel@tonic-gate } 2841*7c478bd9Sstevel@tonic-gate s1 = p1; 2842*7c478bd9Sstevel@tonic-gate s2 = p2; 2843*7c478bd9Sstevel@tonic-gate } else if (*s1 != *s2) { 2844*7c478bd9Sstevel@tonic-gate break; 2845*7c478bd9Sstevel@tonic-gate } else { 2846*7c478bd9Sstevel@tonic-gate s1++; 2847*7c478bd9Sstevel@tonic-gate s2++; 2848*7c478bd9Sstevel@tonic-gate } 2849*7c478bd9Sstevel@tonic-gate } 2850*7c478bd9Sstevel@tonic-gate 2851*7c478bd9Sstevel@tonic-gate return (*s1 - *s2); 2852*7c478bd9Sstevel@tonic-gate } 2853*7c478bd9Sstevel@tonic-gate 2854*7c478bd9Sstevel@tonic-gate static void 2855*7c478bd9Sstevel@tonic-gate make_controller_list() 2856*7c478bd9Sstevel@tonic-gate { 2857*7c478bd9Sstevel@tonic-gate int x; 2858*7c478bd9Sstevel@tonic-gate struct mctlr_list *ctlrp; 2859*7c478bd9Sstevel@tonic-gate 2860*7c478bd9Sstevel@tonic-gate ctlrp = controlp; 2861*7c478bd9Sstevel@tonic-gate 2862*7c478bd9Sstevel@tonic-gate for (x = nctypes; x != 0; x--) { 2863*7c478bd9Sstevel@tonic-gate ctlrp = zalloc(sizeof (struct mctlr_list)); 2864*7c478bd9Sstevel@tonic-gate ctlrp->next = controlp; 2865*7c478bd9Sstevel@tonic-gate ctlrp->ctlr_type = &ctlr_types[x - 1]; 2866*7c478bd9Sstevel@tonic-gate controlp = ctlrp; 2867*7c478bd9Sstevel@tonic-gate 2868*7c478bd9Sstevel@tonic-gate } 2869*7c478bd9Sstevel@tonic-gate } 2870*7c478bd9Sstevel@tonic-gate 2871*7c478bd9Sstevel@tonic-gate static void 2872*7c478bd9Sstevel@tonic-gate check_for_duplicate_disknames(arglist) 2873*7c478bd9Sstevel@tonic-gate char *arglist[]; 2874*7c478bd9Sstevel@tonic-gate { 2875*7c478bd9Sstevel@tonic-gate char *directory = "/dev/rdsk/"; 2876*7c478bd9Sstevel@tonic-gate char **disklist; 2877*7c478bd9Sstevel@tonic-gate int len; 2878*7c478bd9Sstevel@tonic-gate char s[MAXPATHLEN], t[MAXPATHLEN]; 2879*7c478bd9Sstevel@tonic-gate int diskno = 0; 2880*7c478bd9Sstevel@tonic-gate int i; 2881*7c478bd9Sstevel@tonic-gate 2882*7c478bd9Sstevel@tonic-gate 2883*7c478bd9Sstevel@tonic-gate len = strlen(directory); 2884*7c478bd9Sstevel@tonic-gate disklist = arglist; 2885*7c478bd9Sstevel@tonic-gate for (; *disklist != NULL; disklist++) { 2886*7c478bd9Sstevel@tonic-gate if (strncmp(directory, *disklist, len) == 0) { 2887*7c478bd9Sstevel@tonic-gate /* Disk is in conventional format */ 2888*7c478bd9Sstevel@tonic-gate canonicalize_name(s, *disklist); 2889*7c478bd9Sstevel@tonic-gate /* 2890*7c478bd9Sstevel@tonic-gate * check if the disk is already present in 2891*7c478bd9Sstevel@tonic-gate * disk list. 2892*7c478bd9Sstevel@tonic-gate */ 2893*7c478bd9Sstevel@tonic-gate for (i = 0; i < diskno; i++) { 2894*7c478bd9Sstevel@tonic-gate canonicalize_name(t, arglist[i]); 2895*7c478bd9Sstevel@tonic-gate if (strncmp(s, t, strlen(t)) == 0) 2896*7c478bd9Sstevel@tonic-gate break; 2897*7c478bd9Sstevel@tonic-gate } 2898*7c478bd9Sstevel@tonic-gate if (i != diskno) 2899*7c478bd9Sstevel@tonic-gate continue; 2900*7c478bd9Sstevel@tonic-gate } 2901*7c478bd9Sstevel@tonic-gate (void) strcpy(arglist[diskno], *disklist); 2902*7c478bd9Sstevel@tonic-gate diskno++; 2903*7c478bd9Sstevel@tonic-gate } 2904*7c478bd9Sstevel@tonic-gate arglist[diskno] = NULL; 2905*7c478bd9Sstevel@tonic-gate } 2906*7c478bd9Sstevel@tonic-gate 2907*7c478bd9Sstevel@tonic-gate #define DISK_PREFIX "/dev/rdsk/" 2908*7c478bd9Sstevel@tonic-gate 2909*7c478bd9Sstevel@tonic-gate /* 2910*7c478bd9Sstevel@tonic-gate * This Function checks if the non-conventional name is a a link to 2911*7c478bd9Sstevel@tonic-gate * one of the conventional whole disk name. 2912*7c478bd9Sstevel@tonic-gate */ 2913*7c478bd9Sstevel@tonic-gate static int 2914*7c478bd9Sstevel@tonic-gate name_represents_wholedisk(name) 2915*7c478bd9Sstevel@tonic-gate char *name; 2916*7c478bd9Sstevel@tonic-gate { 2917*7c478bd9Sstevel@tonic-gate char symname[MAXPATHLEN]; 2918*7c478bd9Sstevel@tonic-gate char localname[MAXPATHLEN]; 2919*7c478bd9Sstevel@tonic-gate char *nameptr; 2920*7c478bd9Sstevel@tonic-gate 2921*7c478bd9Sstevel@tonic-gate 2922*7c478bd9Sstevel@tonic-gate (void) memset(symname, 0, MAXPATHLEN); 2923*7c478bd9Sstevel@tonic-gate (void) memset(localname, 0, MAXPATHLEN); 2924*7c478bd9Sstevel@tonic-gate (void) strcpy(localname, name); 2925*7c478bd9Sstevel@tonic-gate 2926*7c478bd9Sstevel@tonic-gate while (readlink(localname, symname, MAXPATHLEN) != -1) { 2927*7c478bd9Sstevel@tonic-gate nameptr = symname; 2928*7c478bd9Sstevel@tonic-gate if (strncmp(symname, DISK_PREFIX, strlen(DISK_PREFIX)) == 0) 2929*7c478bd9Sstevel@tonic-gate nameptr += strlen(DISK_PREFIX); 2930*7c478bd9Sstevel@tonic-gate if (conventional_name(nameptr)) { 2931*7c478bd9Sstevel@tonic-gate if (whole_disk_name(nameptr)) 2932*7c478bd9Sstevel@tonic-gate return (0); 2933*7c478bd9Sstevel@tonic-gate else 2934*7c478bd9Sstevel@tonic-gate return (1); 2935*7c478bd9Sstevel@tonic-gate } 2936*7c478bd9Sstevel@tonic-gate (void) strcpy(localname, symname); 2937*7c478bd9Sstevel@tonic-gate (void) memset(symname, 0, MAXPATHLEN); 2938*7c478bd9Sstevel@tonic-gate } 2939*7c478bd9Sstevel@tonic-gate return (0); 2940*7c478bd9Sstevel@tonic-gate } 2941