17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * This file contains the code to perform program startup. This 317c478bd9Sstevel@tonic-gate * includes reading the data file and the search for disks. 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate #include "global.h" 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <ctype.h> 367c478bd9Sstevel@tonic-gate #include <stdlib.h> 377c478bd9Sstevel@tonic-gate #include <unistd.h> 387c478bd9Sstevel@tonic-gate #include <string.h> 397c478bd9Sstevel@tonic-gate #include <strings.h> 407c478bd9Sstevel@tonic-gate #include <fcntl.h> 417c478bd9Sstevel@tonic-gate #include <errno.h> 427c478bd9Sstevel@tonic-gate #include <memory.h> 437c478bd9Sstevel@tonic-gate #include <dirent.h> 447c478bd9Sstevel@tonic-gate #include <sys/fcntl.h> 457c478bd9Sstevel@tonic-gate #include <sys/param.h> 467c478bd9Sstevel@tonic-gate #include <sys/stat.h> 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #include "startup.h" 497c478bd9Sstevel@tonic-gate #include "param.h" 507c478bd9Sstevel@tonic-gate #include "label.h" 517c478bd9Sstevel@tonic-gate #include "misc.h" 527c478bd9Sstevel@tonic-gate #include "menu_command.h" 537c478bd9Sstevel@tonic-gate #include "partition.h" 547c478bd9Sstevel@tonic-gate #include "ctlr_scsi.h" 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #include "auto_sense.h" 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate extern struct ctlr_type ctlr_types[]; 597c478bd9Sstevel@tonic-gate extern int nctypes; 607c478bd9Sstevel@tonic-gate extern struct ctlr_ops genericops; 617c478bd9Sstevel@tonic-gate extern long strtol(); 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate extern int errno; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #ifdef __STDC__ 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* Function prototypes for ANSI C Compilers */ 687c478bd9Sstevel@tonic-gate static void usage(void); 697c478bd9Sstevel@tonic-gate static int sup_prxfile(void); 707c478bd9Sstevel@tonic-gate static void sup_setpath(void); 717c478bd9Sstevel@tonic-gate static void sup_setdtype(void); 727c478bd9Sstevel@tonic-gate static int sup_change_spec(struct disk_type *, char *); 737c478bd9Sstevel@tonic-gate static void sup_setpart(void); 747c478bd9Sstevel@tonic-gate static void search_for_logical_dev(char *devname); 757c478bd9Sstevel@tonic-gate static void add_device_to_disklist(char *devname, char *devpath); 767c478bd9Sstevel@tonic-gate static int disk_is_known(struct dk_cinfo *dkinfo); 777c478bd9Sstevel@tonic-gate static void datafile_error(char *errmsg, char *token); 787c478bd9Sstevel@tonic-gate static void search_duplicate_dtypes(void); 797c478bd9Sstevel@tonic-gate static void search_duplicate_pinfo(void); 807c478bd9Sstevel@tonic-gate static void check_dtypes_for_inconsistency(struct disk_type *dp1, 817c478bd9Sstevel@tonic-gate struct disk_type *dp2); 827c478bd9Sstevel@tonic-gate static void check_pinfo_for_inconsistency(struct partition_info *pp1, 837c478bd9Sstevel@tonic-gate struct partition_info *pp2); 847c478bd9Sstevel@tonic-gate static int str2blks(char *str); 857c478bd9Sstevel@tonic-gate static int str2cyls(char *str); 867c478bd9Sstevel@tonic-gate static struct chg_list *new_chg_list(struct disk_type *); 877c478bd9Sstevel@tonic-gate static char *get_physical_name(char *); 887c478bd9Sstevel@tonic-gate static void sort_disk_list(void); 897c478bd9Sstevel@tonic-gate static int disk_name_compare(const void *, const void *); 907c478bd9Sstevel@tonic-gate static void make_controller_list(void); 917c478bd9Sstevel@tonic-gate static void check_for_duplicate_disknames(char *arglist[]); 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate /* Function prototypes for non-ANSI C Compilers */ 967c478bd9Sstevel@tonic-gate static void usage(); 977c478bd9Sstevel@tonic-gate static int sup_prxfile(); 987c478bd9Sstevel@tonic-gate static void sup_setpath(); 997c478bd9Sstevel@tonic-gate static void sup_setdtype(); 1007c478bd9Sstevel@tonic-gate static int sup_change_spec(); 1017c478bd9Sstevel@tonic-gate static void sup_setpart(); 1027c478bd9Sstevel@tonic-gate static void search_for_logical_dev(); 1037c478bd9Sstevel@tonic-gate static void add_device_to_disklist(); 1047c478bd9Sstevel@tonic-gate static int disk_is_known(); 1057c478bd9Sstevel@tonic-gate static void datafile_error(); 1067c478bd9Sstevel@tonic-gate static void search_duplicate_dtypes(); 1077c478bd9Sstevel@tonic-gate static void search_duplicate_pinfo(); 1087c478bd9Sstevel@tonic-gate static void check_dtypes_for_inconsistency(); 1097c478bd9Sstevel@tonic-gate static void check_pinfo_for_inconsistency(); 1107c478bd9Sstevel@tonic-gate static int str2blks(); 1117c478bd9Sstevel@tonic-gate static int str2cyls(); 1127c478bd9Sstevel@tonic-gate static struct chg_list *new_chg_list(); 1137c478bd9Sstevel@tonic-gate static char *get_physical_name(); 1147c478bd9Sstevel@tonic-gate static void sort_disk_list(); 1157c478bd9Sstevel@tonic-gate static int disk_name_compare(); 1167c478bd9Sstevel@tonic-gate static void make_controller_list(); 1177c478bd9Sstevel@tonic-gate static void check_for_duplicate_disknames(); 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate #if defined(sparc) 1227c478bd9Sstevel@tonic-gate static char *other_ctlrs[] = { 1237c478bd9Sstevel@tonic-gate "ata" 1247c478bd9Sstevel@tonic-gate }; 1257c478bd9Sstevel@tonic-gate #define OTHER_CTLRS 1 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate #elif defined(i386) 1287c478bd9Sstevel@tonic-gate static char *other_ctlrs[] = { 1297c478bd9Sstevel@tonic-gate "ISP-80" 1307c478bd9Sstevel@tonic-gate }; 1317c478bd9Sstevel@tonic-gate #define OTHER_CTLRS 2 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate #else 1347c478bd9Sstevel@tonic-gate #error No Platform defined. 1357c478bd9Sstevel@tonic-gate #endif 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate /* 1397c478bd9Sstevel@tonic-gate * This global is used to store the current line # in the data file. 1407c478bd9Sstevel@tonic-gate * It must be global because the I/O routines are allowed to side 1417c478bd9Sstevel@tonic-gate * effect it to keep track of backslashed newlines. 1427c478bd9Sstevel@tonic-gate */ 1437c478bd9Sstevel@tonic-gate int data_lineno; /* current line # in data file */ 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate /* 1467c478bd9Sstevel@tonic-gate * Search path as defined in the format.dat files 1477c478bd9Sstevel@tonic-gate */ 1487c478bd9Sstevel@tonic-gate static char **search_path = NULL; 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate static int name_represents_wholedisk(char *name); 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate /* 1567c478bd9Sstevel@tonic-gate * This routine digests the options on the command line. It returns 1577c478bd9Sstevel@tonic-gate * the index into argv of the first string that is not an option. If 1587c478bd9Sstevel@tonic-gate * there are none, it returns -1. 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate int 1617c478bd9Sstevel@tonic-gate do_options(int argc, char *argv[]) 1627c478bd9Sstevel@tonic-gate { 1637c478bd9Sstevel@tonic-gate char *ptr; 1647c478bd9Sstevel@tonic-gate int i; 1657c478bd9Sstevel@tonic-gate int next; 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* 1687c478bd9Sstevel@tonic-gate * Default is no extended messages. Can be enabled manually. 1697c478bd9Sstevel@tonic-gate */ 1707c478bd9Sstevel@tonic-gate option_msg = 0; 1717c478bd9Sstevel@tonic-gate diag_msg = 0; 1727c478bd9Sstevel@tonic-gate expert_mode = 0; 1737c478bd9Sstevel@tonic-gate need_newline = 0; 1747c478bd9Sstevel@tonic-gate dev_expert = 0; 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate /* 1777c478bd9Sstevel@tonic-gate * Loop through the argument list, incrementing each time by 1787c478bd9Sstevel@tonic-gate * an amount determined by the options found. 1797c478bd9Sstevel@tonic-gate */ 1807c478bd9Sstevel@tonic-gate for (i = 1; i < argc; i = next) { 1817c478bd9Sstevel@tonic-gate /* 1827c478bd9Sstevel@tonic-gate * Start out assuming an increment of 1. 1837c478bd9Sstevel@tonic-gate */ 1847c478bd9Sstevel@tonic-gate next = i + 1; 1857c478bd9Sstevel@tonic-gate /* 1867c478bd9Sstevel@tonic-gate * As soon as we hit a non-option, we're done. 1877c478bd9Sstevel@tonic-gate */ 1887c478bd9Sstevel@tonic-gate if (*argv[i] != '-') 1897c478bd9Sstevel@tonic-gate return (i); 1907c478bd9Sstevel@tonic-gate /* 1917c478bd9Sstevel@tonic-gate * Loop through all the characters in this option string. 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate for (ptr = argv[i] + 1; *ptr != '\0'; ptr++) { 1947c478bd9Sstevel@tonic-gate /* 1957c478bd9Sstevel@tonic-gate * Determine each option represented. For options 1967c478bd9Sstevel@tonic-gate * that use a second string, increase the increment 1977c478bd9Sstevel@tonic-gate * of the main loop so they aren't re-interpreted. 1987c478bd9Sstevel@tonic-gate */ 1997c478bd9Sstevel@tonic-gate switch (*ptr) { 2007c478bd9Sstevel@tonic-gate case 's': 2017c478bd9Sstevel@tonic-gate case 'S': 2027c478bd9Sstevel@tonic-gate option_s = 1; 2037c478bd9Sstevel@tonic-gate break; 2047c478bd9Sstevel@tonic-gate case 'f': 2057c478bd9Sstevel@tonic-gate case 'F': 2067c478bd9Sstevel@tonic-gate option_f = argv[next++]; 2077c478bd9Sstevel@tonic-gate if (next > argc) 2087c478bd9Sstevel@tonic-gate goto badopt; 2097c478bd9Sstevel@tonic-gate break; 2107c478bd9Sstevel@tonic-gate case 'l': 2117c478bd9Sstevel@tonic-gate case 'L': 2127c478bd9Sstevel@tonic-gate option_l = argv[next++]; 2137c478bd9Sstevel@tonic-gate if (next > argc) 2147c478bd9Sstevel@tonic-gate goto badopt; 2157c478bd9Sstevel@tonic-gate break; 2167c478bd9Sstevel@tonic-gate case 'x': 2177c478bd9Sstevel@tonic-gate case 'X': 2187c478bd9Sstevel@tonic-gate option_x = argv[next++]; 2197c478bd9Sstevel@tonic-gate if (next > argc) 2207c478bd9Sstevel@tonic-gate goto badopt; 2217c478bd9Sstevel@tonic-gate break; 2227c478bd9Sstevel@tonic-gate case 'd': 2237c478bd9Sstevel@tonic-gate case 'D': 2247c478bd9Sstevel@tonic-gate option_d = argv[next++]; 2257c478bd9Sstevel@tonic-gate if (next > argc) 2267c478bd9Sstevel@tonic-gate goto badopt; 2277c478bd9Sstevel@tonic-gate break; 2287c478bd9Sstevel@tonic-gate case 't': 2297c478bd9Sstevel@tonic-gate case 'T': 2307c478bd9Sstevel@tonic-gate option_t = argv[next++]; 2317c478bd9Sstevel@tonic-gate if (next > argc) 2327c478bd9Sstevel@tonic-gate goto badopt; 2337c478bd9Sstevel@tonic-gate break; 2347c478bd9Sstevel@tonic-gate case 'p': 2357c478bd9Sstevel@tonic-gate case 'P': 2367c478bd9Sstevel@tonic-gate option_p = argv[next++]; 2377c478bd9Sstevel@tonic-gate if (next > argc) 2387c478bd9Sstevel@tonic-gate goto badopt; 2397c478bd9Sstevel@tonic-gate break; 2407c478bd9Sstevel@tonic-gate case 'm': 2417c478bd9Sstevel@tonic-gate option_msg = 1; 2427c478bd9Sstevel@tonic-gate break; 2437c478bd9Sstevel@tonic-gate case 'M': 2447c478bd9Sstevel@tonic-gate option_msg = 1; 2457c478bd9Sstevel@tonic-gate diag_msg = 1; 2467c478bd9Sstevel@tonic-gate break; 2477c478bd9Sstevel@tonic-gate case 'e': 2487c478bd9Sstevel@tonic-gate expert_mode = 1; 2497c478bd9Sstevel@tonic-gate break; 2507c478bd9Sstevel@tonic-gate #ifdef DEBUG 2517c478bd9Sstevel@tonic-gate case 'z': 2527c478bd9Sstevel@tonic-gate dev_expert = 1; 2537c478bd9Sstevel@tonic-gate break; 2547c478bd9Sstevel@tonic-gate #endif 2557c478bd9Sstevel@tonic-gate default: 2567c478bd9Sstevel@tonic-gate badopt: 2577c478bd9Sstevel@tonic-gate usage(); 2587c478bd9Sstevel@tonic-gate break; 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate /* 2637c478bd9Sstevel@tonic-gate * All the command line strings were options. Return that fact. 2647c478bd9Sstevel@tonic-gate */ 2657c478bd9Sstevel@tonic-gate return (-1); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate static void 2707c478bd9Sstevel@tonic-gate usage() 2717c478bd9Sstevel@tonic-gate { 2727c478bd9Sstevel@tonic-gate err_print("Usage: format [-s][-d disk_name]"); 2737c478bd9Sstevel@tonic-gate err_print("[-t disk_type][-p partition_name]\n"); 2747c478bd9Sstevel@tonic-gate err_print("\t[-f cmd_file][-l log_file]"); 2757c478bd9Sstevel@tonic-gate err_print("[-x data_file] [-m] [-M] [-e] disk_list\n"); 2767c478bd9Sstevel@tonic-gate fullabort(); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate /* 2817c478bd9Sstevel@tonic-gate * This routine reads in and digests the data file. The data file contains 2827c478bd9Sstevel@tonic-gate * definitions for the search path, known disk types, and known partition 2837c478bd9Sstevel@tonic-gate * maps. 2847c478bd9Sstevel@tonic-gate * 2857c478bd9Sstevel@tonic-gate * Note: for each file being processed, file_name is a pointer to that 2867c478bd9Sstevel@tonic-gate * file's name. We are careful to make sure that file_name points to 2877c478bd9Sstevel@tonic-gate * globally-accessible data, not data on the stack, because each 2887c478bd9Sstevel@tonic-gate * disk/partition/controller definition now keeps a pointer to the 2897c478bd9Sstevel@tonic-gate * filename in which it was defined. In the case of duplicate, 2907c478bd9Sstevel@tonic-gate * conflicting definitions, we can thus tell the user exactly where 2917c478bd9Sstevel@tonic-gate * the problem is occurring. 2927c478bd9Sstevel@tonic-gate */ 2937c478bd9Sstevel@tonic-gate void 2947c478bd9Sstevel@tonic-gate sup_init() 2957c478bd9Sstevel@tonic-gate { 2967c478bd9Sstevel@tonic-gate int nopened_files = 0; 2977c478bd9Sstevel@tonic-gate 2987c478bd9Sstevel@tonic-gate #if defined(sparc) 2997c478bd9Sstevel@tonic-gate char fname[MAXPATHLEN]; 3007c478bd9Sstevel@tonic-gate char *path; 3017c478bd9Sstevel@tonic-gate char *p; 3027c478bd9Sstevel@tonic-gate struct stat stbuf; 3037c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */ 3047c478bd9Sstevel@tonic-gate 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate /* 3077c478bd9Sstevel@tonic-gate * Create a singly-linked list of controller types so that we may 3087c478bd9Sstevel@tonic-gate * dynamically add unknown controllers to this for 3'rd 3097c478bd9Sstevel@tonic-gate * party disk support. 3107c478bd9Sstevel@tonic-gate */ 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate make_controller_list(); 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* 3157c478bd9Sstevel@tonic-gate * If a data file was specified on the command line, use it first 3167c478bd9Sstevel@tonic-gate * If the file cannot be opened, fail. We want to guarantee 3177c478bd9Sstevel@tonic-gate * that, if the user explicitly names a file, they can 3187c478bd9Sstevel@tonic-gate * access it. 3197c478bd9Sstevel@tonic-gate * 3207c478bd9Sstevel@tonic-gate * option_x is already global, no need to dup it on the heap. 3217c478bd9Sstevel@tonic-gate */ 3227c478bd9Sstevel@tonic-gate if (option_x) { 3237c478bd9Sstevel@tonic-gate file_name = option_x; 3247c478bd9Sstevel@tonic-gate if (sup_prxfile()) { 3257c478bd9Sstevel@tonic-gate nopened_files++; 3267c478bd9Sstevel@tonic-gate } else { 3277c478bd9Sstevel@tonic-gate err_print("Unable to open data file '%s' - %s.\n", 3287c478bd9Sstevel@tonic-gate file_name, strerror(errno)); 3297c478bd9Sstevel@tonic-gate fullabort(); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate #if defined(sparc) 3347c478bd9Sstevel@tonic-gate /* 3357c478bd9Sstevel@tonic-gate * Now look for an environment variable FORMAT_PATH. 3367c478bd9Sstevel@tonic-gate * If found, we use it as a colon-separated list 3377c478bd9Sstevel@tonic-gate * of directories. If no such environment variable 3387c478bd9Sstevel@tonic-gate * is defined, use a default path of "/etc". 3397c478bd9Sstevel@tonic-gate */ 3407c478bd9Sstevel@tonic-gate path = getenv("FORMAT_PATH"); 3417c478bd9Sstevel@tonic-gate if (path == NULL) { 3427c478bd9Sstevel@tonic-gate path = "/etc"; 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate /* 3457c478bd9Sstevel@tonic-gate * Traverse the path one file at a time. Pick off 3467c478bd9Sstevel@tonic-gate * the file name, and append the name "format.dat" 3477c478bd9Sstevel@tonic-gate * at the end of the pathname. 3487c478bd9Sstevel@tonic-gate * Whatever string we construct, duplicate it on the 3497c478bd9Sstevel@tonic-gate * heap, so that file_name is globally accessible. 3507c478bd9Sstevel@tonic-gate */ 3517c478bd9Sstevel@tonic-gate while (*path != 0) { 3527c478bd9Sstevel@tonic-gate p = fname; 3537c478bd9Sstevel@tonic-gate while (*path != 0 && *path != ':') 3547c478bd9Sstevel@tonic-gate *p++ = *path++; 3557c478bd9Sstevel@tonic-gate if (p == fname) 3567c478bd9Sstevel@tonic-gate continue; 3577c478bd9Sstevel@tonic-gate *p = 0; 3587c478bd9Sstevel@tonic-gate if (*path == ':') 3597c478bd9Sstevel@tonic-gate path++; 3607c478bd9Sstevel@tonic-gate /* 3617c478bd9Sstevel@tonic-gate * If the path we have so far is a directory, 3627c478bd9Sstevel@tonic-gate * look for a format.dat file in that directory, 3637c478bd9Sstevel@tonic-gate * otherwise try using the path name specified. 3647c478bd9Sstevel@tonic-gate * This permits arbitrary file names in the 3657c478bd9Sstevel@tonic-gate * path specification, if this proves useful. 3667c478bd9Sstevel@tonic-gate */ 3677c478bd9Sstevel@tonic-gate if (stat(fname, &stbuf) == -1) { 3687c478bd9Sstevel@tonic-gate err_print("Unable to access '%s' - %s.\n", 3697c478bd9Sstevel@tonic-gate fname, strerror(errno)); 3707c478bd9Sstevel@tonic-gate } else { 3717c478bd9Sstevel@tonic-gate if (S_ISDIR(stbuf.st_mode)) { 3727c478bd9Sstevel@tonic-gate if (*(p-1) != '/') 3737c478bd9Sstevel@tonic-gate *p++ = '/'; 3747c478bd9Sstevel@tonic-gate (void) strcpy(p, "format.dat"); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate file_name = alloc_string(fname); 3777c478bd9Sstevel@tonic-gate if (sup_prxfile()) { 3787c478bd9Sstevel@tonic-gate nopened_files++; 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */ 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate /* 3857c478bd9Sstevel@tonic-gate * Check for duplicate disk or partitions definitions 3867c478bd9Sstevel@tonic-gate * that are inconsistent - this would be very confusing. 3877c478bd9Sstevel@tonic-gate */ 3887c478bd9Sstevel@tonic-gate search_duplicate_dtypes(); 3897c478bd9Sstevel@tonic-gate search_duplicate_pinfo(); 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate /* 3947c478bd9Sstevel@tonic-gate * Open and process a format data file. Unfortunately, we use 3957c478bd9Sstevel@tonic-gate * globals: file_name for the file name, and data_file 3967c478bd9Sstevel@tonic-gate * for the descriptor. Return true if able to open the file. 3977c478bd9Sstevel@tonic-gate */ 3987c478bd9Sstevel@tonic-gate static int 3997c478bd9Sstevel@tonic-gate sup_prxfile() 4007c478bd9Sstevel@tonic-gate { 4017c478bd9Sstevel@tonic-gate int status; 4027c478bd9Sstevel@tonic-gate TOKEN token; 4037c478bd9Sstevel@tonic-gate TOKEN cleaned; 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate /* 4067c478bd9Sstevel@tonic-gate * Open the data file. Return 0 if unable to do so. 4077c478bd9Sstevel@tonic-gate */ 4087c478bd9Sstevel@tonic-gate data_file = fopen(file_name, "r"); 4097c478bd9Sstevel@tonic-gate if (data_file == NULL) { 4107c478bd9Sstevel@tonic-gate return (0); 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate /* 4137c478bd9Sstevel@tonic-gate * Step through the data file a meta-line at a time. There are 4147c478bd9Sstevel@tonic-gate * typically several backslashed newlines in each meta-line, 4157c478bd9Sstevel@tonic-gate * so data_lineno will be getting side effected along the way. 4167c478bd9Sstevel@tonic-gate */ 4177c478bd9Sstevel@tonic-gate data_lineno = 0; 4187c478bd9Sstevel@tonic-gate for (;;) { 4197c478bd9Sstevel@tonic-gate data_lineno++; 4207c478bd9Sstevel@tonic-gate /* 4217c478bd9Sstevel@tonic-gate * Get the keyword. 4227c478bd9Sstevel@tonic-gate */ 4237c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 4247c478bd9Sstevel@tonic-gate /* 4257c478bd9Sstevel@tonic-gate * If we hit the end of the data file, we're done. 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate if (status == SUP_EOF) 4287c478bd9Sstevel@tonic-gate break; 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * If the line is blank, skip it. 4317c478bd9Sstevel@tonic-gate */ 4327c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 4337c478bd9Sstevel@tonic-gate continue; 4347c478bd9Sstevel@tonic-gate /* 4357c478bd9Sstevel@tonic-gate * If the line starts with some key character, it's an error. 4367c478bd9Sstevel@tonic-gate */ 4377c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 4387c478bd9Sstevel@tonic-gate datafile_error("Expecting keyword, found '%s'", token); 4397c478bd9Sstevel@tonic-gate continue; 4407c478bd9Sstevel@tonic-gate } 4417c478bd9Sstevel@tonic-gate /* 4427c478bd9Sstevel@tonic-gate * Clean up the token and see which keyword it is. Call 4437c478bd9Sstevel@tonic-gate * the appropriate routine to process the rest of the line. 4447c478bd9Sstevel@tonic-gate */ 4457c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 4467c478bd9Sstevel@tonic-gate if (strcmp(cleaned, "search_path") == 0) 4477c478bd9Sstevel@tonic-gate sup_setpath(); 4487c478bd9Sstevel@tonic-gate else if (strcmp(cleaned, "disk_type") == 0) 4497c478bd9Sstevel@tonic-gate sup_setdtype(); 4507c478bd9Sstevel@tonic-gate else if (strcmp(cleaned, "partition") == 0) 4517c478bd9Sstevel@tonic-gate sup_setpart(); 4527c478bd9Sstevel@tonic-gate else { 4537c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", cleaned); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate } 4567c478bd9Sstevel@tonic-gate /* 4577c478bd9Sstevel@tonic-gate * Close the data file. 4587c478bd9Sstevel@tonic-gate */ 4597c478bd9Sstevel@tonic-gate (void) fclose(data_file); 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate return (1); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate /* 4657c478bd9Sstevel@tonic-gate * This routine processes a 'search_path' line in the data file. The 4667c478bd9Sstevel@tonic-gate * search path is a list of disk names that will be searched for by the 4677c478bd9Sstevel@tonic-gate * program. 4687c478bd9Sstevel@tonic-gate * 4697c478bd9Sstevel@tonic-gate * The static path_size and path_alloc are used to build up the 4707c478bd9Sstevel@tonic-gate * list of files comprising the search path. The static definitions 4717c478bd9Sstevel@tonic-gate * enable supporting multiple search path definitions. 4727c478bd9Sstevel@tonic-gate */ 4737c478bd9Sstevel@tonic-gate static void 4747c478bd9Sstevel@tonic-gate sup_setpath() 4757c478bd9Sstevel@tonic-gate { 4767c478bd9Sstevel@tonic-gate TOKEN token; 4777c478bd9Sstevel@tonic-gate TOKEN cleaned; 4787c478bd9Sstevel@tonic-gate int status; 4797c478bd9Sstevel@tonic-gate static int path_size; 4807c478bd9Sstevel@tonic-gate static int path_alloc; 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate /* 4837c478bd9Sstevel@tonic-gate * Pull in some grammar. 4847c478bd9Sstevel@tonic-gate */ 4857c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 4867c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 4877c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 4887c478bd9Sstevel@tonic-gate return; 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate /* 4917c478bd9Sstevel@tonic-gate * Loop through the entries. 4927c478bd9Sstevel@tonic-gate */ 4937c478bd9Sstevel@tonic-gate for (;;) { 4947c478bd9Sstevel@tonic-gate /* 4957c478bd9Sstevel@tonic-gate * Pull in the disk name. 4967c478bd9Sstevel@tonic-gate */ 4977c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 4987c478bd9Sstevel@tonic-gate /* 4997c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 5007c478bd9Sstevel@tonic-gate */ 5017c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 5027c478bd9Sstevel@tonic-gate break; 5037c478bd9Sstevel@tonic-gate /* 5047c478bd9Sstevel@tonic-gate * If we hit some key character, it's an error. 5057c478bd9Sstevel@tonic-gate */ 5067c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 5077c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 5087c478bd9Sstevel@tonic-gate break; 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 5117c478bd9Sstevel@tonic-gate /* 5127c478bd9Sstevel@tonic-gate * Build the string into an argvlist. This array 5137c478bd9Sstevel@tonic-gate * is dynamically sized, as necessary, and terminated 5147c478bd9Sstevel@tonic-gate * with a null. Each name is alloc'ed on the heap, 5157c478bd9Sstevel@tonic-gate * so no dangling references. 5167c478bd9Sstevel@tonic-gate */ 5177c478bd9Sstevel@tonic-gate search_path = build_argvlist(search_path, &path_size, 5187c478bd9Sstevel@tonic-gate &path_alloc, cleaned); 5197c478bd9Sstevel@tonic-gate /* 5207c478bd9Sstevel@tonic-gate * Pull in some grammar. 5217c478bd9Sstevel@tonic-gate */ 5227c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 5237c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 5247c478bd9Sstevel@tonic-gate break; 5257c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 5267c478bd9Sstevel@tonic-gate datafile_error("Expecting ', ', found '%s'", token); 5277c478bd9Sstevel@tonic-gate break; 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate /* 5337c478bd9Sstevel@tonic-gate * This routine processes a 'disk_type' line in the data file. It defines 5347c478bd9Sstevel@tonic-gate * the physical attributes of a brand of disk when connected to a specific 5357c478bd9Sstevel@tonic-gate * controller type. 5367c478bd9Sstevel@tonic-gate */ 5377c478bd9Sstevel@tonic-gate static void 5387c478bd9Sstevel@tonic-gate sup_setdtype() 5397c478bd9Sstevel@tonic-gate { 5407c478bd9Sstevel@tonic-gate TOKEN token, cleaned, ident; 5417c478bd9Sstevel@tonic-gate int val, status, i; 5427c478bd9Sstevel@tonic-gate ulong_t flags = 0; 5437c478bd9Sstevel@tonic-gate struct disk_type *dtype, *type; 5447c478bd9Sstevel@tonic-gate struct ctlr_type *ctype; 5457c478bd9Sstevel@tonic-gate char *dtype_name, *ptr; 5467c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate /* 5497c478bd9Sstevel@tonic-gate * Pull in some grammar. 5507c478bd9Sstevel@tonic-gate */ 5517c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 5527c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 5537c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 5547c478bd9Sstevel@tonic-gate return; 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate /* 5577c478bd9Sstevel@tonic-gate * Pull in the name of the disk type. 5587c478bd9Sstevel@tonic-gate */ 5597c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 5607c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 5617c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 5627c478bd9Sstevel@tonic-gate return; 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 5657c478bd9Sstevel@tonic-gate /* 5667c478bd9Sstevel@tonic-gate * Allocate space for the disk type and copy in the name. 5677c478bd9Sstevel@tonic-gate */ 5687c478bd9Sstevel@tonic-gate dtype_name = (char *)zalloc(strlen(cleaned) + 1); 5697c478bd9Sstevel@tonic-gate (void) strcpy(dtype_name, cleaned); 5707c478bd9Sstevel@tonic-gate dtype = (struct disk_type *)zalloc(sizeof (struct disk_type)); 5717c478bd9Sstevel@tonic-gate dtype->dtype_asciilabel = dtype_name; 5727c478bd9Sstevel@tonic-gate /* 5737c478bd9Sstevel@tonic-gate * Save the filename/linenumber where this disk was defined 5747c478bd9Sstevel@tonic-gate */ 5757c478bd9Sstevel@tonic-gate dtype->dtype_filename = file_name; 5767c478bd9Sstevel@tonic-gate dtype->dtype_lineno = data_lineno; 5777c478bd9Sstevel@tonic-gate /* 5787c478bd9Sstevel@tonic-gate * Loop for each attribute. 5797c478bd9Sstevel@tonic-gate */ 5807c478bd9Sstevel@tonic-gate for (;;) { 5817c478bd9Sstevel@tonic-gate /* 5827c478bd9Sstevel@tonic-gate * Pull in some grammar. 5837c478bd9Sstevel@tonic-gate */ 5847c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 5857c478bd9Sstevel@tonic-gate /* 5867c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 5877c478bd9Sstevel@tonic-gate */ 5887c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 5897c478bd9Sstevel@tonic-gate break; 5907c478bd9Sstevel@tonic-gate if (status != SUP_COLON) { 5917c478bd9Sstevel@tonic-gate datafile_error("Expecting ':', found '%s'", token); 5927c478bd9Sstevel@tonic-gate return; 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate /* 5957c478bd9Sstevel@tonic-gate * Pull in the attribute. 5967c478bd9Sstevel@tonic-gate */ 5977c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 5987c478bd9Sstevel@tonic-gate /* 5997c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 6007c478bd9Sstevel@tonic-gate */ 6017c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 6027c478bd9Sstevel@tonic-gate break; 6037c478bd9Sstevel@tonic-gate /* 6047c478bd9Sstevel@tonic-gate * If we hit a key character, it's an error. 6057c478bd9Sstevel@tonic-gate */ 6067c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 6077c478bd9Sstevel@tonic-gate datafile_error("Expecting keyword, found '%s'", token); 6087c478bd9Sstevel@tonic-gate return; 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate clean_token(ident, token); 6117c478bd9Sstevel@tonic-gate /* 6127c478bd9Sstevel@tonic-gate * Check to see if we've got a change specification 6137c478bd9Sstevel@tonic-gate * If so, this routine will parse the entire 6147c478bd9Sstevel@tonic-gate * specification, so just restart at top of loop 6157c478bd9Sstevel@tonic-gate */ 6167c478bd9Sstevel@tonic-gate if (sup_change_spec(dtype, ident)) { 6177c478bd9Sstevel@tonic-gate continue; 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate /* 6207c478bd9Sstevel@tonic-gate * Pull in more grammar. 6217c478bd9Sstevel@tonic-gate */ 6227c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 6237c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 6247c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 6257c478bd9Sstevel@tonic-gate return; 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate /* 6287c478bd9Sstevel@tonic-gate * Pull in the value of the attribute. 6297c478bd9Sstevel@tonic-gate */ 6307c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 6317c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 6327c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 6337c478bd9Sstevel@tonic-gate return; 6347c478bd9Sstevel@tonic-gate } 6357c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 6367c478bd9Sstevel@tonic-gate /* 6377c478bd9Sstevel@tonic-gate * If the attribute defined the ctlr... 6387c478bd9Sstevel@tonic-gate */ 6397c478bd9Sstevel@tonic-gate if (strcmp(ident, "ctlr") == 0) { 6407c478bd9Sstevel@tonic-gate /* 6417c478bd9Sstevel@tonic-gate * Match the value with a ctlr type. 6427c478bd9Sstevel@tonic-gate */ 6437c478bd9Sstevel@tonic-gate mlp = controlp; 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate while (mlp != NULL) { 6467c478bd9Sstevel@tonic-gate if (strcmp(mlp->ctlr_type->ctype_name, 6477c478bd9Sstevel@tonic-gate cleaned) == 0) 6487c478bd9Sstevel@tonic-gate break; 6497c478bd9Sstevel@tonic-gate mlp = mlp->next; 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate /* 6527c478bd9Sstevel@tonic-gate * If we couldn't match it, it's an error. 6537c478bd9Sstevel@tonic-gate */ 6547c478bd9Sstevel@tonic-gate if (mlp == NULL) { 6557c478bd9Sstevel@tonic-gate for (i = 0; i < OTHER_CTLRS; i++) { 6567c478bd9Sstevel@tonic-gate if (strcmp(other_ctlrs[i], cleaned) 6577c478bd9Sstevel@tonic-gate == 0) { 6587c478bd9Sstevel@tonic-gate datafile_error(NULL, NULL); 6597c478bd9Sstevel@tonic-gate return; 6607c478bd9Sstevel@tonic-gate } 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate if (i == OTHER_CTLRS) { 6637c478bd9Sstevel@tonic-gate datafile_error("Unknown controller '%s'", 6647c478bd9Sstevel@tonic-gate cleaned); 6657c478bd9Sstevel@tonic-gate return; 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate /* 6697c478bd9Sstevel@tonic-gate * Found a match. Add this disk type to the list 6707c478bd9Sstevel@tonic-gate * for the ctlr type if we can complete the 6717c478bd9Sstevel@tonic-gate * disk specification correctly. 6727c478bd9Sstevel@tonic-gate */ 6737c478bd9Sstevel@tonic-gate ctype = mlp->ctlr_type; 6747c478bd9Sstevel@tonic-gate flags |= SUP_CTLR; 6757c478bd9Sstevel@tonic-gate continue; 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate /* 6787c478bd9Sstevel@tonic-gate * All other attributes require a numeric value. Convert 6797c478bd9Sstevel@tonic-gate * the value to a number. 6807c478bd9Sstevel@tonic-gate */ 6817c478bd9Sstevel@tonic-gate val = (int)strtol(cleaned, &ptr, 0); 6827c478bd9Sstevel@tonic-gate if (*ptr != '\0') { 6837c478bd9Sstevel@tonic-gate datafile_error("Expecting an integer, found '%s'", 6847c478bd9Sstevel@tonic-gate cleaned); 6857c478bd9Sstevel@tonic-gate return; 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate /* 6887c478bd9Sstevel@tonic-gate * Figure out which attribute it was and fill in the 6897c478bd9Sstevel@tonic-gate * appropriate value. Also note that the attribute 6907c478bd9Sstevel@tonic-gate * has been defined. 6917c478bd9Sstevel@tonic-gate */ 6927c478bd9Sstevel@tonic-gate if (strcmp(ident, "ncyl") == 0) { 6937c478bd9Sstevel@tonic-gate dtype->dtype_ncyl = val; 6947c478bd9Sstevel@tonic-gate flags |= SUP_NCYL; 6957c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "acyl") == 0) { 6967c478bd9Sstevel@tonic-gate dtype->dtype_acyl = val; 6977c478bd9Sstevel@tonic-gate flags |= SUP_ACYL; 6987c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "pcyl") == 0) { 6997c478bd9Sstevel@tonic-gate dtype->dtype_pcyl = val; 7007c478bd9Sstevel@tonic-gate flags |= SUP_PCYL; 7017c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "nhead") == 0) { 7027c478bd9Sstevel@tonic-gate dtype->dtype_nhead = val; 7037c478bd9Sstevel@tonic-gate flags |= SUP_NHEAD; 7047c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "nsect") == 0) { 7057c478bd9Sstevel@tonic-gate dtype->dtype_nsect = val; 7067c478bd9Sstevel@tonic-gate flags |= SUP_NSECT; 7077c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "rpm") == 0) { 7087c478bd9Sstevel@tonic-gate dtype->dtype_rpm = val; 7097c478bd9Sstevel@tonic-gate flags |= SUP_RPM; 7107c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "bpt") == 0) { 7117c478bd9Sstevel@tonic-gate dtype->dtype_bpt = val; 7127c478bd9Sstevel@tonic-gate flags |= SUP_BPT; 7137c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "bps") == 0) { 7147c478bd9Sstevel@tonic-gate dtype->dtype_bps = val; 7157c478bd9Sstevel@tonic-gate flags |= SUP_BPS; 7167c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "drive_type") == 0) { 7177c478bd9Sstevel@tonic-gate dtype->dtype_dr_type = val; 7187c478bd9Sstevel@tonic-gate flags |= SUP_DRTYPE; 7197c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "cache") == 0) { 7207c478bd9Sstevel@tonic-gate dtype->dtype_cache = val; 7217c478bd9Sstevel@tonic-gate flags |= SUP_CACHE; 7227c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "prefetch") == 0) { 7237c478bd9Sstevel@tonic-gate dtype->dtype_threshold = val; 7247c478bd9Sstevel@tonic-gate flags |= SUP_PREFETCH; 7257c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "read_retries") == 0) { 7267c478bd9Sstevel@tonic-gate dtype->dtype_read_retries = val; 7277c478bd9Sstevel@tonic-gate flags |= SUP_READ_RETRIES; 7287c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "write_retries") == 0) { 7297c478bd9Sstevel@tonic-gate dtype->dtype_write_retries = val; 7307c478bd9Sstevel@tonic-gate flags |= SUP_WRITE_RETRIES; 7317c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "min_prefetch") == 0) { 7327c478bd9Sstevel@tonic-gate dtype->dtype_prefetch_min = val; 7337c478bd9Sstevel@tonic-gate flags |= SUP_CACHE_MIN; 7347c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "max_prefetch") == 0) { 7357c478bd9Sstevel@tonic-gate dtype->dtype_prefetch_max = val; 7367c478bd9Sstevel@tonic-gate flags |= SUP_CACHE_MAX; 7377c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "trks_zone") == 0) { 7387c478bd9Sstevel@tonic-gate dtype->dtype_trks_zone = val; 7397c478bd9Sstevel@tonic-gate flags |= SUP_TRKS_ZONE; 7407c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "atrks") == 0) { 7417c478bd9Sstevel@tonic-gate dtype->dtype_atrks = val; 7427c478bd9Sstevel@tonic-gate flags |= SUP_ATRKS; 7437c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "asect") == 0) { 7447c478bd9Sstevel@tonic-gate dtype->dtype_asect = val; 7457c478bd9Sstevel@tonic-gate flags |= SUP_ASECT; 7467c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "psect") == 0) { 7477c478bd9Sstevel@tonic-gate dtype->dtype_psect = val; 7487c478bd9Sstevel@tonic-gate flags |= SUP_PSECT; 7497c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "phead") == 0) { 7507c478bd9Sstevel@tonic-gate dtype->dtype_phead = val; 7517c478bd9Sstevel@tonic-gate flags |= SUP_PHEAD; 7527c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "fmt_time") == 0) { 7537c478bd9Sstevel@tonic-gate dtype->dtype_fmt_time = val; 7547c478bd9Sstevel@tonic-gate flags |= SUP_FMTTIME; 7557c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "cyl_skew") == 0) { 7567c478bd9Sstevel@tonic-gate dtype->dtype_cyl_skew = val; 7577c478bd9Sstevel@tonic-gate flags |= SUP_CYLSKEW; 7587c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "trk_skew") == 0) { 7597c478bd9Sstevel@tonic-gate dtype->dtype_trk_skew = val; 7607c478bd9Sstevel@tonic-gate flags |= SUP_TRKSKEW; 7617c478bd9Sstevel@tonic-gate } else { 7627c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate /* 7667c478bd9Sstevel@tonic-gate * Check to be sure all the necessary attributes have been defined. 7677c478bd9Sstevel@tonic-gate * If any are missing, it's an error. Also, log options for later 7687c478bd9Sstevel@tonic-gate * use by specific driver. 7697c478bd9Sstevel@tonic-gate */ 7707c478bd9Sstevel@tonic-gate dtype->dtype_options = flags; 7717c478bd9Sstevel@tonic-gate if ((flags & SUP_MIN_DRIVE) != SUP_MIN_DRIVE) { 7727c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 7737c478bd9Sstevel@tonic-gate return; 7747c478bd9Sstevel@tonic-gate } 7757c478bd9Sstevel@tonic-gate if ((!(ctype->ctype_flags & CF_SCSI)) && (!(flags & SUP_BPT)) && 7767c478bd9Sstevel@tonic-gate (!(ctype->ctype_flags & CF_NOFORMAT))) { 7777c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 7787c478bd9Sstevel@tonic-gate return; 7797c478bd9Sstevel@tonic-gate } 7807c478bd9Sstevel@tonic-gate if ((ctype->ctype_flags & CF_SMD_DEFS) && (!(flags & SUP_BPS))) { 7817c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 7827c478bd9Sstevel@tonic-gate return; 7837c478bd9Sstevel@tonic-gate } 7847c478bd9Sstevel@tonic-gate /* 7857c478bd9Sstevel@tonic-gate * Add this disk type to the list for the ctlr type 7867c478bd9Sstevel@tonic-gate */ 7877c478bd9Sstevel@tonic-gate assert(flags & SUP_CTLR); 7887c478bd9Sstevel@tonic-gate type = ctype->ctype_dlist; 7897c478bd9Sstevel@tonic-gate if (type == NULL) { 7907c478bd9Sstevel@tonic-gate ctype->ctype_dlist = dtype; 7917c478bd9Sstevel@tonic-gate } else { 7927c478bd9Sstevel@tonic-gate while (type->dtype_next != NULL) 7937c478bd9Sstevel@tonic-gate type = type->dtype_next; 7947c478bd9Sstevel@tonic-gate type->dtype_next = dtype; 7957c478bd9Sstevel@tonic-gate } 7967c478bd9Sstevel@tonic-gate } 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate 7997c478bd9Sstevel@tonic-gate /* 8007c478bd9Sstevel@tonic-gate * Parse a SCSI mode page change specification. 8017c478bd9Sstevel@tonic-gate * 8027c478bd9Sstevel@tonic-gate * Return: 8037c478bd9Sstevel@tonic-gate * 0: not change specification, continue parsing 8047c478bd9Sstevel@tonic-gate * 1: was change specification, it was ok, 8057c478bd9Sstevel@tonic-gate * or we already handled the error. 8067c478bd9Sstevel@tonic-gate */ 8077c478bd9Sstevel@tonic-gate static int 8087c478bd9Sstevel@tonic-gate sup_change_spec(struct disk_type *disk, char *id) 8097c478bd9Sstevel@tonic-gate { 8107c478bd9Sstevel@tonic-gate char *p; 8117c478bd9Sstevel@tonic-gate char *p2; 8127c478bd9Sstevel@tonic-gate int pageno; 8137c478bd9Sstevel@tonic-gate int byteno; 8147c478bd9Sstevel@tonic-gate int mode; 8157c478bd9Sstevel@tonic-gate int value; 8167c478bd9Sstevel@tonic-gate TOKEN token; 8177c478bd9Sstevel@tonic-gate TOKEN ident; 8187c478bd9Sstevel@tonic-gate struct chg_list *cp; 8197c478bd9Sstevel@tonic-gate int tilde; 8207c478bd9Sstevel@tonic-gate int i; 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate /* 8237c478bd9Sstevel@tonic-gate * Syntax: p[<nn>|0x<xx>] 8247c478bd9Sstevel@tonic-gate */ 8257c478bd9Sstevel@tonic-gate if (*id != 'p') { 8267c478bd9Sstevel@tonic-gate return (0); 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate pageno = (int)strtol(id+1, &p2, 0); 8297c478bd9Sstevel@tonic-gate if (*p2 != 0) { 8307c478bd9Sstevel@tonic-gate return (0); 8317c478bd9Sstevel@tonic-gate } 8327c478bd9Sstevel@tonic-gate /* 8337c478bd9Sstevel@tonic-gate * Once we get this far, we know we have the 8347c478bd9Sstevel@tonic-gate * beginnings of a change specification. 8357c478bd9Sstevel@tonic-gate * If there's a problem now, report the problem, 8367c478bd9Sstevel@tonic-gate * and return 1, so that the caller can restart 8377c478bd9Sstevel@tonic-gate * parsing at the next expression. 8387c478bd9Sstevel@tonic-gate */ 8397c478bd9Sstevel@tonic-gate if (!scsi_supported_page(pageno)) { 8407c478bd9Sstevel@tonic-gate datafile_error("Unsupported mode page '%s'", id); 8417c478bd9Sstevel@tonic-gate return (1); 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate /* 8447c478bd9Sstevel@tonic-gate * Next token should be the byte offset 8457c478bd9Sstevel@tonic-gate */ 8467c478bd9Sstevel@tonic-gate if (sup_gettoken(token) != SUP_STRING) { 8477c478bd9Sstevel@tonic-gate datafile_error("Unexpected value '%s'", token); 8487c478bd9Sstevel@tonic-gate return (1); 8497c478bd9Sstevel@tonic-gate } 8507c478bd9Sstevel@tonic-gate clean_token(ident, token); 8517c478bd9Sstevel@tonic-gate 8527c478bd9Sstevel@tonic-gate /* 8537c478bd9Sstevel@tonic-gate * Syntax: b[<nn>|0x<xx>] 8547c478bd9Sstevel@tonic-gate */ 8557c478bd9Sstevel@tonic-gate p = ident; 8567c478bd9Sstevel@tonic-gate if (*p++ != 'b') { 8577c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 8587c478bd9Sstevel@tonic-gate return (1); 8597c478bd9Sstevel@tonic-gate } 8607c478bd9Sstevel@tonic-gate byteno = (int)strtol(p, &p2, 10); 8617c478bd9Sstevel@tonic-gate if (*p2 != 0) { 8627c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 8637c478bd9Sstevel@tonic-gate return (1); 8647c478bd9Sstevel@tonic-gate } 8657c478bd9Sstevel@tonic-gate if (byteno == 0 || byteno == 1) { 8667c478bd9Sstevel@tonic-gate datafile_error("Unsupported byte offset '%s'", ident); 8677c478bd9Sstevel@tonic-gate return (1); 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate /* 8717c478bd9Sstevel@tonic-gate * Get the operator for this expression 8727c478bd9Sstevel@tonic-gate */ 8737c478bd9Sstevel@tonic-gate mode = CHG_MODE_UNDEFINED; 8747c478bd9Sstevel@tonic-gate switch (sup_gettoken(token)) { 8757c478bd9Sstevel@tonic-gate case SUP_EQL: 8767c478bd9Sstevel@tonic-gate mode = CHG_MODE_ABS; 8777c478bd9Sstevel@tonic-gate break; 8787c478bd9Sstevel@tonic-gate case SUP_OR: 8797c478bd9Sstevel@tonic-gate if (sup_gettoken(token) == SUP_EQL) 8807c478bd9Sstevel@tonic-gate mode = CHG_MODE_SET; 8817c478bd9Sstevel@tonic-gate break; 8827c478bd9Sstevel@tonic-gate case SUP_AND: 8837c478bd9Sstevel@tonic-gate if (sup_gettoken(token) == SUP_EQL) 8847c478bd9Sstevel@tonic-gate mode = CHG_MODE_CLR; 8857c478bd9Sstevel@tonic-gate break; 8867c478bd9Sstevel@tonic-gate } 8877c478bd9Sstevel@tonic-gate if (mode == CHG_MODE_UNDEFINED) { 8887c478bd9Sstevel@tonic-gate datafile_error("Unexpected operator: '%s'", token); 8897c478bd9Sstevel@tonic-gate return (1); 8907c478bd9Sstevel@tonic-gate } 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate /* 8937c478bd9Sstevel@tonic-gate * Get right-hand of expression - accept optional tilde 8947c478bd9Sstevel@tonic-gate */ 8957c478bd9Sstevel@tonic-gate tilde = 0; 8967c478bd9Sstevel@tonic-gate if ((i = sup_gettoken(token)) == SUP_TILDE) { 8977c478bd9Sstevel@tonic-gate tilde = 1; 8987c478bd9Sstevel@tonic-gate i = sup_gettoken(token); 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate if (i != SUP_STRING) { 9017c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 9027c478bd9Sstevel@tonic-gate return (1); 9037c478bd9Sstevel@tonic-gate } 9047c478bd9Sstevel@tonic-gate clean_token(ident, token); 9057c478bd9Sstevel@tonic-gate value = (int)strtol(ident, &p, 0); 9067c478bd9Sstevel@tonic-gate if (*p != 0) { 9077c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 9087c478bd9Sstevel@tonic-gate return (1); 9097c478bd9Sstevel@tonic-gate } 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate /* 9127c478bd9Sstevel@tonic-gate * Apply the tilde operator, if found. 9137c478bd9Sstevel@tonic-gate * Constrain to a byte value. 9147c478bd9Sstevel@tonic-gate */ 9157c478bd9Sstevel@tonic-gate if (tilde) { 9167c478bd9Sstevel@tonic-gate value = ~value; 9177c478bd9Sstevel@tonic-gate } 9187c478bd9Sstevel@tonic-gate value &= 0xff; 9197c478bd9Sstevel@tonic-gate 9207c478bd9Sstevel@tonic-gate /* 9217c478bd9Sstevel@tonic-gate * We parsed a successful change specification expression. 9227c478bd9Sstevel@tonic-gate * Add it to the list for this disk type. 9237c478bd9Sstevel@tonic-gate */ 9247c478bd9Sstevel@tonic-gate cp = new_chg_list(disk); 9257c478bd9Sstevel@tonic-gate cp->pageno = pageno; 9267c478bd9Sstevel@tonic-gate cp->byteno = byteno; 9277c478bd9Sstevel@tonic-gate cp->mode = mode; 9287c478bd9Sstevel@tonic-gate cp->value = value; 9297c478bd9Sstevel@tonic-gate return (1); 9307c478bd9Sstevel@tonic-gate } 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate /* 9347c478bd9Sstevel@tonic-gate * This routine processes a 'partition' line in the data file. It defines 9357c478bd9Sstevel@tonic-gate * a known partition map for a particular disk type on a particular 9367c478bd9Sstevel@tonic-gate * controller type. 9377c478bd9Sstevel@tonic-gate */ 9387c478bd9Sstevel@tonic-gate static void 9397c478bd9Sstevel@tonic-gate sup_setpart() 9407c478bd9Sstevel@tonic-gate { 9417c478bd9Sstevel@tonic-gate TOKEN token, cleaned, disk, ctlr, ident; 9427c478bd9Sstevel@tonic-gate struct disk_type *dtype = NULL; 9437c478bd9Sstevel@tonic-gate struct ctlr_type *ctype = NULL; 9447c478bd9Sstevel@tonic-gate struct partition_info *pinfo, *parts; 9457c478bd9Sstevel@tonic-gate char *pinfo_name; 9467c478bd9Sstevel@tonic-gate int i, index, status, val1, val2, flags = 0; 9477c478bd9Sstevel@tonic-gate ushort_t vtoc_tag; 9487c478bd9Sstevel@tonic-gate ushort_t vtoc_flag; 9497c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 9507c478bd9Sstevel@tonic-gate 9517c478bd9Sstevel@tonic-gate /* 9527c478bd9Sstevel@tonic-gate * Pull in some grammar. 9537c478bd9Sstevel@tonic-gate */ 9547c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 9557c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 9567c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 9577c478bd9Sstevel@tonic-gate return; 9587c478bd9Sstevel@tonic-gate } 9597c478bd9Sstevel@tonic-gate /* 9607c478bd9Sstevel@tonic-gate * Pull in the name of the map. 9617c478bd9Sstevel@tonic-gate */ 9627c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 9637c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 9647c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 9657c478bd9Sstevel@tonic-gate return; 9667c478bd9Sstevel@tonic-gate } 9677c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 9687c478bd9Sstevel@tonic-gate /* 9697c478bd9Sstevel@tonic-gate * Allocate space for the partition map and fill in the name. 9707c478bd9Sstevel@tonic-gate */ 9717c478bd9Sstevel@tonic-gate pinfo_name = (char *)zalloc(strlen(cleaned) + 1); 9727c478bd9Sstevel@tonic-gate (void) strcpy(pinfo_name, cleaned); 9737c478bd9Sstevel@tonic-gate pinfo = (struct partition_info *)zalloc(sizeof (struct partition_info)); 9747c478bd9Sstevel@tonic-gate pinfo->pinfo_name = pinfo_name; 9757c478bd9Sstevel@tonic-gate /* 9767c478bd9Sstevel@tonic-gate * Save the filename/linenumber where this partition was defined 9777c478bd9Sstevel@tonic-gate */ 9787c478bd9Sstevel@tonic-gate pinfo->pinfo_filename = file_name; 9797c478bd9Sstevel@tonic-gate pinfo->pinfo_lineno = data_lineno; 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate /* 9827c478bd9Sstevel@tonic-gate * Install default vtoc information into the new partition table 9837c478bd9Sstevel@tonic-gate */ 9847c478bd9Sstevel@tonic-gate set_vtoc_defaults(pinfo); 9857c478bd9Sstevel@tonic-gate 9867c478bd9Sstevel@tonic-gate /* 9877c478bd9Sstevel@tonic-gate * Loop for each attribute in the line. 9887c478bd9Sstevel@tonic-gate */ 9897c478bd9Sstevel@tonic-gate for (;;) { 9907c478bd9Sstevel@tonic-gate /* 9917c478bd9Sstevel@tonic-gate * Pull in some grammar. 9927c478bd9Sstevel@tonic-gate */ 9937c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 9947c478bd9Sstevel@tonic-gate /* 9957c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 9967c478bd9Sstevel@tonic-gate */ 9977c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 9987c478bd9Sstevel@tonic-gate break; 9997c478bd9Sstevel@tonic-gate if (status != SUP_COLON) { 10007c478bd9Sstevel@tonic-gate datafile_error("Expecting ':', found '%s'", token); 10017c478bd9Sstevel@tonic-gate return; 10027c478bd9Sstevel@tonic-gate } 10037c478bd9Sstevel@tonic-gate /* 10047c478bd9Sstevel@tonic-gate * Pull in the attribute. 10057c478bd9Sstevel@tonic-gate */ 10067c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 10077c478bd9Sstevel@tonic-gate /* 10087c478bd9Sstevel@tonic-gate * If we hit end of line, we're done. 10097c478bd9Sstevel@tonic-gate */ 10107c478bd9Sstevel@tonic-gate if (status == SUP_EOL) 10117c478bd9Sstevel@tonic-gate break; 10127c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 10137c478bd9Sstevel@tonic-gate datafile_error("Expecting keyword, found '%s'", token); 10147c478bd9Sstevel@tonic-gate return; 10157c478bd9Sstevel@tonic-gate } 10167c478bd9Sstevel@tonic-gate clean_token(ident, token); 10177c478bd9Sstevel@tonic-gate /* 10187c478bd9Sstevel@tonic-gate * Pull in more grammar. 10197c478bd9Sstevel@tonic-gate */ 10207c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 10217c478bd9Sstevel@tonic-gate if (status != SUP_EQL) { 10227c478bd9Sstevel@tonic-gate datafile_error("Expecting '=', found '%s'", token); 10237c478bd9Sstevel@tonic-gate return; 10247c478bd9Sstevel@tonic-gate } 10257c478bd9Sstevel@tonic-gate /* 10267c478bd9Sstevel@tonic-gate * Pull in the value of the attribute. 10277c478bd9Sstevel@tonic-gate */ 10287c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 10297c478bd9Sstevel@tonic-gate /* 10307c478bd9Sstevel@tonic-gate * If we hit a key character, it's an error. 10317c478bd9Sstevel@tonic-gate */ 10327c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 10337c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 10347c478bd9Sstevel@tonic-gate return; 10357c478bd9Sstevel@tonic-gate } 10367c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 10377c478bd9Sstevel@tonic-gate /* 10387c478bd9Sstevel@tonic-gate * If the attribute is the ctlr, save the ctlr name and 10397c478bd9Sstevel@tonic-gate * mark it defined. 10407c478bd9Sstevel@tonic-gate */ 10417c478bd9Sstevel@tonic-gate if (strcmp(ident, "ctlr") == 0) { 10427c478bd9Sstevel@tonic-gate (void) strcpy(ctlr, cleaned); 10437c478bd9Sstevel@tonic-gate flags |= SUP_CTLR; 10447c478bd9Sstevel@tonic-gate continue; 10457c478bd9Sstevel@tonic-gate /* 10467c478bd9Sstevel@tonic-gate * If the attribute is the disk, save the disk name and 10477c478bd9Sstevel@tonic-gate * mark it defined. 10487c478bd9Sstevel@tonic-gate */ 10497c478bd9Sstevel@tonic-gate } else if (strcmp(ident, "disk") == 0) { 10507c478bd9Sstevel@tonic-gate (void) strcpy(disk, cleaned); 10517c478bd9Sstevel@tonic-gate flags |= SUP_DISK; 10527c478bd9Sstevel@tonic-gate continue; 10537c478bd9Sstevel@tonic-gate } 10547c478bd9Sstevel@tonic-gate /* 10557c478bd9Sstevel@tonic-gate * If we now know both the controller name and the 10567c478bd9Sstevel@tonic-gate * disk name, let's see if we can find the controller 10577c478bd9Sstevel@tonic-gate * and disk type. This will give us the geometry, 10587c478bd9Sstevel@tonic-gate * which can permit us to accept partitions specs 10597c478bd9Sstevel@tonic-gate * in cylinders or blocks. 10607c478bd9Sstevel@tonic-gate */ 10617c478bd9Sstevel@tonic-gate if (((flags & (SUP_DISK|SUP_CTLR)) == (SUP_DISK|SUP_CTLR)) && 10627c478bd9Sstevel@tonic-gate dtype == NULL && ctype == NULL) { 10637c478bd9Sstevel@tonic-gate /* 10647c478bd9Sstevel@tonic-gate * Attempt to match the specified ctlr to a known type. 10657c478bd9Sstevel@tonic-gate */ 10667c478bd9Sstevel@tonic-gate mlp = controlp; 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate while (mlp != NULL) { 10697c478bd9Sstevel@tonic-gate if (strcmp(mlp->ctlr_type->ctype_name, 10707c478bd9Sstevel@tonic-gate ctlr) == 0) 10717c478bd9Sstevel@tonic-gate break; 10727c478bd9Sstevel@tonic-gate mlp = mlp->next; 10737c478bd9Sstevel@tonic-gate } 10747c478bd9Sstevel@tonic-gate /* 10757c478bd9Sstevel@tonic-gate * If no match is found, it's an error. 10767c478bd9Sstevel@tonic-gate */ 10777c478bd9Sstevel@tonic-gate if (mlp == NULL) { 10787c478bd9Sstevel@tonic-gate for (i = 0; i < OTHER_CTLRS; i++) { 10797c478bd9Sstevel@tonic-gate if (strcmp(other_ctlrs[i], ctlr) == 0) { 10807c478bd9Sstevel@tonic-gate datafile_error(NULL, NULL); 10817c478bd9Sstevel@tonic-gate return; 10827c478bd9Sstevel@tonic-gate } 10837c478bd9Sstevel@tonic-gate } 10847c478bd9Sstevel@tonic-gate if (i == OTHER_CTLRS) { 10857c478bd9Sstevel@tonic-gate datafile_error( 10867c478bd9Sstevel@tonic-gate "Unknown controller '%s'", ctlr); 10877c478bd9Sstevel@tonic-gate return; 10887c478bd9Sstevel@tonic-gate } 10897c478bd9Sstevel@tonic-gate } 10907c478bd9Sstevel@tonic-gate ctype = mlp->ctlr_type; 10917c478bd9Sstevel@tonic-gate /* 10927c478bd9Sstevel@tonic-gate * Attempt to match the specified disk to a known type. 10937c478bd9Sstevel@tonic-gate */ 10947c478bd9Sstevel@tonic-gate for (dtype = ctype->ctype_dlist; dtype != NULL; 10957c478bd9Sstevel@tonic-gate dtype = dtype->dtype_next) { 10967c478bd9Sstevel@tonic-gate if (strcmp(dtype->dtype_asciilabel, disk) == 0) 10977c478bd9Sstevel@tonic-gate break; 10987c478bd9Sstevel@tonic-gate } 10997c478bd9Sstevel@tonic-gate /* 11007c478bd9Sstevel@tonic-gate * If no match is found, it's an error. 11017c478bd9Sstevel@tonic-gate */ 11027c478bd9Sstevel@tonic-gate if (dtype == NULL) { 11037c478bd9Sstevel@tonic-gate datafile_error("Unknown disk '%s'", disk); 11047c478bd9Sstevel@tonic-gate return; 11057c478bd9Sstevel@tonic-gate } 11067c478bd9Sstevel@tonic-gate /* 11077c478bd9Sstevel@tonic-gate * Now that we know the disk type, set up the 11087c478bd9Sstevel@tonic-gate * globals that let that magic macro "spc()" 11097c478bd9Sstevel@tonic-gate * do it's thing. Sorry that this is glued 11107c478bd9Sstevel@tonic-gate * together so poorly... 11117c478bd9Sstevel@tonic-gate */ 11127c478bd9Sstevel@tonic-gate nhead = dtype->dtype_nhead; 11137c478bd9Sstevel@tonic-gate nsect = dtype->dtype_nsect; 11147c478bd9Sstevel@tonic-gate acyl = dtype->dtype_acyl; 11157c478bd9Sstevel@tonic-gate ncyl = dtype->dtype_ncyl; 11167c478bd9Sstevel@tonic-gate } 11177c478bd9Sstevel@tonic-gate /* 11187c478bd9Sstevel@tonic-gate * By now, the disk and controller type must be defined 11197c478bd9Sstevel@tonic-gate */ 11207c478bd9Sstevel@tonic-gate if (dtype == NULL || ctype == NULL) { 11217c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 11227c478bd9Sstevel@tonic-gate return; 11237c478bd9Sstevel@tonic-gate } 11247c478bd9Sstevel@tonic-gate /* 11257c478bd9Sstevel@tonic-gate * The rest of the attributes are all single letters. 11267c478bd9Sstevel@tonic-gate * Make sure the specified attribute is a single letter. 11277c478bd9Sstevel@tonic-gate */ 11287c478bd9Sstevel@tonic-gate if (strlen(ident) != 1) { 11297c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 11307c478bd9Sstevel@tonic-gate return; 11317c478bd9Sstevel@tonic-gate } 11327c478bd9Sstevel@tonic-gate /* 11337c478bd9Sstevel@tonic-gate * Also make sure it is within the legal range of letters. 11347c478bd9Sstevel@tonic-gate */ 11357c478bd9Sstevel@tonic-gate if (ident[0] < PARTITION_BASE || ident[0] > PARTITION_BASE+9) { 11367c478bd9Sstevel@tonic-gate datafile_error("Unknown keyword '%s'", ident); 11377c478bd9Sstevel@tonic-gate return; 11387c478bd9Sstevel@tonic-gate } 11397c478bd9Sstevel@tonic-gate /* 11407c478bd9Sstevel@tonic-gate * Here's the index of the partition we're dealing with 11417c478bd9Sstevel@tonic-gate */ 11427c478bd9Sstevel@tonic-gate index = ident[0] - PARTITION_BASE; 11437c478bd9Sstevel@tonic-gate /* 11447c478bd9Sstevel@tonic-gate * For SunOS 5.0, we support the additional syntax: 11457c478bd9Sstevel@tonic-gate * [<tag>, ] [<flag>, ] <start>, <end> 11467c478bd9Sstevel@tonic-gate * instead of: 11477c478bd9Sstevel@tonic-gate * <start>, <end> 11487c478bd9Sstevel@tonic-gate * 11497c478bd9Sstevel@tonic-gate * <tag> may be one of: boot, root, swap, etc. 11507c478bd9Sstevel@tonic-gate * <flag> consists of two characters: 11517c478bd9Sstevel@tonic-gate * W (writable) or R (read-only) 11527c478bd9Sstevel@tonic-gate * M (mountable) or U (unmountable) 11537c478bd9Sstevel@tonic-gate * 11547c478bd9Sstevel@tonic-gate * Start with the defaults assigned above: 11557c478bd9Sstevel@tonic-gate */ 11567c478bd9Sstevel@tonic-gate vtoc_tag = pinfo->vtoc.v_part[index].p_tag; 11577c478bd9Sstevel@tonic-gate vtoc_flag = pinfo->vtoc.v_part[index].p_flag; 11587c478bd9Sstevel@tonic-gate 11597c478bd9Sstevel@tonic-gate /* 11607c478bd9Sstevel@tonic-gate * First try to match token against possible tag values 11617c478bd9Sstevel@tonic-gate */ 11627c478bd9Sstevel@tonic-gate if (find_value(ptag_choices, cleaned, &i) == 1) { 11637c478bd9Sstevel@tonic-gate /* 11647c478bd9Sstevel@tonic-gate * Found valid tag. Use it and advance parser 11657c478bd9Sstevel@tonic-gate */ 11667c478bd9Sstevel@tonic-gate vtoc_tag = (ushort_t)i; 11677c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 11687c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 11697c478bd9Sstevel@tonic-gate datafile_error( 11707c478bd9Sstevel@tonic-gate "Expecting ', ', found '%s'", 11717c478bd9Sstevel@tonic-gate token); 11727c478bd9Sstevel@tonic-gate return; 11737c478bd9Sstevel@tonic-gate } 11747c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 11757c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 11767c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", 11777c478bd9Sstevel@tonic-gate token); 11787c478bd9Sstevel@tonic-gate return; 11797c478bd9Sstevel@tonic-gate } 11807c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 11817c478bd9Sstevel@tonic-gate } 11827c478bd9Sstevel@tonic-gate 11837c478bd9Sstevel@tonic-gate /* 11847c478bd9Sstevel@tonic-gate * Try to match token against possible flag values 11857c478bd9Sstevel@tonic-gate */ 11867c478bd9Sstevel@tonic-gate if (find_value(pflag_choices, cleaned, &i) == 1) { 11877c478bd9Sstevel@tonic-gate /* 11887c478bd9Sstevel@tonic-gate * Found valid flag. Use it and advance parser 11897c478bd9Sstevel@tonic-gate */ 11907c478bd9Sstevel@tonic-gate vtoc_flag = (ushort_t)i; 11917c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 11927c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 11937c478bd9Sstevel@tonic-gate datafile_error("Expecting ', ', found '%s'", 11947c478bd9Sstevel@tonic-gate token); 11957c478bd9Sstevel@tonic-gate return; 11967c478bd9Sstevel@tonic-gate } 11977c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 11987c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 11997c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", 12007c478bd9Sstevel@tonic-gate token); 12017c478bd9Sstevel@tonic-gate return; 12027c478bd9Sstevel@tonic-gate } 12037c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 12047c478bd9Sstevel@tonic-gate } 12057c478bd9Sstevel@tonic-gate /* 12067c478bd9Sstevel@tonic-gate * All other attributes have a pair of numeric values. 12077c478bd9Sstevel@tonic-gate * Convert the first value to a number. This value 12087c478bd9Sstevel@tonic-gate * is the starting cylinder number of the partition. 12097c478bd9Sstevel@tonic-gate */ 12107c478bd9Sstevel@tonic-gate val1 = str2cyls(cleaned); 12117c478bd9Sstevel@tonic-gate if (val1 == -1) { 12127c478bd9Sstevel@tonic-gate datafile_error("Expecting an integer, found '%s'", 12137c478bd9Sstevel@tonic-gate cleaned); 12147c478bd9Sstevel@tonic-gate return; 12157c478bd9Sstevel@tonic-gate } 12167c478bd9Sstevel@tonic-gate /* 12177c478bd9Sstevel@tonic-gate * Pull in some grammar. 12187c478bd9Sstevel@tonic-gate */ 12197c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 12207c478bd9Sstevel@tonic-gate if (status != SUP_COMMA) { 12217c478bd9Sstevel@tonic-gate datafile_error("Expecting ', ', found '%s'", token); 12227c478bd9Sstevel@tonic-gate return; 12237c478bd9Sstevel@tonic-gate } 12247c478bd9Sstevel@tonic-gate /* 12257c478bd9Sstevel@tonic-gate * Pull in the second value. 12267c478bd9Sstevel@tonic-gate */ 12277c478bd9Sstevel@tonic-gate status = sup_gettoken(token); 12287c478bd9Sstevel@tonic-gate if (status != SUP_STRING) { 12297c478bd9Sstevel@tonic-gate datafile_error("Expecting value, found '%s'", token); 12307c478bd9Sstevel@tonic-gate return; 12317c478bd9Sstevel@tonic-gate } 12327c478bd9Sstevel@tonic-gate clean_token(cleaned, token); 12337c478bd9Sstevel@tonic-gate /* 12347c478bd9Sstevel@tonic-gate * Convert the second value to a number. This value 12357c478bd9Sstevel@tonic-gate * is the number of blocks composing the partition. 12367c478bd9Sstevel@tonic-gate * If the token is terminated with a 'c', the units 12377c478bd9Sstevel@tonic-gate * are cylinders, not blocks. Also accept a 'b', if 12387c478bd9Sstevel@tonic-gate * they choose to be so specific. 12397c478bd9Sstevel@tonic-gate */ 12407c478bd9Sstevel@tonic-gate val2 = str2blks(cleaned); 12417c478bd9Sstevel@tonic-gate if (val2 == -1) { 12427c478bd9Sstevel@tonic-gate datafile_error("Expecting an integer, found '%s'", 12437c478bd9Sstevel@tonic-gate cleaned); 12447c478bd9Sstevel@tonic-gate return; 12457c478bd9Sstevel@tonic-gate } 12467c478bd9Sstevel@tonic-gate /* 12477c478bd9Sstevel@tonic-gate * Fill in the appropriate map entry with the values. 12487c478bd9Sstevel@tonic-gate */ 12497c478bd9Sstevel@tonic-gate pinfo->pinfo_map[index].dkl_cylno = val1; 12507c478bd9Sstevel@tonic-gate pinfo->pinfo_map[index].dkl_nblk = val2; 12517c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_tag = vtoc_tag; 12527c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_flag = vtoc_flag; 12537c478bd9Sstevel@tonic-gate 12547c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16) 12557c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_start = val1 * (nhead * nsect); 12567c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_size = val2; 12577c478bd9Sstevel@tonic-gate 12587c478bd9Sstevel@tonic-gate if (val2 == 0) { 12597c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_tag = 0; 12607c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_flag = 0; 12617c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[index].p_start = 0; 12627c478bd9Sstevel@tonic-gate pinfo->pinfo_map[index].dkl_cylno = 0; 12637c478bd9Sstevel@tonic-gate } 12647c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_16) */ 12657c478bd9Sstevel@tonic-gate 12667c478bd9Sstevel@tonic-gate } 12677c478bd9Sstevel@tonic-gate /* 12687c478bd9Sstevel@tonic-gate * Check to be sure that all necessary attributes were defined. 12697c478bd9Sstevel@tonic-gate */ 12707c478bd9Sstevel@tonic-gate if ((flags & SUP_MIN_PART) != SUP_MIN_PART) { 12717c478bd9Sstevel@tonic-gate datafile_error("Incomplete specification", ""); 12727c478bd9Sstevel@tonic-gate return; 12737c478bd9Sstevel@tonic-gate } 12747c478bd9Sstevel@tonic-gate /* 12757c478bd9Sstevel@tonic-gate * Add this partition map to the list of known maps for the 12767c478bd9Sstevel@tonic-gate * specified disk/ctlr. 12777c478bd9Sstevel@tonic-gate */ 12787c478bd9Sstevel@tonic-gate parts = dtype->dtype_plist; 12797c478bd9Sstevel@tonic-gate if (parts == NULL) 12807c478bd9Sstevel@tonic-gate dtype->dtype_plist = pinfo; 12817c478bd9Sstevel@tonic-gate else { 12827c478bd9Sstevel@tonic-gate while (parts->pinfo_next != NULL) 12837c478bd9Sstevel@tonic-gate parts = parts->pinfo_next; 12847c478bd9Sstevel@tonic-gate parts->pinfo_next = pinfo; 12857c478bd9Sstevel@tonic-gate } 12867c478bd9Sstevel@tonic-gate } 12877c478bd9Sstevel@tonic-gate 12887c478bd9Sstevel@tonic-gate /* 12897c478bd9Sstevel@tonic-gate * Open the disk device - just a wrapper for open. 12907c478bd9Sstevel@tonic-gate */ 12917c478bd9Sstevel@tonic-gate int 12927c478bd9Sstevel@tonic-gate open_disk(char *diskname, int flags) 12937c478bd9Sstevel@tonic-gate { 12947c478bd9Sstevel@tonic-gate return (open(diskname, flags)); 12957c478bd9Sstevel@tonic-gate } 12967c478bd9Sstevel@tonic-gate 12977c478bd9Sstevel@tonic-gate /* 12987c478bd9Sstevel@tonic-gate * This routine performs the disk search during startup. It looks for 12997c478bd9Sstevel@tonic-gate * all the disks in the search path, and creates a list of those that 13007c478bd9Sstevel@tonic-gate * are found. 13017c478bd9Sstevel@tonic-gate */ 13027c478bd9Sstevel@tonic-gate void 13037c478bd9Sstevel@tonic-gate do_search(char *arglist[]) 13047c478bd9Sstevel@tonic-gate { 13057c478bd9Sstevel@tonic-gate char **sp; 13067c478bd9Sstevel@tonic-gate DIR *dir; 13077c478bd9Sstevel@tonic-gate struct dirent *dp; 13087c478bd9Sstevel@tonic-gate char s[MAXPATHLEN]; 13097c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 13107c478bd9Sstevel@tonic-gate char curdir[MAXPATHLEN]; 13117c478bd9Sstevel@tonic-gate char *directory = "/dev/rdsk"; 13127c478bd9Sstevel@tonic-gate struct disk_info *disk; 13137c478bd9Sstevel@tonic-gate int i; 13147c478bd9Sstevel@tonic-gate 13157c478bd9Sstevel@tonic-gate /* 13167c478bd9Sstevel@tonic-gate * Change directory to the device directory. This 13177c478bd9Sstevel@tonic-gate * gives us the most efficient access to that directory. 13187c478bd9Sstevel@tonic-gate * Remember where we were, and return there when finished. 13197c478bd9Sstevel@tonic-gate */ 13207c478bd9Sstevel@tonic-gate if (getcwd(curdir, sizeof (curdir)) == NULL) { 13217c478bd9Sstevel@tonic-gate err_print("Cannot get current directory - %s\n", 13227c478bd9Sstevel@tonic-gate strerror(errno)); 13237c478bd9Sstevel@tonic-gate fullabort(); 13247c478bd9Sstevel@tonic-gate } 13257c478bd9Sstevel@tonic-gate if (chdir(directory) == -1) { 13267c478bd9Sstevel@tonic-gate err_print("Cannot set directory to %s - %s\n", 13277c478bd9Sstevel@tonic-gate directory, strerror(errno)); 13287c478bd9Sstevel@tonic-gate fullabort(); 13297c478bd9Sstevel@tonic-gate } 13307c478bd9Sstevel@tonic-gate 13317c478bd9Sstevel@tonic-gate /* 13327c478bd9Sstevel@tonic-gate * If there were disks specified on the command line, 13337c478bd9Sstevel@tonic-gate * use those disks, and nothing but those disks. 13347c478bd9Sstevel@tonic-gate */ 13357c478bd9Sstevel@tonic-gate if (arglist != NULL) { 13367c478bd9Sstevel@tonic-gate check_for_duplicate_disknames(arglist); 13377c478bd9Sstevel@tonic-gate for (; *arglist != NULL; arglist++) { 13387c478bd9Sstevel@tonic-gate search_for_logical_dev(*arglist); 13397c478bd9Sstevel@tonic-gate } 13407c478bd9Sstevel@tonic-gate } else { 13417c478bd9Sstevel@tonic-gate /* 13427c478bd9Sstevel@tonic-gate * If there were no disks specified on the command line, 13437c478bd9Sstevel@tonic-gate * search for all disks attached to the system. 13447c478bd9Sstevel@tonic-gate */ 13457c478bd9Sstevel@tonic-gate fmt_print("Searching for disks..."); 13467c478bd9Sstevel@tonic-gate (void) fflush(stdout); 13477c478bd9Sstevel@tonic-gate need_newline = 1; 13487c478bd9Sstevel@tonic-gate 13497c478bd9Sstevel@tonic-gate /* 13507c478bd9Sstevel@tonic-gate * Find all disks specified in search_path definitions 13517c478bd9Sstevel@tonic-gate * in whatever format.dat files were processed. 13527c478bd9Sstevel@tonic-gate */ 13537c478bd9Sstevel@tonic-gate sp = search_path; 13547c478bd9Sstevel@tonic-gate if (sp != NULL) { 13557c478bd9Sstevel@tonic-gate while (*sp != NULL) { 13567c478bd9Sstevel@tonic-gate search_for_logical_dev(*sp++); 13577c478bd9Sstevel@tonic-gate } 13587c478bd9Sstevel@tonic-gate } 13597c478bd9Sstevel@tonic-gate 13607c478bd9Sstevel@tonic-gate /* 13617c478bd9Sstevel@tonic-gate * Open the device directory 13627c478bd9Sstevel@tonic-gate */ 13637c478bd9Sstevel@tonic-gate if ((dir = opendir(".")) == NULL) { 13647c478bd9Sstevel@tonic-gate err_print("Cannot open %s - %s\n", 13657c478bd9Sstevel@tonic-gate directory, strerror(errno)); 13667c478bd9Sstevel@tonic-gate fullabort(); 13677c478bd9Sstevel@tonic-gate } 13687c478bd9Sstevel@tonic-gate 13697c478bd9Sstevel@tonic-gate /* 13707c478bd9Sstevel@tonic-gate * Now find all usable nodes in /dev/rdsk (or /dev, if 4.x) 13717c478bd9Sstevel@tonic-gate * First find all nodes which do not conform to 13727c478bd9Sstevel@tonic-gate * standard disk naming conventions. This permits 13737c478bd9Sstevel@tonic-gate * all user-defined names to override the default names. 13747c478bd9Sstevel@tonic-gate */ 13757c478bd9Sstevel@tonic-gate while ((dp = readdir(dir)) != NULL) { 13767c478bd9Sstevel@tonic-gate if (strcmp(dp->d_name, ".") == 0 || 13777c478bd9Sstevel@tonic-gate strcmp(dp->d_name, "..") == 0) 13787c478bd9Sstevel@tonic-gate continue; 13797c478bd9Sstevel@tonic-gate if (!conventional_name(dp->d_name)) { 13807c478bd9Sstevel@tonic-gate if (!fdisk_physical_name(dp->d_name)) { 13817c478bd9Sstevel@tonic-gate /* 13827c478bd9Sstevel@tonic-gate * If non-conventional name represents 13837c478bd9Sstevel@tonic-gate * a link to non-s2 slice , ignore it. 13847c478bd9Sstevel@tonic-gate */ 13857c478bd9Sstevel@tonic-gate if (!name_represents_wholedisk 13867c478bd9Sstevel@tonic-gate (dp->d_name)) { 13877c478bd9Sstevel@tonic-gate (void) strcpy(path, directory); 13887c478bd9Sstevel@tonic-gate (void) strcat(path, "/"); 13897c478bd9Sstevel@tonic-gate (void) strcat(path, dp->d_name); 13907c478bd9Sstevel@tonic-gate add_device_to_disklist(dp->d_name, 13917c478bd9Sstevel@tonic-gate path); 13927c478bd9Sstevel@tonic-gate } 13937c478bd9Sstevel@tonic-gate } 13947c478bd9Sstevel@tonic-gate } 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate } 13977c478bd9Sstevel@tonic-gate rewinddir(dir); 13987c478bd9Sstevel@tonic-gate 13997c478bd9Sstevel@tonic-gate 14007c478bd9Sstevel@tonic-gate /* 14017c478bd9Sstevel@tonic-gate * Now find all nodes corresponding to the standard 14027c478bd9Sstevel@tonic-gate * device naming conventions. 14037c478bd9Sstevel@tonic-gate */ 14047c478bd9Sstevel@tonic-gate while ((dp = readdir(dir)) != NULL) { 14057c478bd9Sstevel@tonic-gate if (strcmp(dp->d_name, ".") == 0 || 14067c478bd9Sstevel@tonic-gate strcmp(dp->d_name, "..") == 0) 14077c478bd9Sstevel@tonic-gate continue; 14087c478bd9Sstevel@tonic-gate if (whole_disk_name(dp->d_name)) { 14097c478bd9Sstevel@tonic-gate (void) strcpy(path, directory); 14107c478bd9Sstevel@tonic-gate (void) strcat(path, "/"); 14117c478bd9Sstevel@tonic-gate (void) strcat(path, dp->d_name); 14127c478bd9Sstevel@tonic-gate canonicalize_name(s, dp->d_name); 14137c478bd9Sstevel@tonic-gate add_device_to_disklist(s, path); 14147c478bd9Sstevel@tonic-gate } 14157c478bd9Sstevel@tonic-gate } 14167c478bd9Sstevel@tonic-gate /* 14177c478bd9Sstevel@tonic-gate * Close the directory 14187c478bd9Sstevel@tonic-gate */ 14197c478bd9Sstevel@tonic-gate if (closedir(dir) == -1) { 14207c478bd9Sstevel@tonic-gate err_print("Cannot close directory %s - %s\n", 14217c478bd9Sstevel@tonic-gate directory, strerror(errno)); 14227c478bd9Sstevel@tonic-gate fullabort(); 14237c478bd9Sstevel@tonic-gate } 14247c478bd9Sstevel@tonic-gate 14257c478bd9Sstevel@tonic-gate need_newline = 0; 14267c478bd9Sstevel@tonic-gate fmt_print("done\n"); 14277c478bd9Sstevel@tonic-gate } 14287c478bd9Sstevel@tonic-gate 14297c478bd9Sstevel@tonic-gate /* 14307c478bd9Sstevel@tonic-gate * Return to whence we came 14317c478bd9Sstevel@tonic-gate */ 14327c478bd9Sstevel@tonic-gate if (chdir(curdir) == -1) { 14337c478bd9Sstevel@tonic-gate err_print("Cannot set directory to %s - %s\n", 14347c478bd9Sstevel@tonic-gate curdir, strerror(errno)); 14357c478bd9Sstevel@tonic-gate fullabort(); 14367c478bd9Sstevel@tonic-gate } 14377c478bd9Sstevel@tonic-gate 14387c478bd9Sstevel@tonic-gate /* 14397c478bd9Sstevel@tonic-gate * If we didn't find any disks, give up. 14407c478bd9Sstevel@tonic-gate */ 14417c478bd9Sstevel@tonic-gate if (disk_list == NULL) { 14427c478bd9Sstevel@tonic-gate if (geteuid() == 0) { 14437c478bd9Sstevel@tonic-gate err_print("No disks found!\n"); 14447c478bd9Sstevel@tonic-gate } else { 14457c478bd9Sstevel@tonic-gate err_print("No permission (or no disks found)!\n"); 14467c478bd9Sstevel@tonic-gate } 14477c478bd9Sstevel@tonic-gate (void) fflush(stdout); 14487c478bd9Sstevel@tonic-gate fullabort(); 14497c478bd9Sstevel@tonic-gate } 14507c478bd9Sstevel@tonic-gate 14517c478bd9Sstevel@tonic-gate sort_disk_list(); 14527c478bd9Sstevel@tonic-gate 14537c478bd9Sstevel@tonic-gate /* 14547c478bd9Sstevel@tonic-gate * Tell user the results of the auto-configure process 14557c478bd9Sstevel@tonic-gate */ 14567c478bd9Sstevel@tonic-gate i = 0; 14577c478bd9Sstevel@tonic-gate for (disk = disk_list; disk != NULL; disk = disk->disk_next) { 14587c478bd9Sstevel@tonic-gate float scaled; 14597c478bd9Sstevel@tonic-gate long nblks; 14607c478bd9Sstevel@tonic-gate struct disk_type *type; 14617c478bd9Sstevel@tonic-gate if (disk->disk_flags & DSK_AUTO_CONFIG) { 14627c478bd9Sstevel@tonic-gate if (i++ == 0) { 14637c478bd9Sstevel@tonic-gate fmt_print("\n"); 14647c478bd9Sstevel@tonic-gate } 14657c478bd9Sstevel@tonic-gate fmt_print("%s: ", disk->disk_name); 14667c478bd9Sstevel@tonic-gate if (disk->disk_flags & DSK_LABEL_DIRTY) { 14677c478bd9Sstevel@tonic-gate fmt_print("configured "); 14687c478bd9Sstevel@tonic-gate } else { 14697c478bd9Sstevel@tonic-gate fmt_print("configured and labeled "); 14707c478bd9Sstevel@tonic-gate } 14717c478bd9Sstevel@tonic-gate type = disk->disk_type; 14727c478bd9Sstevel@tonic-gate nblks = type->dtype_ncyl * type->dtype_nhead * 14737c478bd9Sstevel@tonic-gate type->dtype_nsect; 14747c478bd9Sstevel@tonic-gate if (disk->label_type == L_TYPE_SOLARIS) 14757c478bd9Sstevel@tonic-gate scaled = bn2mb(nblks); 14767c478bd9Sstevel@tonic-gate else 14777c478bd9Sstevel@tonic-gate scaled = bn2mb(type->capacity); 14787c478bd9Sstevel@tonic-gate fmt_print("with capacity of "); 14797c478bd9Sstevel@tonic-gate if (scaled > 1024.0) { 14807c478bd9Sstevel@tonic-gate fmt_print("%1.2fGB\n", scaled/1024.0); 14817c478bd9Sstevel@tonic-gate } else { 14827c478bd9Sstevel@tonic-gate fmt_print("%1.2fMB\n", scaled); 14837c478bd9Sstevel@tonic-gate } 14847c478bd9Sstevel@tonic-gate } 14857c478bd9Sstevel@tonic-gate } 14867c478bd9Sstevel@tonic-gate } 14877c478bd9Sstevel@tonic-gate 14887c478bd9Sstevel@tonic-gate 14897c478bd9Sstevel@tonic-gate /* 14907c478bd9Sstevel@tonic-gate * For a given "logical" disk name as specified in a format.dat 14917c478bd9Sstevel@tonic-gate * search path, try to find the device it actually refers to. 14927c478bd9Sstevel@tonic-gate * Since we are trying to maintain 4.x naming convention 14937c478bd9Sstevel@tonic-gate * compatibility in 5.0, this involves a little bit of work. 14947c478bd9Sstevel@tonic-gate * We also want to be able to function under 4.x, if needed. 14957c478bd9Sstevel@tonic-gate * 14967c478bd9Sstevel@tonic-gate * canonical: standard name reference. append a partition 14977c478bd9Sstevel@tonic-gate * reference, and open that file in the device directory. 14987c478bd9Sstevel@tonic-gate * examples: SVR4: c0t0d0 14997c478bd9Sstevel@tonic-gate * 4.x: sd0 15007c478bd9Sstevel@tonic-gate * 15017c478bd9Sstevel@tonic-gate * absolute: begins with a '/', and is assumed to be an 15027c478bd9Sstevel@tonic-gate * absolute pathname to some node. 15037c478bd9Sstevel@tonic-gate * 15047c478bd9Sstevel@tonic-gate * relative: non-canonical, doesn't begin with a '/'. 15057c478bd9Sstevel@tonic-gate * assumed to be the name of a file in the appropriate 15067c478bd9Sstevel@tonic-gate * device directory. 15077c478bd9Sstevel@tonic-gate */ 15087c478bd9Sstevel@tonic-gate static void 15097c478bd9Sstevel@tonic-gate search_for_logical_dev(char *devname) 15107c478bd9Sstevel@tonic-gate { 15117c478bd9Sstevel@tonic-gate char path[MAXPATHLEN]; 15127c478bd9Sstevel@tonic-gate char *directory = "/dev/rdsk/"; 15137c478bd9Sstevel@tonic-gate char *partition = "s2"; 15147c478bd9Sstevel@tonic-gate 15157c478bd9Sstevel@tonic-gate /* 15167c478bd9Sstevel@tonic-gate * If the name is an absolute path name, accept it as is 15177c478bd9Sstevel@tonic-gate */ 15187c478bd9Sstevel@tonic-gate if (*devname == '/') { 15197c478bd9Sstevel@tonic-gate (void) strcpy(path, devname); 15207c478bd9Sstevel@tonic-gate } else if (canonical_name(devname)) { 15217c478bd9Sstevel@tonic-gate /* 15227c478bd9Sstevel@tonic-gate * If canonical name, construct a standard path name. 15237c478bd9Sstevel@tonic-gate */ 15247c478bd9Sstevel@tonic-gate (void) strcpy(path, directory); 15257c478bd9Sstevel@tonic-gate (void) strcat(path, devname); 15267c478bd9Sstevel@tonic-gate (void) strcat(path, partition); 15277c478bd9Sstevel@tonic-gate } else if (canonical4x_name(devname)) { 15287c478bd9Sstevel@tonic-gate /* 15297c478bd9Sstevel@tonic-gate * Check to see if it's a 4.x file name in the /dev 15307c478bd9Sstevel@tonic-gate * directory on 5.0. Here, we only accept the 15317c478bd9Sstevel@tonic-gate * canonicalized form: sd0. 15327c478bd9Sstevel@tonic-gate */ 15337c478bd9Sstevel@tonic-gate (void) strcpy(path, "/dev/r"); 15347c478bd9Sstevel@tonic-gate (void) strcat(path, devname); 15357c478bd9Sstevel@tonic-gate (void) strcat(path, "c"); 15367c478bd9Sstevel@tonic-gate } else { 15377c478bd9Sstevel@tonic-gate /* 15387c478bd9Sstevel@tonic-gate * If it's not a canonical name, then it may be a 15397c478bd9Sstevel@tonic-gate * reference to an actual file name in the device 15407c478bd9Sstevel@tonic-gate * directory itself. 15417c478bd9Sstevel@tonic-gate */ 15427c478bd9Sstevel@tonic-gate (void) strcpy(path, directory); 15437c478bd9Sstevel@tonic-gate (void) strcat(path, devname); 15447c478bd9Sstevel@tonic-gate } 15457c478bd9Sstevel@tonic-gate 15467c478bd9Sstevel@tonic-gate /* now add the device */ 15477c478bd9Sstevel@tonic-gate add_device_to_disklist(devname, path); 15487c478bd9Sstevel@tonic-gate } 15497c478bd9Sstevel@tonic-gate 15507c478bd9Sstevel@tonic-gate 15517c478bd9Sstevel@tonic-gate /* 15527c478bd9Sstevel@tonic-gate * Add a device to the disk list, if it appears to be a disk, 15537c478bd9Sstevel@tonic-gate * and we haven't already found it under some other name. 15547c478bd9Sstevel@tonic-gate */ 15557c478bd9Sstevel@tonic-gate static void 15567c478bd9Sstevel@tonic-gate add_device_to_disklist(char *devname, char *devpath) 15577c478bd9Sstevel@tonic-gate { 15587c478bd9Sstevel@tonic-gate struct disk_info *search_disk; 15597c478bd9Sstevel@tonic-gate struct ctlr_info *search_ctlr; 15607c478bd9Sstevel@tonic-gate struct disk_type *search_dtype, *efi_disk; 15617c478bd9Sstevel@tonic-gate struct partition_info *search_parts; 15627c478bd9Sstevel@tonic-gate struct disk_info *dptr; 15637c478bd9Sstevel@tonic-gate struct ctlr_info *cptr; 15647c478bd9Sstevel@tonic-gate struct disk_type *type; 15657c478bd9Sstevel@tonic-gate struct partition_info *parts; 15667c478bd9Sstevel@tonic-gate struct dk_label search_label; 15677c478bd9Sstevel@tonic-gate struct dk_cinfo dkinfo; 15687c478bd9Sstevel@tonic-gate struct stat stbuf; 15697c478bd9Sstevel@tonic-gate struct ctlr_type *ctlr, *tctlr; 15707c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 15717c478bd9Sstevel@tonic-gate struct efi_info efi_info; 1572*c7d4aa56Sphitran struct dk_minfo mediainfo; 15737c478bd9Sstevel@tonic-gate int search_file; 15747c478bd9Sstevel@tonic-gate int status; 15757c478bd9Sstevel@tonic-gate int i; 15767c478bd9Sstevel@tonic-gate int access_flags = 0; 15777c478bd9Sstevel@tonic-gate 15787c478bd9Sstevel@tonic-gate /* 15797c478bd9Sstevel@tonic-gate * Attempt to open the disk. If it fails, skip it. 15807c478bd9Sstevel@tonic-gate */ 15817c478bd9Sstevel@tonic-gate if ((search_file = open_disk(devpath, O_RDWR | O_NDELAY)) < 0) { 15827c478bd9Sstevel@tonic-gate return; 15837c478bd9Sstevel@tonic-gate } 15847c478bd9Sstevel@tonic-gate /* 15857c478bd9Sstevel@tonic-gate * Must be a character device 15867c478bd9Sstevel@tonic-gate */ 15877c478bd9Sstevel@tonic-gate if (fstat(search_file, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) { 15887c478bd9Sstevel@tonic-gate (void) close(search_file); 15897c478bd9Sstevel@tonic-gate return; 15907c478bd9Sstevel@tonic-gate } 15917c478bd9Sstevel@tonic-gate /* 15927c478bd9Sstevel@tonic-gate * Attempt to read the configuration info on the disk. 15937c478bd9Sstevel@tonic-gate * Again, if it fails, we assume the disk's not there. 15947c478bd9Sstevel@tonic-gate * Note we must close the file for the disk before we 15957c478bd9Sstevel@tonic-gate * continue. 15967c478bd9Sstevel@tonic-gate */ 15977c478bd9Sstevel@tonic-gate if (ioctl(search_file, DKIOCINFO, &dkinfo) < 0) { 15987c478bd9Sstevel@tonic-gate (void) close(search_file); 15997c478bd9Sstevel@tonic-gate return; 16007c478bd9Sstevel@tonic-gate } 16017c478bd9Sstevel@tonic-gate 16027c478bd9Sstevel@tonic-gate /* If it is a removable media, skip it. */ 16037c478bd9Sstevel@tonic-gate 16047c478bd9Sstevel@tonic-gate if (!expert_mode) { 16057c478bd9Sstevel@tonic-gate int isremovable, ret; 16067c478bd9Sstevel@tonic-gate ret = ioctl(search_file, DKIOCREMOVABLE, &isremovable); 16077c478bd9Sstevel@tonic-gate if ((ret >= 0) && (isremovable != 0)) { 16087c478bd9Sstevel@tonic-gate (void) close(search_file); 16097c478bd9Sstevel@tonic-gate return; 16107c478bd9Sstevel@tonic-gate } 16117c478bd9Sstevel@tonic-gate } 16127c478bd9Sstevel@tonic-gate 16137c478bd9Sstevel@tonic-gate /* 16147c478bd9Sstevel@tonic-gate * If the type of disk is one we don't know about, 16157c478bd9Sstevel@tonic-gate * add it to the list. 16167c478bd9Sstevel@tonic-gate */ 16177c478bd9Sstevel@tonic-gate mlp = controlp; 16187c478bd9Sstevel@tonic-gate 16197c478bd9Sstevel@tonic-gate while (mlp != NULL) { 16207c478bd9Sstevel@tonic-gate if (mlp->ctlr_type->ctype_ctype == dkinfo.dki_ctype && 16217c478bd9Sstevel@tonic-gate strcmp(mlp->ctlr_type->ctype_name, dkinfo.dki_cname) == 0) { 16227c478bd9Sstevel@tonic-gate break; 16237c478bd9Sstevel@tonic-gate } 16247c478bd9Sstevel@tonic-gate mlp = mlp->next; 16257c478bd9Sstevel@tonic-gate } 16267c478bd9Sstevel@tonic-gate 16277c478bd9Sstevel@tonic-gate if (mlp == NULL) { 1628*c7d4aa56Sphitran if (dkinfo.dki_ctype == DKC_CDROM) { 1629*c7d4aa56Sphitran if (ioctl(search_file, DKIOCGMEDIAINFO, 1630*c7d4aa56Sphitran &mediainfo) < 0) { 1631*c7d4aa56Sphitran mediainfo.dki_media_type = DK_UNKNOWN; 1632*c7d4aa56Sphitran } 1633*c7d4aa56Sphitran } 16347c478bd9Sstevel@tonic-gate /* 16357c478bd9Sstevel@tonic-gate * Skip CDROM devices, they are read only. 1636*c7d4aa56Sphitran * But not devices like Iomega Rev Drive which 1637*c7d4aa56Sphitran * identifies itself as a CDROM, but has a removable 1638*c7d4aa56Sphitran * disk. 16397c478bd9Sstevel@tonic-gate * Also skip PCMCIA memory card device since 16407c478bd9Sstevel@tonic-gate * it is used as a pseudo floppy disk drive 16417c478bd9Sstevel@tonic-gate * at the present time (BugID 1201473) 16427c478bd9Sstevel@tonic-gate */ 1643*c7d4aa56Sphitran if (((dkinfo.dki_ctype == DKC_CDROM) && 1644*c7d4aa56Sphitran (mediainfo.dki_media_type != DK_REMOVABLE_DISK)) || 16457c478bd9Sstevel@tonic-gate (dkinfo.dki_ctype == DKC_PCMCIA_MEM)) { 16467c478bd9Sstevel@tonic-gate (void) close(search_file); 16477c478bd9Sstevel@tonic-gate return; 16487c478bd9Sstevel@tonic-gate } 16497c478bd9Sstevel@tonic-gate /* 16507c478bd9Sstevel@tonic-gate * create the new ctlr_type structure and fill it in. 16517c478bd9Sstevel@tonic-gate */ 16527c478bd9Sstevel@tonic-gate tctlr = zalloc(sizeof (struct ctlr_type)); 16537c478bd9Sstevel@tonic-gate tctlr->ctype_ctype = dkinfo.dki_ctype; 16547c478bd9Sstevel@tonic-gate tctlr->ctype_name = zalloc(DK_DEVLEN); 16557c478bd9Sstevel@tonic-gate if (strlcpy(tctlr->ctype_name, dkinfo.dki_cname, 16567c478bd9Sstevel@tonic-gate DK_DEVLEN) > DK_DEVLEN) { 16577c478bd9Sstevel@tonic-gate /* 16587c478bd9Sstevel@tonic-gate * DKIOCINFO returned a controller name longer 16597c478bd9Sstevel@tonic-gate * than DK_DEVLEN bytes, which means more of the 16607c478bd9Sstevel@tonic-gate * dk_cinfo structure may be corrupt. We don't 16617c478bd9Sstevel@tonic-gate * allow the user to perform any operations on 16627c478bd9Sstevel@tonic-gate * the device in this case 16637c478bd9Sstevel@tonic-gate */ 16647c478bd9Sstevel@tonic-gate err_print("\nError: Device %s: controller " 16657c478bd9Sstevel@tonic-gate "name (%s)\nis invalid. Device will not " 16667c478bd9Sstevel@tonic-gate "be displayed.\n", devname, dkinfo.dki_cname); 16677c478bd9Sstevel@tonic-gate (void) close(search_file); 16687c478bd9Sstevel@tonic-gate destroy_data(tctlr->ctype_name); 16697c478bd9Sstevel@tonic-gate destroy_data((char *)tctlr); 16707c478bd9Sstevel@tonic-gate return; 16717c478bd9Sstevel@tonic-gate } else { 16727c478bd9Sstevel@tonic-gate tctlr->ctype_ops = zalloc(sizeof (struct ctlr_ops)); 16737c478bd9Sstevel@tonic-gate 16747c478bd9Sstevel@tonic-gate /* 16757c478bd9Sstevel@tonic-gate * copy the generic disk ops structure into local copy. 16767c478bd9Sstevel@tonic-gate */ 16777c478bd9Sstevel@tonic-gate *(tctlr->ctype_ops) = genericops; 16787c478bd9Sstevel@tonic-gate 16797c478bd9Sstevel@tonic-gate tctlr->ctype_flags = CF_WLIST; 16807c478bd9Sstevel@tonic-gate 16817c478bd9Sstevel@tonic-gate mlp = controlp; 16827c478bd9Sstevel@tonic-gate 16837c478bd9Sstevel@tonic-gate while (mlp->next != NULL) { 16847c478bd9Sstevel@tonic-gate mlp = mlp->next; 16857c478bd9Sstevel@tonic-gate } 16867c478bd9Sstevel@tonic-gate 16877c478bd9Sstevel@tonic-gate mlp->next = zalloc(sizeof (struct mctlr_list)); 16887c478bd9Sstevel@tonic-gate mlp->next->ctlr_type = tctlr; 16897c478bd9Sstevel@tonic-gate } 16907c478bd9Sstevel@tonic-gate } 16917c478bd9Sstevel@tonic-gate 16927c478bd9Sstevel@tonic-gate /* 16937c478bd9Sstevel@tonic-gate * Search through all disks known at this time, to 16947c478bd9Sstevel@tonic-gate * determine if we're already identified this disk. 16957c478bd9Sstevel@tonic-gate * If so, then there's no need to include it a 16967c478bd9Sstevel@tonic-gate * second time. This permits the user-defined names 16977c478bd9Sstevel@tonic-gate * to supercede the standard conventional names. 16987c478bd9Sstevel@tonic-gate */ 16997c478bd9Sstevel@tonic-gate if (disk_is_known(&dkinfo)) { 17007c478bd9Sstevel@tonic-gate (void) close(search_file); 17017c478bd9Sstevel@tonic-gate return; 17027c478bd9Sstevel@tonic-gate } 17037c478bd9Sstevel@tonic-gate #if defined(sparc) 17047c478bd9Sstevel@tonic-gate /* 17057c478bd9Sstevel@tonic-gate * Because opening id with FNDELAY always succeeds, 17067c478bd9Sstevel@tonic-gate * read the label early on to see whether the device 17077c478bd9Sstevel@tonic-gate * really exists. A result of DSK_RESERVED 17087c478bd9Sstevel@tonic-gate * means the disk may be reserved. 17097c478bd9Sstevel@tonic-gate * In the future, it will be good 17107c478bd9Sstevel@tonic-gate * to move these into controller specific files and have a common 17117c478bd9Sstevel@tonic-gate * generic check for reserved disks here, including intel disks. 17127c478bd9Sstevel@tonic-gate */ 17137c478bd9Sstevel@tonic-gate if (dkinfo.dki_ctype == DKC_SCSI_CCS) { 17147c478bd9Sstevel@tonic-gate i = scsi_rdwr(DIR_READ, search_file, (daddr_t)0, 17157c478bd9Sstevel@tonic-gate 1, (char *)&search_label, F_SILENT, NULL); 17167c478bd9Sstevel@tonic-gate switch (i) { 17177c478bd9Sstevel@tonic-gate case DSK_RESERVED: 17187c478bd9Sstevel@tonic-gate access_flags |= DSK_RESERVED; 17197c478bd9Sstevel@tonic-gate break; 17207c478bd9Sstevel@tonic-gate case DSK_UNAVAILABLE: 17217c478bd9Sstevel@tonic-gate access_flags |= DSK_UNAVAILABLE; 17227c478bd9Sstevel@tonic-gate break; 17237c478bd9Sstevel@tonic-gate default: 17247c478bd9Sstevel@tonic-gate break; 17257c478bd9Sstevel@tonic-gate } 17267c478bd9Sstevel@tonic-gate } 17277c478bd9Sstevel@tonic-gate #endif /* defined(sparc) */ 17287c478bd9Sstevel@tonic-gate 17297c478bd9Sstevel@tonic-gate /* 17307c478bd9Sstevel@tonic-gate * The disk appears to be present. Allocate space for the 17317c478bd9Sstevel@tonic-gate * disk structure and add it to the list of found disks. 17327c478bd9Sstevel@tonic-gate */ 17337c478bd9Sstevel@tonic-gate search_disk = (struct disk_info *)zalloc(sizeof (struct disk_info)); 17347c478bd9Sstevel@tonic-gate if (disk_list == NULL) 17357c478bd9Sstevel@tonic-gate disk_list = search_disk; 17367c478bd9Sstevel@tonic-gate else { 17377c478bd9Sstevel@tonic-gate for (dptr = disk_list; dptr->disk_next != NULL; 17387c478bd9Sstevel@tonic-gate dptr = dptr->disk_next) 17397c478bd9Sstevel@tonic-gate ; 17407c478bd9Sstevel@tonic-gate dptr->disk_next = search_disk; 17417c478bd9Sstevel@tonic-gate } 17427c478bd9Sstevel@tonic-gate /* 17437c478bd9Sstevel@tonic-gate * Fill in some info from the ioctls. 17447c478bd9Sstevel@tonic-gate */ 17457c478bd9Sstevel@tonic-gate search_disk->disk_dkinfo = dkinfo; 17467c478bd9Sstevel@tonic-gate if (is_efi_type(search_file)) { 17477c478bd9Sstevel@tonic-gate search_disk->label_type = L_TYPE_EFI; 17487c478bd9Sstevel@tonic-gate } else { 17497c478bd9Sstevel@tonic-gate search_disk->label_type = L_TYPE_SOLARIS; 17507c478bd9Sstevel@tonic-gate } 17517c478bd9Sstevel@tonic-gate /* 17527c478bd9Sstevel@tonic-gate * Remember the names of the disk 17537c478bd9Sstevel@tonic-gate */ 17547c478bd9Sstevel@tonic-gate search_disk->disk_name = alloc_string(devname); 17557c478bd9Sstevel@tonic-gate search_disk->disk_path = alloc_string(devpath); 17567c478bd9Sstevel@tonic-gate 17577c478bd9Sstevel@tonic-gate (void) strcpy(x86_devname, devname); 17587c478bd9Sstevel@tonic-gate 17597c478bd9Sstevel@tonic-gate /* 17607c478bd9Sstevel@tonic-gate * Determine if this device is linked to a physical name. 17617c478bd9Sstevel@tonic-gate */ 17627c478bd9Sstevel@tonic-gate search_disk->devfs_name = get_physical_name(devpath); 17637c478bd9Sstevel@tonic-gate 17647c478bd9Sstevel@tonic-gate /* 17657c478bd9Sstevel@tonic-gate * Try to match the ctlr for this disk with a ctlr we 17667c478bd9Sstevel@tonic-gate * have already found. A match is assumed if the ctlrs 17677c478bd9Sstevel@tonic-gate * are at the same address && ctypes agree 17687c478bd9Sstevel@tonic-gate */ 17697c478bd9Sstevel@tonic-gate for (search_ctlr = ctlr_list; search_ctlr != NULL; 17707c478bd9Sstevel@tonic-gate search_ctlr = search_ctlr->ctlr_next) 17717c478bd9Sstevel@tonic-gate if (search_ctlr->ctlr_addr == dkinfo.dki_addr && 17727c478bd9Sstevel@tonic-gate search_ctlr->ctlr_space == dkinfo.dki_space && 17737c478bd9Sstevel@tonic-gate search_ctlr->ctlr_ctype->ctype_ctype == 17747c478bd9Sstevel@tonic-gate dkinfo.dki_ctype) 17757c478bd9Sstevel@tonic-gate break; 17767c478bd9Sstevel@tonic-gate /* 17777c478bd9Sstevel@tonic-gate * If no match was found, we need to identify this ctlr. 17787c478bd9Sstevel@tonic-gate */ 17797c478bd9Sstevel@tonic-gate if (search_ctlr == NULL) { 17807c478bd9Sstevel@tonic-gate /* 17817c478bd9Sstevel@tonic-gate * Match the type of the ctlr to a known type. 17827c478bd9Sstevel@tonic-gate */ 17837c478bd9Sstevel@tonic-gate mlp = controlp; 17847c478bd9Sstevel@tonic-gate 17857c478bd9Sstevel@tonic-gate while (mlp != NULL) { 17867c478bd9Sstevel@tonic-gate if (mlp->ctlr_type->ctype_ctype == dkinfo.dki_ctype) 17877c478bd9Sstevel@tonic-gate break; 17887c478bd9Sstevel@tonic-gate mlp = mlp->next; 17897c478bd9Sstevel@tonic-gate } 17907c478bd9Sstevel@tonic-gate /* 17917c478bd9Sstevel@tonic-gate * If no match was found, it's an error. 17927c478bd9Sstevel@tonic-gate * Close the disk and report the error. 17937c478bd9Sstevel@tonic-gate */ 17947c478bd9Sstevel@tonic-gate if (mlp == NULL) { 17957c478bd9Sstevel@tonic-gate err_print("\nError: found disk attached to "); 17967c478bd9Sstevel@tonic-gate err_print("unsupported controller type '%d'.\n", 17977c478bd9Sstevel@tonic-gate dkinfo.dki_ctype); 17987c478bd9Sstevel@tonic-gate (void) close(search_file); 17997c478bd9Sstevel@tonic-gate return; 18007c478bd9Sstevel@tonic-gate } 18017c478bd9Sstevel@tonic-gate /* 18027c478bd9Sstevel@tonic-gate * Allocate space for the ctlr structure and add it 18037c478bd9Sstevel@tonic-gate * to the list of found ctlrs. 18047c478bd9Sstevel@tonic-gate */ 18057c478bd9Sstevel@tonic-gate search_ctlr = (struct ctlr_info *) 18067c478bd9Sstevel@tonic-gate zalloc(sizeof (struct ctlr_info)); 18077c478bd9Sstevel@tonic-gate search_ctlr->ctlr_ctype = mlp->ctlr_type; 18087c478bd9Sstevel@tonic-gate if (ctlr_list == NULL) 18097c478bd9Sstevel@tonic-gate ctlr_list = search_ctlr; 18107c478bd9Sstevel@tonic-gate else { 18117c478bd9Sstevel@tonic-gate for (cptr = ctlr_list; cptr->ctlr_next != NULL; 18127c478bd9Sstevel@tonic-gate cptr = cptr->ctlr_next) 18137c478bd9Sstevel@tonic-gate ; 18147c478bd9Sstevel@tonic-gate cptr->ctlr_next = search_ctlr; 18157c478bd9Sstevel@tonic-gate } 18167c478bd9Sstevel@tonic-gate /* 18177c478bd9Sstevel@tonic-gate * Fill in info from the ioctl. 18187c478bd9Sstevel@tonic-gate */ 18197c478bd9Sstevel@tonic-gate for (i = 0; i < DK_DEVLEN; i++) { 18207c478bd9Sstevel@tonic-gate search_ctlr->ctlr_cname[i] = dkinfo.dki_cname[i]; 18217c478bd9Sstevel@tonic-gate search_ctlr->ctlr_dname[i] = dkinfo.dki_dname[i]; 18227c478bd9Sstevel@tonic-gate } 18237c478bd9Sstevel@tonic-gate /* 18247c478bd9Sstevel@tonic-gate * Make sure these can be used as simple strings 18257c478bd9Sstevel@tonic-gate */ 18267c478bd9Sstevel@tonic-gate search_ctlr->ctlr_cname[i] = 0; 18277c478bd9Sstevel@tonic-gate search_ctlr->ctlr_dname[i] = 0; 18287c478bd9Sstevel@tonic-gate 18297c478bd9Sstevel@tonic-gate search_ctlr->ctlr_flags = dkinfo.dki_flags; 18307c478bd9Sstevel@tonic-gate search_ctlr->ctlr_num = dkinfo.dki_cnum; 18317c478bd9Sstevel@tonic-gate search_ctlr->ctlr_addr = dkinfo.dki_addr; 18327c478bd9Sstevel@tonic-gate search_ctlr->ctlr_space = dkinfo.dki_space; 18337c478bd9Sstevel@tonic-gate search_ctlr->ctlr_prio = dkinfo.dki_prio; 18347c478bd9Sstevel@tonic-gate search_ctlr->ctlr_vec = dkinfo.dki_vec; 18357c478bd9Sstevel@tonic-gate } 18367c478bd9Sstevel@tonic-gate /* 18377c478bd9Sstevel@tonic-gate * By this point, we have a known ctlr. Link the disk 18387c478bd9Sstevel@tonic-gate * to the ctlr. 18397c478bd9Sstevel@tonic-gate */ 18407c478bd9Sstevel@tonic-gate search_disk->disk_ctlr = search_ctlr; 18417c478bd9Sstevel@tonic-gate if (access_flags & (DSK_RESERVED | DSK_UNAVAILABLE)) { 18427c478bd9Sstevel@tonic-gate if (access_flags & DSK_RESERVED) 18437c478bd9Sstevel@tonic-gate search_disk->disk_flags |= DSK_RESERVED; 18447c478bd9Sstevel@tonic-gate else 18457c478bd9Sstevel@tonic-gate search_disk->disk_flags |= DSK_UNAVAILABLE; 18467c478bd9Sstevel@tonic-gate (void) close(search_file); 18477c478bd9Sstevel@tonic-gate return; 18487c478bd9Sstevel@tonic-gate } else { 18497c478bd9Sstevel@tonic-gate search_disk->disk_flags &= ~(DSK_RESERVED | DSK_UNAVAILABLE); 18507c478bd9Sstevel@tonic-gate } 18517c478bd9Sstevel@tonic-gate 18527c478bd9Sstevel@tonic-gate /* 18537c478bd9Sstevel@tonic-gate * Attempt to read the primary label. 18547c478bd9Sstevel@tonic-gate * (Note that this is really through the DKIOCGVTOC 18557c478bd9Sstevel@tonic-gate * ioctl, then converted from vtoc to label.) 18567c478bd9Sstevel@tonic-gate */ 18577c478bd9Sstevel@tonic-gate if (search_disk->label_type == L_TYPE_SOLARIS) { 18587c478bd9Sstevel@tonic-gate status = read_label(search_file, &search_label); 18597c478bd9Sstevel@tonic-gate } else { 18607c478bd9Sstevel@tonic-gate status = read_efi_label(search_file, &efi_info); 18617c478bd9Sstevel@tonic-gate } 18627c478bd9Sstevel@tonic-gate /* 18637c478bd9Sstevel@tonic-gate * If reading the label failed, and this is a SCSI 18647c478bd9Sstevel@tonic-gate * disk, we can attempt to auto-sense the disk 18657c478bd9Sstevel@tonic-gate * configuration. 18667c478bd9Sstevel@tonic-gate */ 18677c478bd9Sstevel@tonic-gate ctlr = search_ctlr->ctlr_ctype; 18687c478bd9Sstevel@tonic-gate if ((status == -1) && (ctlr->ctype_ctype == DKC_SCSI_CCS)) { 18697c478bd9Sstevel@tonic-gate if (option_msg && diag_msg) { 18707c478bd9Sstevel@tonic-gate err_print("%s: attempting auto configuration\n", 18717c478bd9Sstevel@tonic-gate search_disk->disk_name); 18727c478bd9Sstevel@tonic-gate } 18737c478bd9Sstevel@tonic-gate switch (search_disk->label_type) { 18747c478bd9Sstevel@tonic-gate case (L_TYPE_SOLARIS): 18757c478bd9Sstevel@tonic-gate if (auto_sense(search_file, 0, &search_label) != NULL) { 18767c478bd9Sstevel@tonic-gate /* 18777c478bd9Sstevel@tonic-gate * Auto config worked, so we now have 18787c478bd9Sstevel@tonic-gate * a valid label for the disk. Mark 18797c478bd9Sstevel@tonic-gate * the disk as needing the label flushed. 18807c478bd9Sstevel@tonic-gate */ 18817c478bd9Sstevel@tonic-gate status = 0; 18827c478bd9Sstevel@tonic-gate search_disk->disk_flags |= 18837c478bd9Sstevel@tonic-gate (DSK_LABEL_DIRTY | DSK_AUTO_CONFIG); 18847c478bd9Sstevel@tonic-gate } 18857c478bd9Sstevel@tonic-gate break; 18867c478bd9Sstevel@tonic-gate case (L_TYPE_EFI): 18877c478bd9Sstevel@tonic-gate efi_disk = auto_efi_sense(search_file, &efi_info); 18887c478bd9Sstevel@tonic-gate if (efi_disk != NULL) { 18897c478bd9Sstevel@tonic-gate /* 18907c478bd9Sstevel@tonic-gate * Auto config worked, so we now have 18917c478bd9Sstevel@tonic-gate * a valid label for the disk. 18927c478bd9Sstevel@tonic-gate */ 18937c478bd9Sstevel@tonic-gate status = 0; 18947c478bd9Sstevel@tonic-gate search_disk->disk_flags |= 18957c478bd9Sstevel@tonic-gate (DSK_LABEL_DIRTY | DSK_AUTO_CONFIG); 18967c478bd9Sstevel@tonic-gate } 18977c478bd9Sstevel@tonic-gate break; 18987c478bd9Sstevel@tonic-gate default: 18997c478bd9Sstevel@tonic-gate /* Should never happen */ 19007c478bd9Sstevel@tonic-gate break; 19017c478bd9Sstevel@tonic-gate } 19027c478bd9Sstevel@tonic-gate } 19037c478bd9Sstevel@tonic-gate /* 19047c478bd9Sstevel@tonic-gate * Close the file for this disk. 19057c478bd9Sstevel@tonic-gate */ 19067c478bd9Sstevel@tonic-gate (void) close(search_file); 19077c478bd9Sstevel@tonic-gate /* 19087c478bd9Sstevel@tonic-gate * If we didn't successfully read the label, or the label 19097c478bd9Sstevel@tonic-gate * appears corrupt, just leave the disk as an unknown type. 19107c478bd9Sstevel@tonic-gate */ 19117c478bd9Sstevel@tonic-gate if (status == -1) { 19127c478bd9Sstevel@tonic-gate return; 19137c478bd9Sstevel@tonic-gate } 19147c478bd9Sstevel@tonic-gate 19157c478bd9Sstevel@tonic-gate if (search_disk->label_type == L_TYPE_SOLARIS) { 19167c478bd9Sstevel@tonic-gate if (!checklabel(&search_label)) { 19177c478bd9Sstevel@tonic-gate return; 19187c478bd9Sstevel@tonic-gate } 19197c478bd9Sstevel@tonic-gate if (trim_id(search_label.dkl_asciilabel)) { 19207c478bd9Sstevel@tonic-gate return; 19217c478bd9Sstevel@tonic-gate } 19227c478bd9Sstevel@tonic-gate } 19237c478bd9Sstevel@tonic-gate /* 19247c478bd9Sstevel@tonic-gate * The label looks ok. Mark the disk as labeled. 19257c478bd9Sstevel@tonic-gate */ 19267c478bd9Sstevel@tonic-gate search_disk->disk_flags |= DSK_LABEL; 19277c478bd9Sstevel@tonic-gate 19287c478bd9Sstevel@tonic-gate if (search_disk->label_type == L_TYPE_EFI) { 19297c478bd9Sstevel@tonic-gate search_dtype = (struct disk_type *) 19307c478bd9Sstevel@tonic-gate zalloc(sizeof (struct disk_type)); 19317c478bd9Sstevel@tonic-gate type = search_ctlr->ctlr_ctype->ctype_dlist; 19327c478bd9Sstevel@tonic-gate if (type == NULL) { 19337c478bd9Sstevel@tonic-gate search_ctlr->ctlr_ctype->ctype_dlist = 19347c478bd9Sstevel@tonic-gate search_dtype; 19357c478bd9Sstevel@tonic-gate } else { 19367c478bd9Sstevel@tonic-gate while (type->dtype_next != NULL) { 19377c478bd9Sstevel@tonic-gate type = type->dtype_next; 19387c478bd9Sstevel@tonic-gate } 19397c478bd9Sstevel@tonic-gate type->dtype_next = search_dtype; 19407c478bd9Sstevel@tonic-gate } 19417c478bd9Sstevel@tonic-gate 19427c478bd9Sstevel@tonic-gate (void) strlcpy(search_dtype->vendor, efi_info.vendor, 9); 19437c478bd9Sstevel@tonic-gate (void) strlcpy(search_dtype->product, efi_info.product, 17); 19447c478bd9Sstevel@tonic-gate (void) strlcpy(search_dtype->revision, efi_info.revision, 5); 19457c478bd9Sstevel@tonic-gate search_dtype->capacity = efi_info.capacity; 19467c478bd9Sstevel@tonic-gate search_disk->disk_type = search_dtype; 19477c478bd9Sstevel@tonic-gate 19487c478bd9Sstevel@tonic-gate search_parts = (struct partition_info *) 19497c478bd9Sstevel@tonic-gate zalloc(sizeof (struct partition_info)); 19507c478bd9Sstevel@tonic-gate search_dtype->dtype_plist = search_parts; 19517c478bd9Sstevel@tonic-gate 19527c478bd9Sstevel@tonic-gate search_parts->pinfo_name = alloc_string("original"); 19537c478bd9Sstevel@tonic-gate search_parts->pinfo_next = NULL; 19547c478bd9Sstevel@tonic-gate search_parts->etoc = efi_info.e_parts; 19557c478bd9Sstevel@tonic-gate search_disk->disk_parts = search_parts; 19567c478bd9Sstevel@tonic-gate 19577c478bd9Sstevel@tonic-gate /* 19587c478bd9Sstevel@tonic-gate * Copy the volume name, if present 19597c478bd9Sstevel@tonic-gate */ 19607c478bd9Sstevel@tonic-gate for (i = 0; i < search_parts->etoc->efi_nparts; i++) { 19617c478bd9Sstevel@tonic-gate if (search_parts->etoc->efi_parts[i].p_tag == 19627c478bd9Sstevel@tonic-gate V_RESERVED) { 19637c478bd9Sstevel@tonic-gate if (search_parts->etoc->efi_parts[i].p_name) { 19647c478bd9Sstevel@tonic-gate bcopy(search_parts->etoc->efi_parts[i].p_name, 19657c478bd9Sstevel@tonic-gate search_disk->v_volume, LEN_DKL_VVOL); 19667c478bd9Sstevel@tonic-gate } else { 19677c478bd9Sstevel@tonic-gate bzero(search_disk->v_volume, LEN_DKL_VVOL); 19687c478bd9Sstevel@tonic-gate } 19697c478bd9Sstevel@tonic-gate break; 19707c478bd9Sstevel@tonic-gate } 19717c478bd9Sstevel@tonic-gate } 19727c478bd9Sstevel@tonic-gate return; 19737c478bd9Sstevel@tonic-gate } 19747c478bd9Sstevel@tonic-gate 19757c478bd9Sstevel@tonic-gate /* 19767c478bd9Sstevel@tonic-gate * Attempt to match the disk type in the label with a 19777c478bd9Sstevel@tonic-gate * known disk type. 19787c478bd9Sstevel@tonic-gate */ 19797c478bd9Sstevel@tonic-gate for (search_dtype = search_ctlr->ctlr_ctype->ctype_dlist; 19807c478bd9Sstevel@tonic-gate search_dtype != NULL; 19817c478bd9Sstevel@tonic-gate search_dtype = search_dtype->dtype_next) 19827c478bd9Sstevel@tonic-gate if (dtype_match(&search_label, search_dtype)) 19837c478bd9Sstevel@tonic-gate break; 19847c478bd9Sstevel@tonic-gate /* 19857c478bd9Sstevel@tonic-gate * If no match was found, we need to create a disk type 19867c478bd9Sstevel@tonic-gate * for this disk. 19877c478bd9Sstevel@tonic-gate */ 19887c478bd9Sstevel@tonic-gate if (search_dtype == NULL) { 19897c478bd9Sstevel@tonic-gate /* 19907c478bd9Sstevel@tonic-gate * Allocate space for the disk type and add it 19917c478bd9Sstevel@tonic-gate * to the list of disk types for this ctlr type. 19927c478bd9Sstevel@tonic-gate */ 19937c478bd9Sstevel@tonic-gate search_dtype = (struct disk_type *) 19947c478bd9Sstevel@tonic-gate zalloc(sizeof (struct disk_type)); 19957c478bd9Sstevel@tonic-gate type = search_ctlr->ctlr_ctype->ctype_dlist; 19967c478bd9Sstevel@tonic-gate if (type == NULL) 19977c478bd9Sstevel@tonic-gate search_ctlr->ctlr_ctype->ctype_dlist = 19987c478bd9Sstevel@tonic-gate search_dtype; 19997c478bd9Sstevel@tonic-gate else { 20007c478bd9Sstevel@tonic-gate while (type->dtype_next != NULL) 20017c478bd9Sstevel@tonic-gate type = type->dtype_next; 20027c478bd9Sstevel@tonic-gate type->dtype_next = search_dtype; 20037c478bd9Sstevel@tonic-gate } 20047c478bd9Sstevel@tonic-gate /* 20057c478bd9Sstevel@tonic-gate * Fill in the drive info from the disk label. 20067c478bd9Sstevel@tonic-gate */ 20077c478bd9Sstevel@tonic-gate search_dtype->dtype_next = NULL; 20087c478bd9Sstevel@tonic-gate search_dtype->dtype_asciilabel = (char *) 20097c478bd9Sstevel@tonic-gate zalloc(strlen(search_label.dkl_asciilabel) + 1); 20107c478bd9Sstevel@tonic-gate (void) strcpy(search_dtype->dtype_asciilabel, 20117c478bd9Sstevel@tonic-gate search_label.dkl_asciilabel); 20127c478bd9Sstevel@tonic-gate search_dtype->dtype_pcyl = search_label.dkl_pcyl; 20137c478bd9Sstevel@tonic-gate search_dtype->dtype_ncyl = search_label.dkl_ncyl; 20147c478bd9Sstevel@tonic-gate search_dtype->dtype_acyl = search_label.dkl_acyl; 20157c478bd9Sstevel@tonic-gate search_dtype->dtype_nhead = search_label.dkl_nhead; 20167c478bd9Sstevel@tonic-gate search_dtype->dtype_nsect = search_label.dkl_nsect; 20177c478bd9Sstevel@tonic-gate search_dtype->dtype_rpm = search_label.dkl_rpm; 20187c478bd9Sstevel@tonic-gate /* 20197c478bd9Sstevel@tonic-gate * Mark the disk as needing specification of 20207c478bd9Sstevel@tonic-gate * ctlr specific attributes. This is necessary 20217c478bd9Sstevel@tonic-gate * because the label doesn't contain these attributes, 20227c478bd9Sstevel@tonic-gate * and they aren't known at this point. They will 20237c478bd9Sstevel@tonic-gate * be asked for if this disk is ever selected by 20247c478bd9Sstevel@tonic-gate * the user. 20257c478bd9Sstevel@tonic-gate * Note: for SCSI, we believe the label. 20267c478bd9Sstevel@tonic-gate */ 20277c478bd9Sstevel@tonic-gate if ((search_ctlr->ctlr_ctype->ctype_ctype != DKC_SCSI_CCS) && 20287c478bd9Sstevel@tonic-gate (search_ctlr->ctlr_ctype->ctype_ctype != DKC_DIRECT) && 20297c478bd9Sstevel@tonic-gate (search_ctlr->ctlr_ctype->ctype_ctype != DKC_PCMCIA_ATA)) { 20307c478bd9Sstevel@tonic-gate search_dtype->dtype_flags |= DT_NEED_SPEFS; 20317c478bd9Sstevel@tonic-gate } 20327c478bd9Sstevel@tonic-gate } 20337c478bd9Sstevel@tonic-gate /* 20347c478bd9Sstevel@tonic-gate * By this time we have a known disk type. Link the disk 20357c478bd9Sstevel@tonic-gate * to the disk type. 20367c478bd9Sstevel@tonic-gate */ 20377c478bd9Sstevel@tonic-gate search_disk->disk_type = search_dtype; 20387c478bd9Sstevel@tonic-gate /* 20397c478bd9Sstevel@tonic-gate * Attempt to match the partition map in the label with 20407c478bd9Sstevel@tonic-gate * a known partition map for this disk type. 20417c478bd9Sstevel@tonic-gate */ 20427c478bd9Sstevel@tonic-gate for (search_parts = search_dtype->dtype_plist; 20437c478bd9Sstevel@tonic-gate search_parts != NULL; 20447c478bd9Sstevel@tonic-gate search_parts = search_parts->pinfo_next) 20457c478bd9Sstevel@tonic-gate if (parts_match(&search_label, search_parts)) { 20467c478bd9Sstevel@tonic-gate break; 20477c478bd9Sstevel@tonic-gate } 20487c478bd9Sstevel@tonic-gate /* 20497c478bd9Sstevel@tonic-gate * If no match was made, we need to create a partition 20507c478bd9Sstevel@tonic-gate * map for this disk. 20517c478bd9Sstevel@tonic-gate */ 20527c478bd9Sstevel@tonic-gate if (search_parts == NULL) { 20537c478bd9Sstevel@tonic-gate /* 20547c478bd9Sstevel@tonic-gate * Allocate space for the partition map and add 20557c478bd9Sstevel@tonic-gate * it to the list of maps for this disk type. 20567c478bd9Sstevel@tonic-gate */ 20577c478bd9Sstevel@tonic-gate search_parts = (struct partition_info *) 20587c478bd9Sstevel@tonic-gate zalloc(sizeof (struct partition_info)); 20597c478bd9Sstevel@tonic-gate parts = search_dtype->dtype_plist; 20607c478bd9Sstevel@tonic-gate if (parts == NULL) 20617c478bd9Sstevel@tonic-gate search_dtype->dtype_plist = search_parts; 20627c478bd9Sstevel@tonic-gate else { 20637c478bd9Sstevel@tonic-gate while (parts->pinfo_next != NULL) 20647c478bd9Sstevel@tonic-gate parts = parts->pinfo_next; 20657c478bd9Sstevel@tonic-gate parts->pinfo_next = search_parts; 20667c478bd9Sstevel@tonic-gate } 20677c478bd9Sstevel@tonic-gate search_parts->pinfo_next = NULL; 20687c478bd9Sstevel@tonic-gate /* 20697c478bd9Sstevel@tonic-gate * Fill in the name of the map with a name derived 20707c478bd9Sstevel@tonic-gate * from the name of this disk. This is necessary 20717c478bd9Sstevel@tonic-gate * because the label contains no name for the 20727c478bd9Sstevel@tonic-gate * partition map. 20737c478bd9Sstevel@tonic-gate */ 20747c478bd9Sstevel@tonic-gate search_parts->pinfo_name = alloc_string("original"); 20757c478bd9Sstevel@tonic-gate /* 20767c478bd9Sstevel@tonic-gate * Fill in the partition info from the disk label. 20777c478bd9Sstevel@tonic-gate */ 20787c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 20797c478bd9Sstevel@tonic-gate 20807c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 20817c478bd9Sstevel@tonic-gate search_parts->pinfo_map[i] = 20827c478bd9Sstevel@tonic-gate search_label.dkl_map[i]; 20837c478bd9Sstevel@tonic-gate 20847c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 20857c478bd9Sstevel@tonic-gate search_parts->pinfo_map[i].dkl_cylno = 20867c478bd9Sstevel@tonic-gate search_label.dkl_vtoc.v_part[i].p_start / 20877c478bd9Sstevel@tonic-gate ((int)(search_label.dkl_nhead * 20887c478bd9Sstevel@tonic-gate search_label.dkl_nsect)); 20897c478bd9Sstevel@tonic-gate search_parts->pinfo_map[i].dkl_nblk = 20907c478bd9Sstevel@tonic-gate search_label.dkl_vtoc.v_part[i].p_size; 20917c478bd9Sstevel@tonic-gate 20927c478bd9Sstevel@tonic-gate #else 20937c478bd9Sstevel@tonic-gate #error No VTOC format defined. 20947c478bd9Sstevel@tonic-gate #endif 20957c478bd9Sstevel@tonic-gate } 20967c478bd9Sstevel@tonic-gate } 20977c478bd9Sstevel@tonic-gate /* 20987c478bd9Sstevel@tonic-gate * If the vtoc looks valid, copy the volume name and vtoc 20997c478bd9Sstevel@tonic-gate * info from the label. Otherwise, install a default vtoc. 21007c478bd9Sstevel@tonic-gate * This permits vtoc info to automatically appear in the sun 21017c478bd9Sstevel@tonic-gate * label, without requiring an upgrade procedure. 21027c478bd9Sstevel@tonic-gate */ 21037c478bd9Sstevel@tonic-gate if (search_label.dkl_vtoc.v_version == V_VERSION) { 21047c478bd9Sstevel@tonic-gate bcopy(search_label.dkl_vtoc.v_volume, 21057c478bd9Sstevel@tonic-gate search_disk->v_volume, LEN_DKL_VVOL); 21067c478bd9Sstevel@tonic-gate search_parts->vtoc = search_label.dkl_vtoc; 21077c478bd9Sstevel@tonic-gate } else { 21087c478bd9Sstevel@tonic-gate bzero(search_disk->v_volume, LEN_DKL_VVOL); 21097c478bd9Sstevel@tonic-gate set_vtoc_defaults(search_parts); 21107c478bd9Sstevel@tonic-gate } 21117c478bd9Sstevel@tonic-gate /* 21127c478bd9Sstevel@tonic-gate * By this time we have a known partitition map. Link the 21137c478bd9Sstevel@tonic-gate * disk to the partition map. 21147c478bd9Sstevel@tonic-gate */ 21157c478bd9Sstevel@tonic-gate search_disk->disk_parts = search_parts; 21167c478bd9Sstevel@tonic-gate } 21177c478bd9Sstevel@tonic-gate 21187c478bd9Sstevel@tonic-gate 21197c478bd9Sstevel@tonic-gate /* 21207c478bd9Sstevel@tonic-gate * Search the disk list for a disk with the identical configuration. 21217c478bd9Sstevel@tonic-gate * Return true if one is found. 21227c478bd9Sstevel@tonic-gate */ 21237c478bd9Sstevel@tonic-gate static int 21247c478bd9Sstevel@tonic-gate disk_is_known(struct dk_cinfo *dkinfo) 21257c478bd9Sstevel@tonic-gate { 21267c478bd9Sstevel@tonic-gate struct disk_info *dp; 21277c478bd9Sstevel@tonic-gate 21287c478bd9Sstevel@tonic-gate dp = disk_list; 21297c478bd9Sstevel@tonic-gate while (dp != NULL) { 21307c478bd9Sstevel@tonic-gate if (dp->disk_dkinfo.dki_ctype == dkinfo->dki_ctype && 21317c478bd9Sstevel@tonic-gate dp->disk_dkinfo.dki_cnum == dkinfo->dki_cnum && 21327c478bd9Sstevel@tonic-gate dp->disk_dkinfo.dki_unit == dkinfo->dki_unit && 21337c478bd9Sstevel@tonic-gate strcmp(dp->disk_dkinfo.dki_dname, 21347c478bd9Sstevel@tonic-gate dkinfo->dki_dname) == 0) { 21357c478bd9Sstevel@tonic-gate return (1); 21367c478bd9Sstevel@tonic-gate } 21377c478bd9Sstevel@tonic-gate dp = dp->disk_next; 21387c478bd9Sstevel@tonic-gate } 21397c478bd9Sstevel@tonic-gate return (0); 21407c478bd9Sstevel@tonic-gate } 21417c478bd9Sstevel@tonic-gate 21427c478bd9Sstevel@tonic-gate 21437c478bd9Sstevel@tonic-gate /* 21447c478bd9Sstevel@tonic-gate * This routine checks to see if a given disk type matches the type 21457c478bd9Sstevel@tonic-gate * in the disk label. 21467c478bd9Sstevel@tonic-gate */ 21477c478bd9Sstevel@tonic-gate int 21487c478bd9Sstevel@tonic-gate dtype_match(label, dtype) 21497c478bd9Sstevel@tonic-gate register struct dk_label *label; 21507c478bd9Sstevel@tonic-gate register struct disk_type *dtype; 21517c478bd9Sstevel@tonic-gate { 21527c478bd9Sstevel@tonic-gate 21537c478bd9Sstevel@tonic-gate if (dtype->dtype_asciilabel == NULL) { 21547c478bd9Sstevel@tonic-gate return (0); 21557c478bd9Sstevel@tonic-gate } 21567c478bd9Sstevel@tonic-gate 21577c478bd9Sstevel@tonic-gate /* 21587c478bd9Sstevel@tonic-gate * If the any of the physical characteristics are different, or 21597c478bd9Sstevel@tonic-gate * the name is different, it doesn't match. 21607c478bd9Sstevel@tonic-gate */ 21617c478bd9Sstevel@tonic-gate if ((strcmp(label->dkl_asciilabel, dtype->dtype_asciilabel) != 0) || 21627c478bd9Sstevel@tonic-gate (label->dkl_ncyl != dtype->dtype_ncyl) || 21637c478bd9Sstevel@tonic-gate (label->dkl_acyl != dtype->dtype_acyl) || 21647c478bd9Sstevel@tonic-gate (label->dkl_nhead != dtype->dtype_nhead) || 21657c478bd9Sstevel@tonic-gate (label->dkl_nsect != dtype->dtype_nsect)) { 21667c478bd9Sstevel@tonic-gate return (0); 21677c478bd9Sstevel@tonic-gate } 21687c478bd9Sstevel@tonic-gate /* 21697c478bd9Sstevel@tonic-gate * If those are all identical, assume it's a match. 21707c478bd9Sstevel@tonic-gate */ 21717c478bd9Sstevel@tonic-gate return (1); 21727c478bd9Sstevel@tonic-gate } 21737c478bd9Sstevel@tonic-gate 21747c478bd9Sstevel@tonic-gate /* 21757c478bd9Sstevel@tonic-gate * This routine checks to see if a given partition map matches the map 21767c478bd9Sstevel@tonic-gate * in the disk label. 21777c478bd9Sstevel@tonic-gate */ 21787c478bd9Sstevel@tonic-gate int 21797c478bd9Sstevel@tonic-gate parts_match(label, pinfo) 21807c478bd9Sstevel@tonic-gate register struct dk_label *label; 21817c478bd9Sstevel@tonic-gate register struct partition_info *pinfo; 21827c478bd9Sstevel@tonic-gate { 21837c478bd9Sstevel@tonic-gate int i; 21847c478bd9Sstevel@tonic-gate 21857c478bd9Sstevel@tonic-gate /* 21867c478bd9Sstevel@tonic-gate * If any of the partition entries is different, it doesn't match. 21877c478bd9Sstevel@tonic-gate */ 21887c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) 21897c478bd9Sstevel@tonic-gate 21907c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 21917c478bd9Sstevel@tonic-gate if ((label->dkl_map[i].dkl_cylno != 21927c478bd9Sstevel@tonic-gate pinfo->pinfo_map[i].dkl_cylno) || 21937c478bd9Sstevel@tonic-gate (label->dkl_map[i].dkl_nblk != 21947c478bd9Sstevel@tonic-gate pinfo->pinfo_map[i].dkl_nblk)) 21957c478bd9Sstevel@tonic-gate 21967c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 21977c478bd9Sstevel@tonic-gate if ((pinfo->pinfo_map[i].dkl_cylno != 21987c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_start / 21997c478bd9Sstevel@tonic-gate (label->dkl_nhead * label->dkl_nsect)) || 22007c478bd9Sstevel@tonic-gate (pinfo->pinfo_map[i].dkl_nblk != 22017c478bd9Sstevel@tonic-gate label->dkl_vtoc.v_part[i].p_size)) 22027c478bd9Sstevel@tonic-gate #else 22037c478bd9Sstevel@tonic-gate #error No VTOC format defined. 22047c478bd9Sstevel@tonic-gate #endif 22057c478bd9Sstevel@tonic-gate return (0); 22067c478bd9Sstevel@tonic-gate /* 22077c478bd9Sstevel@tonic-gate * Compare the vtoc information for a match 22087c478bd9Sstevel@tonic-gate * Do not require the volume name to be equal, for a match! 22097c478bd9Sstevel@tonic-gate */ 22107c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_version != pinfo->vtoc.v_version) 22117c478bd9Sstevel@tonic-gate return (0); 22127c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_nparts != pinfo->vtoc.v_nparts) 22137c478bd9Sstevel@tonic-gate return (0); 22147c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 22157c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_part[i].p_tag != 22167c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[i].p_tag) 22177c478bd9Sstevel@tonic-gate return (0); 22187c478bd9Sstevel@tonic-gate if (label->dkl_vtoc.v_part[i].p_flag != 22197c478bd9Sstevel@tonic-gate pinfo->vtoc.v_part[i].p_flag) 22207c478bd9Sstevel@tonic-gate return (0); 22217c478bd9Sstevel@tonic-gate } 22227c478bd9Sstevel@tonic-gate /* 22237c478bd9Sstevel@tonic-gate * If they are all identical, it's a match. 22247c478bd9Sstevel@tonic-gate */ 22257c478bd9Sstevel@tonic-gate return (1); 22267c478bd9Sstevel@tonic-gate } 22277c478bd9Sstevel@tonic-gate 22287c478bd9Sstevel@tonic-gate /* 22297c478bd9Sstevel@tonic-gate * This routine checks to see if the given disk name refers to the disk 22307c478bd9Sstevel@tonic-gate * in the given disk structure. 22317c478bd9Sstevel@tonic-gate */ 22327c478bd9Sstevel@tonic-gate int 22337c478bd9Sstevel@tonic-gate diskname_match(char *name, struct disk_info *disk) 22347c478bd9Sstevel@tonic-gate { 22357c478bd9Sstevel@tonic-gate struct dk_cinfo dkinfo; 22367c478bd9Sstevel@tonic-gate char s[MAXPATHLEN]; 22377c478bd9Sstevel@tonic-gate int fd; 22387c478bd9Sstevel@tonic-gate 22397c478bd9Sstevel@tonic-gate /* 22407c478bd9Sstevel@tonic-gate * Match the name of the disk in the disk_info structure 22417c478bd9Sstevel@tonic-gate */ 22427c478bd9Sstevel@tonic-gate if (strcmp(name, disk->disk_name) == 0) { 22437c478bd9Sstevel@tonic-gate return (1); 22447c478bd9Sstevel@tonic-gate } 22457c478bd9Sstevel@tonic-gate 22467c478bd9Sstevel@tonic-gate /* 22477c478bd9Sstevel@tonic-gate * Check to see if it's a 4.x file name in the /dev 22487c478bd9Sstevel@tonic-gate * directory on 5.0. Here, we only accept the 22497c478bd9Sstevel@tonic-gate * canonicalized form: sd0. 22507c478bd9Sstevel@tonic-gate */ 22517c478bd9Sstevel@tonic-gate if (canonical4x_name(name) == 0) { 22527c478bd9Sstevel@tonic-gate return (0); 22537c478bd9Sstevel@tonic-gate } 22547c478bd9Sstevel@tonic-gate 22557c478bd9Sstevel@tonic-gate (void) strcpy(s, "/dev/r"); 22567c478bd9Sstevel@tonic-gate (void) strcat(s, name); 22577c478bd9Sstevel@tonic-gate (void) strcat(s, "c"); 22587c478bd9Sstevel@tonic-gate 22597c478bd9Sstevel@tonic-gate if ((fd = open_disk(s, O_RDWR | O_NDELAY)) < 0) { 22607c478bd9Sstevel@tonic-gate return (0); 22617c478bd9Sstevel@tonic-gate } 22627c478bd9Sstevel@tonic-gate 22637c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) { 22647c478bd9Sstevel@tonic-gate (void) close(fd); 22657c478bd9Sstevel@tonic-gate return (0); 22667c478bd9Sstevel@tonic-gate } 22677c478bd9Sstevel@tonic-gate (void) close(fd); 22687c478bd9Sstevel@tonic-gate 22697c478bd9Sstevel@tonic-gate if (disk->disk_dkinfo.dki_ctype == dkinfo.dki_ctype && 22707c478bd9Sstevel@tonic-gate disk->disk_dkinfo.dki_cnum == dkinfo.dki_cnum && 22717c478bd9Sstevel@tonic-gate disk->disk_dkinfo.dki_unit == dkinfo.dki_unit && 22727c478bd9Sstevel@tonic-gate strcmp(disk->disk_dkinfo.dki_dname, 22737c478bd9Sstevel@tonic-gate dkinfo.dki_dname) == 0) { 22747c478bd9Sstevel@tonic-gate return (1); 22757c478bd9Sstevel@tonic-gate } 22767c478bd9Sstevel@tonic-gate return (0); 22777c478bd9Sstevel@tonic-gate } 22787c478bd9Sstevel@tonic-gate 22797c478bd9Sstevel@tonic-gate 22807c478bd9Sstevel@tonic-gate static void 22817c478bd9Sstevel@tonic-gate datafile_error(char *errmsg, char *token) 22827c478bd9Sstevel@tonic-gate { 22837c478bd9Sstevel@tonic-gate int token_type; 22847c478bd9Sstevel@tonic-gate TOKEN token_buf; 22857c478bd9Sstevel@tonic-gate 22867c478bd9Sstevel@tonic-gate /* 22877c478bd9Sstevel@tonic-gate * Allow us to get by controllers that the other platforms don't 22887c478bd9Sstevel@tonic-gate * know about. 22897c478bd9Sstevel@tonic-gate */ 22907c478bd9Sstevel@tonic-gate if (errmsg != NULL) { 22917c478bd9Sstevel@tonic-gate err_print(errmsg, token); 22927c478bd9Sstevel@tonic-gate err_print(" - %s (%d)\n", file_name, data_lineno); 22937c478bd9Sstevel@tonic-gate } 22947c478bd9Sstevel@tonic-gate 22957c478bd9Sstevel@tonic-gate /* 22967c478bd9Sstevel@tonic-gate * Re-sync the parsing at the beginning of the next line 22977c478bd9Sstevel@tonic-gate * unless of course we're already there. 22987c478bd9Sstevel@tonic-gate */ 22997c478bd9Sstevel@tonic-gate if (last_token_type != SUP_EOF && last_token_type != SUP_EOL) { 23007c478bd9Sstevel@tonic-gate do { 23017c478bd9Sstevel@tonic-gate token_type = sup_gettoken(token_buf); 23027c478bd9Sstevel@tonic-gate } while (token_type != SUP_EOF && token_type != SUP_EOL); 23037c478bd9Sstevel@tonic-gate 23047c478bd9Sstevel@tonic-gate if (token_type == SUP_EOF) { 23057c478bd9Sstevel@tonic-gate sup_pushtoken(token_buf, token_type); 23067c478bd9Sstevel@tonic-gate } 23077c478bd9Sstevel@tonic-gate } 23087c478bd9Sstevel@tonic-gate } 23097c478bd9Sstevel@tonic-gate 23107c478bd9Sstevel@tonic-gate 23117c478bd9Sstevel@tonic-gate /* 23127c478bd9Sstevel@tonic-gate * Search through all defined disk types for duplicate entries 23137c478bd9Sstevel@tonic-gate * that are inconsistent with each other. Disks with different 23147c478bd9Sstevel@tonic-gate * characteristics should be named differently. 23157c478bd9Sstevel@tonic-gate * Note that this function only checks for duplicate disks 23167c478bd9Sstevel@tonic-gate * for the same controller. It's possible to have two disks with 23177c478bd9Sstevel@tonic-gate * the same name, but defined for different controllers. 23187c478bd9Sstevel@tonic-gate * That may or may not be a problem... 23197c478bd9Sstevel@tonic-gate */ 23207c478bd9Sstevel@tonic-gate static void 23217c478bd9Sstevel@tonic-gate search_duplicate_dtypes() 23227c478bd9Sstevel@tonic-gate { 23237c478bd9Sstevel@tonic-gate struct disk_type *dp1; 23247c478bd9Sstevel@tonic-gate struct disk_type *dp2; 23257c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 23267c478bd9Sstevel@tonic-gate 23277c478bd9Sstevel@tonic-gate mlp = controlp; 23287c478bd9Sstevel@tonic-gate 23297c478bd9Sstevel@tonic-gate while (mlp != NULL) { 23307c478bd9Sstevel@tonic-gate dp1 = mlp->ctlr_type->ctype_dlist; 23317c478bd9Sstevel@tonic-gate while (dp1 != NULL) { 23327c478bd9Sstevel@tonic-gate dp2 = dp1->dtype_next; 23337c478bd9Sstevel@tonic-gate while (dp2 != NULL) { 23347c478bd9Sstevel@tonic-gate check_dtypes_for_inconsistency(dp1, dp2); 23357c478bd9Sstevel@tonic-gate dp2 = dp2->dtype_next; 23367c478bd9Sstevel@tonic-gate } 23377c478bd9Sstevel@tonic-gate dp1 = dp1->dtype_next; 23387c478bd9Sstevel@tonic-gate } 23397c478bd9Sstevel@tonic-gate mlp = mlp->next; 23407c478bd9Sstevel@tonic-gate } 23417c478bd9Sstevel@tonic-gate } 23427c478bd9Sstevel@tonic-gate 23437c478bd9Sstevel@tonic-gate 23447c478bd9Sstevel@tonic-gate /* 23457c478bd9Sstevel@tonic-gate * Search through all defined partition types for duplicate entries 23467c478bd9Sstevel@tonic-gate * that are inconsistent with each other. Partitions with different 23477c478bd9Sstevel@tonic-gate * characteristics should be named differently. 23487c478bd9Sstevel@tonic-gate * Note that this function only checks for duplicate partitions 23497c478bd9Sstevel@tonic-gate * for the same disk. It's possible to have two partitions with 23507c478bd9Sstevel@tonic-gate * the same name, but defined for different disks. 23517c478bd9Sstevel@tonic-gate * That may or may not be a problem... 23527c478bd9Sstevel@tonic-gate */ 23537c478bd9Sstevel@tonic-gate static void 23547c478bd9Sstevel@tonic-gate search_duplicate_pinfo() 23557c478bd9Sstevel@tonic-gate { 23567c478bd9Sstevel@tonic-gate struct disk_type *dp; 23577c478bd9Sstevel@tonic-gate struct partition_info *pp1; 23587c478bd9Sstevel@tonic-gate struct partition_info *pp2; 23597c478bd9Sstevel@tonic-gate struct mctlr_list *mlp; 23607c478bd9Sstevel@tonic-gate 23617c478bd9Sstevel@tonic-gate mlp = controlp; 23627c478bd9Sstevel@tonic-gate 23637c478bd9Sstevel@tonic-gate while (mlp != NULL) { 23647c478bd9Sstevel@tonic-gate dp = mlp->ctlr_type->ctype_dlist; 23657c478bd9Sstevel@tonic-gate while (dp != NULL) { 23667c478bd9Sstevel@tonic-gate pp1 = dp->dtype_plist; 23677c478bd9Sstevel@tonic-gate while (pp1 != NULL) { 23687c478bd9Sstevel@tonic-gate pp2 = pp1->pinfo_next; 23697c478bd9Sstevel@tonic-gate while (pp2 != NULL) { 23707c478bd9Sstevel@tonic-gate check_pinfo_for_inconsistency(pp1, pp2); 23717c478bd9Sstevel@tonic-gate pp2 = pp2->pinfo_next; 23727c478bd9Sstevel@tonic-gate } 23737c478bd9Sstevel@tonic-gate pp1 = pp1->pinfo_next; 23747c478bd9Sstevel@tonic-gate } 23757c478bd9Sstevel@tonic-gate dp = dp->dtype_next; 23767c478bd9Sstevel@tonic-gate } 23777c478bd9Sstevel@tonic-gate mlp = mlp->next; 23787c478bd9Sstevel@tonic-gate } 23797c478bd9Sstevel@tonic-gate } 23807c478bd9Sstevel@tonic-gate 23817c478bd9Sstevel@tonic-gate 23827c478bd9Sstevel@tonic-gate /* 23837c478bd9Sstevel@tonic-gate * Determine if two particular disk definitions are inconsistent. 23847c478bd9Sstevel@tonic-gate * Ie: same name, but different characteristics. 23857c478bd9Sstevel@tonic-gate * If so, print an error message and abort. 23867c478bd9Sstevel@tonic-gate */ 23877c478bd9Sstevel@tonic-gate static void 23887c478bd9Sstevel@tonic-gate check_dtypes_for_inconsistency(dp1, dp2) 23897c478bd9Sstevel@tonic-gate struct disk_type *dp1; 23907c478bd9Sstevel@tonic-gate struct disk_type *dp2; 23917c478bd9Sstevel@tonic-gate { 23927c478bd9Sstevel@tonic-gate int i; 23937c478bd9Sstevel@tonic-gate int result; 23947c478bd9Sstevel@tonic-gate struct chg_list *cp1; 23957c478bd9Sstevel@tonic-gate struct chg_list *cp2; 23967c478bd9Sstevel@tonic-gate 23977c478bd9Sstevel@tonic-gate 23987c478bd9Sstevel@tonic-gate /* 23997c478bd9Sstevel@tonic-gate * If the name's different, we're ok 24007c478bd9Sstevel@tonic-gate */ 24017c478bd9Sstevel@tonic-gate if (strcmp(dp1->dtype_asciilabel, dp2->dtype_asciilabel) != 0) { 24027c478bd9Sstevel@tonic-gate return; 24037c478bd9Sstevel@tonic-gate } 24047c478bd9Sstevel@tonic-gate 24057c478bd9Sstevel@tonic-gate /* 24067c478bd9Sstevel@tonic-gate * Compare all the disks' characteristics 24077c478bd9Sstevel@tonic-gate */ 24087c478bd9Sstevel@tonic-gate result = 0; 24097c478bd9Sstevel@tonic-gate result |= (dp1->dtype_flags != dp2->dtype_flags); 24107c478bd9Sstevel@tonic-gate result |= (dp1->dtype_options != dp2->dtype_options); 24117c478bd9Sstevel@tonic-gate result |= (dp1->dtype_fmt_time != dp2->dtype_fmt_time); 24127c478bd9Sstevel@tonic-gate result |= (dp1->dtype_bpt != dp2->dtype_bpt); 24137c478bd9Sstevel@tonic-gate result |= (dp1->dtype_ncyl != dp2->dtype_ncyl); 24147c478bd9Sstevel@tonic-gate result |= (dp1->dtype_acyl != dp2->dtype_acyl); 24157c478bd9Sstevel@tonic-gate result |= (dp1->dtype_pcyl != dp2->dtype_pcyl); 24167c478bd9Sstevel@tonic-gate result |= (dp1->dtype_nhead != dp2->dtype_nhead); 24177c478bd9Sstevel@tonic-gate result |= (dp1->dtype_nsect != dp2->dtype_nsect); 24187c478bd9Sstevel@tonic-gate result |= (dp1->dtype_rpm != dp2->dtype_rpm); 24197c478bd9Sstevel@tonic-gate result |= (dp1->dtype_cyl_skew != dp2->dtype_cyl_skew); 24207c478bd9Sstevel@tonic-gate result |= (dp1->dtype_trk_skew != dp2->dtype_trk_skew); 24217c478bd9Sstevel@tonic-gate result |= (dp1->dtype_trks_zone != dp2->dtype_trks_zone); 24227c478bd9Sstevel@tonic-gate result |= (dp1->dtype_atrks != dp2->dtype_atrks); 24237c478bd9Sstevel@tonic-gate result |= (dp1->dtype_asect != dp2->dtype_asect); 24247c478bd9Sstevel@tonic-gate result |= (dp1->dtype_cache != dp2->dtype_cache); 24257c478bd9Sstevel@tonic-gate result |= (dp1->dtype_threshold != dp2->dtype_threshold); 24267c478bd9Sstevel@tonic-gate result |= (dp1->dtype_read_retries != dp2->dtype_read_retries); 24277c478bd9Sstevel@tonic-gate result |= (dp1->dtype_write_retries != dp2->dtype_write_retries); 24287c478bd9Sstevel@tonic-gate result |= (dp1->dtype_prefetch_min != dp2->dtype_prefetch_min); 24297c478bd9Sstevel@tonic-gate result |= (dp1->dtype_prefetch_max != dp2->dtype_prefetch_max); 24307c478bd9Sstevel@tonic-gate for (i = 0; i < NSPECIFICS; i++) { 24317c478bd9Sstevel@tonic-gate result |= (dp1->dtype_specifics[i] != dp2->dtype_specifics[i]); 24327c478bd9Sstevel@tonic-gate } 24337c478bd9Sstevel@tonic-gate 24347c478bd9Sstevel@tonic-gate cp1 = dp1->dtype_chglist; 24357c478bd9Sstevel@tonic-gate cp2 = dp2->dtype_chglist; 24367c478bd9Sstevel@tonic-gate while (cp1 != NULL && cp2 != NULL) { 24377c478bd9Sstevel@tonic-gate if (cp1 == NULL || cp2 == NULL) { 24387c478bd9Sstevel@tonic-gate result = 1; 24397c478bd9Sstevel@tonic-gate break; 24407c478bd9Sstevel@tonic-gate } 24417c478bd9Sstevel@tonic-gate result |= (cp1->pageno != cp2->pageno); 24427c478bd9Sstevel@tonic-gate result |= (cp1->byteno != cp2->byteno); 24437c478bd9Sstevel@tonic-gate result |= (cp1->mode != cp2->mode); 24447c478bd9Sstevel@tonic-gate result |= (cp1->value != cp2->value); 24457c478bd9Sstevel@tonic-gate cp1 = cp1->next; 24467c478bd9Sstevel@tonic-gate cp2 = cp2->next; 24477c478bd9Sstevel@tonic-gate } 24487c478bd9Sstevel@tonic-gate 24497c478bd9Sstevel@tonic-gate if (result) { 24507c478bd9Sstevel@tonic-gate err_print("Inconsistent definitions for disk type '%s'\n", 24517c478bd9Sstevel@tonic-gate dp1->dtype_asciilabel); 24527c478bd9Sstevel@tonic-gate if (dp1->dtype_filename != NULL && 24537c478bd9Sstevel@tonic-gate dp2->dtype_filename != NULL) { 24547c478bd9Sstevel@tonic-gate err_print("%s (%d) - %s (%d)\n", 24557c478bd9Sstevel@tonic-gate dp1->dtype_filename, dp1->dtype_lineno, 24567c478bd9Sstevel@tonic-gate dp2->dtype_filename, dp2->dtype_lineno); 24577c478bd9Sstevel@tonic-gate } 24587c478bd9Sstevel@tonic-gate fullabort(); 24597c478bd9Sstevel@tonic-gate } 24607c478bd9Sstevel@tonic-gate } 24617c478bd9Sstevel@tonic-gate 24627c478bd9Sstevel@tonic-gate 24637c478bd9Sstevel@tonic-gate /* 24647c478bd9Sstevel@tonic-gate * Determine if two particular partition definitions are inconsistent. 24657c478bd9Sstevel@tonic-gate * Ie: same name, but different characteristics. 24667c478bd9Sstevel@tonic-gate * If so, print an error message and abort. 24677c478bd9Sstevel@tonic-gate */ 24687c478bd9Sstevel@tonic-gate static void 24697c478bd9Sstevel@tonic-gate check_pinfo_for_inconsistency(pp1, pp2) 24707c478bd9Sstevel@tonic-gate struct partition_info *pp1; 24717c478bd9Sstevel@tonic-gate struct partition_info *pp2; 24727c478bd9Sstevel@tonic-gate { 24737c478bd9Sstevel@tonic-gate int i; 24747c478bd9Sstevel@tonic-gate int result; 24757c478bd9Sstevel@tonic-gate struct dk_map32 *map1; 24767c478bd9Sstevel@tonic-gate struct dk_map32 *map2; 24777c478bd9Sstevel@tonic-gate 24787c478bd9Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8) 24797c478bd9Sstevel@tonic-gate struct dk_map2 *vp1; 24807c478bd9Sstevel@tonic-gate struct dk_map2 *vp2; 24817c478bd9Sstevel@tonic-gate 24827c478bd9Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_16) 24837c478bd9Sstevel@tonic-gate struct dkl_partition *vp1; 24847c478bd9Sstevel@tonic-gate struct dkl_partition *vp2; 24857c478bd9Sstevel@tonic-gate #else 24867c478bd9Sstevel@tonic-gate #error No VTOC layout defined. 24877c478bd9Sstevel@tonic-gate #endif /* defined(_SUNOS_VTOC_8) */ 24887c478bd9Sstevel@tonic-gate 24897c478bd9Sstevel@tonic-gate /* 24907c478bd9Sstevel@tonic-gate * If the name's different, we're ok 24917c478bd9Sstevel@tonic-gate */ 24927c478bd9Sstevel@tonic-gate if (strcmp(pp1->pinfo_name, pp2->pinfo_name) != 0) { 24937c478bd9Sstevel@tonic-gate return; 24947c478bd9Sstevel@tonic-gate } 24957c478bd9Sstevel@tonic-gate 24967c478bd9Sstevel@tonic-gate /* 24977c478bd9Sstevel@tonic-gate * Compare all the partitions' characteristics 24987c478bd9Sstevel@tonic-gate */ 24997c478bd9Sstevel@tonic-gate result = 0; 25007c478bd9Sstevel@tonic-gate map1 = pp1->pinfo_map; 25017c478bd9Sstevel@tonic-gate map2 = pp2->pinfo_map; 25027c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++, map1++, map2++) { 25037c478bd9Sstevel@tonic-gate result |= (map1->dkl_cylno != map2->dkl_cylno); 25047c478bd9Sstevel@tonic-gate result |= (map1->dkl_nblk != map2->dkl_nblk); 25057c478bd9Sstevel@tonic-gate } 25067c478bd9Sstevel@tonic-gate 25077c478bd9Sstevel@tonic-gate /* 25087c478bd9Sstevel@tonic-gate * Compare the significant portions of the vtoc information 25097c478bd9Sstevel@tonic-gate */ 25107c478bd9Sstevel@tonic-gate vp1 = pp1->vtoc.v_part; 25117c478bd9Sstevel@tonic-gate vp2 = pp2->vtoc.v_part; 25127c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++, vp1++, vp2++) { 25137c478bd9Sstevel@tonic-gate result |= (vp1->p_tag != vp2->p_tag); 25147c478bd9Sstevel@tonic-gate result |= (vp1->p_flag != vp2->p_flag); 25157c478bd9Sstevel@tonic-gate } 25167c478bd9Sstevel@tonic-gate 25177c478bd9Sstevel@tonic-gate if (result) { 25187c478bd9Sstevel@tonic-gate err_print("Inconsistent definitions for partition type '%s'\n", 25197c478bd9Sstevel@tonic-gate pp1->pinfo_name); 25207c478bd9Sstevel@tonic-gate if (pp1->pinfo_filename != NULL && 25217c478bd9Sstevel@tonic-gate pp2->pinfo_filename != NULL) { 25227c478bd9Sstevel@tonic-gate err_print("%s (%d) - %s (%d)\n", 25237c478bd9Sstevel@tonic-gate pp1->pinfo_filename, pp1->pinfo_lineno, 25247c478bd9Sstevel@tonic-gate pp2->pinfo_filename, pp2->pinfo_lineno); 25257c478bd9Sstevel@tonic-gate } 25267c478bd9Sstevel@tonic-gate fullabort(); 25277c478bd9Sstevel@tonic-gate } 25287c478bd9Sstevel@tonic-gate } 25297c478bd9Sstevel@tonic-gate 25307c478bd9Sstevel@tonic-gate /* 25317c478bd9Sstevel@tonic-gate * Convert a string of digits into a block number. 25327c478bd9Sstevel@tonic-gate * The digits are assumed to be a block number unless the 25337c478bd9Sstevel@tonic-gate * the string is terminated by 'c', in which case it is 25347c478bd9Sstevel@tonic-gate * assumed to be in units of cylinders. Accept a 'b' 25357c478bd9Sstevel@tonic-gate * to explictly specify blocks, for consistency. 25367c478bd9Sstevel@tonic-gate * 25377c478bd9Sstevel@tonic-gate * NB: uses the macro spc(), which requires that the 25387c478bd9Sstevel@tonic-gate * globals nhead/nsect/acyl be set up correctly. 25397c478bd9Sstevel@tonic-gate * 25407c478bd9Sstevel@tonic-gate * Returns -1 in the case of an error. 25417c478bd9Sstevel@tonic-gate */ 25427c478bd9Sstevel@tonic-gate static int 25437c478bd9Sstevel@tonic-gate str2blks(char *str) 25447c478bd9Sstevel@tonic-gate { 25457c478bd9Sstevel@tonic-gate int blks; 25467c478bd9Sstevel@tonic-gate char *p; 25477c478bd9Sstevel@tonic-gate 25487c478bd9Sstevel@tonic-gate blks = (int)strtol(str, &p, 0); 25497c478bd9Sstevel@tonic-gate /* 25507c478bd9Sstevel@tonic-gate * Check what terminated the conversion. 25517c478bd9Sstevel@tonic-gate */ 25527c478bd9Sstevel@tonic-gate if (*p != 0) { 25537c478bd9Sstevel@tonic-gate /* 25547c478bd9Sstevel@tonic-gate * Units specifier of 'c': convert cylinders to blocks 25557c478bd9Sstevel@tonic-gate */ 25567c478bd9Sstevel@tonic-gate if (*p == 'c') { 25577c478bd9Sstevel@tonic-gate p++; 25587c478bd9Sstevel@tonic-gate blks = blks * spc(); 25597c478bd9Sstevel@tonic-gate /* 25607c478bd9Sstevel@tonic-gate * Ignore a 'b' specifier. 25617c478bd9Sstevel@tonic-gate */ 25627c478bd9Sstevel@tonic-gate } else if (*p == 'b') { 25637c478bd9Sstevel@tonic-gate p++; 25647c478bd9Sstevel@tonic-gate } 25657c478bd9Sstevel@tonic-gate /* 25667c478bd9Sstevel@tonic-gate * Anthing left over is an error 25677c478bd9Sstevel@tonic-gate */ 25687c478bd9Sstevel@tonic-gate if (*p != 0) { 25697c478bd9Sstevel@tonic-gate blks = -1; 25707c478bd9Sstevel@tonic-gate } 25717c478bd9Sstevel@tonic-gate } 25727c478bd9Sstevel@tonic-gate 25737c478bd9Sstevel@tonic-gate return (blks); 25747c478bd9Sstevel@tonic-gate } 25757c478bd9Sstevel@tonic-gate /* 25767c478bd9Sstevel@tonic-gate * Convert a string of digits into a cylinder number. 25777c478bd9Sstevel@tonic-gate * Accept a an optional 'c' specifier, for consistency. 25787c478bd9Sstevel@tonic-gate * 25797c478bd9Sstevel@tonic-gate * Returns -1 in the case of an error. 25807c478bd9Sstevel@tonic-gate */ 25817c478bd9Sstevel@tonic-gate int 25827c478bd9Sstevel@tonic-gate str2cyls(char *str) 25837c478bd9Sstevel@tonic-gate { 25847c478bd9Sstevel@tonic-gate int cyls; 25857c478bd9Sstevel@tonic-gate char *p; 25867c478bd9Sstevel@tonic-gate 25877c478bd9Sstevel@tonic-gate cyls = (int)strtol(str, &p, 0); 25887c478bd9Sstevel@tonic-gate /* 25897c478bd9Sstevel@tonic-gate * Check what terminated the conversion. 25907c478bd9Sstevel@tonic-gate */ 25917c478bd9Sstevel@tonic-gate if (*p != 0) { 25927c478bd9Sstevel@tonic-gate /* 25937c478bd9Sstevel@tonic-gate * Units specifier of 'c': convert cylinders to blocks 25947c478bd9Sstevel@tonic-gate */ 25957c478bd9Sstevel@tonic-gate if (*p == 'c') { 25967c478bd9Sstevel@tonic-gate p++; 25977c478bd9Sstevel@tonic-gate } 25987c478bd9Sstevel@tonic-gate /* 25997c478bd9Sstevel@tonic-gate * Anthing left over is an error 26007c478bd9Sstevel@tonic-gate */ 26017c478bd9Sstevel@tonic-gate if (*p != 0) { 26027c478bd9Sstevel@tonic-gate cyls = -1; 26037c478bd9Sstevel@tonic-gate } 26047c478bd9Sstevel@tonic-gate } 26057c478bd9Sstevel@tonic-gate 26067c478bd9Sstevel@tonic-gate return (cyls); 26077c478bd9Sstevel@tonic-gate } 26087c478bd9Sstevel@tonic-gate 26097c478bd9Sstevel@tonic-gate 26107c478bd9Sstevel@tonic-gate /* 26117c478bd9Sstevel@tonic-gate * Create a new chg_list structure, and append it onto the 26127c478bd9Sstevel@tonic-gate * end of the current chg_list under construction. By 26137c478bd9Sstevel@tonic-gate * applying changes in the order in which listed in the 26147c478bd9Sstevel@tonic-gate * data file, the changes we make are deterministic. 26157c478bd9Sstevel@tonic-gate * Return a pointer to the new structure, so that the 26167c478bd9Sstevel@tonic-gate * caller can fill in the appropriate information. 26177c478bd9Sstevel@tonic-gate */ 26187c478bd9Sstevel@tonic-gate static struct chg_list * 26197c478bd9Sstevel@tonic-gate new_chg_list(struct disk_type *disk) 26207c478bd9Sstevel@tonic-gate { 26217c478bd9Sstevel@tonic-gate struct chg_list *cp; 26227c478bd9Sstevel@tonic-gate struct chg_list *nc; 26237c478bd9Sstevel@tonic-gate 26247c478bd9Sstevel@tonic-gate nc = zalloc(sizeof (struct chg_list)); 26257c478bd9Sstevel@tonic-gate 26267c478bd9Sstevel@tonic-gate if (disk->dtype_chglist == NULL) { 26277c478bd9Sstevel@tonic-gate disk->dtype_chglist = nc; 26287c478bd9Sstevel@tonic-gate } else { 26297c478bd9Sstevel@tonic-gate for (cp = disk->dtype_chglist; cp->next; cp = cp->next) 26307c478bd9Sstevel@tonic-gate ; 26317c478bd9Sstevel@tonic-gate cp->next = nc; 26327c478bd9Sstevel@tonic-gate } 26337c478bd9Sstevel@tonic-gate nc->next = NULL; 26347c478bd9Sstevel@tonic-gate return (nc); 26357c478bd9Sstevel@tonic-gate } 26367c478bd9Sstevel@tonic-gate 26377c478bd9Sstevel@tonic-gate 26387c478bd9Sstevel@tonic-gate /* 26397c478bd9Sstevel@tonic-gate * Follow symbolic links from the logical device name to 26407c478bd9Sstevel@tonic-gate * the /devfs physical device name. To be complete, we 26417c478bd9Sstevel@tonic-gate * handle the case of multiple links. This function 26427c478bd9Sstevel@tonic-gate * either returns NULL (no links, or some other error), 26437c478bd9Sstevel@tonic-gate * or the physical device name, alloc'ed on the heap. 26447c478bd9Sstevel@tonic-gate * 26457c478bd9Sstevel@tonic-gate * Note that the standard /devices prefix is stripped from 26467c478bd9Sstevel@tonic-gate * the final pathname, if present. The trailing options 26477c478bd9Sstevel@tonic-gate * are also removed (":c, raw"). 26487c478bd9Sstevel@tonic-gate */ 26497c478bd9Sstevel@tonic-gate static char * 26507c478bd9Sstevel@tonic-gate get_physical_name(char *path) 26517c478bd9Sstevel@tonic-gate { 26527c478bd9Sstevel@tonic-gate struct stat stbuf; 26537c478bd9Sstevel@tonic-gate int i; 26547c478bd9Sstevel@tonic-gate int level; 26557c478bd9Sstevel@tonic-gate char *p; 26567c478bd9Sstevel@tonic-gate char s[MAXPATHLEN]; 26577c478bd9Sstevel@tonic-gate char buf[MAXPATHLEN]; 26587c478bd9Sstevel@tonic-gate char dir[MAXPATHLEN]; 26597c478bd9Sstevel@tonic-gate char savedir[MAXPATHLEN]; 26607c478bd9Sstevel@tonic-gate char *result = NULL; 26617c478bd9Sstevel@tonic-gate 26627c478bd9Sstevel@tonic-gate if (getcwd(savedir, sizeof (savedir)) == NULL) { 26637c478bd9Sstevel@tonic-gate err_print("getcwd() failed - %s\n", strerror(errno)); 26647c478bd9Sstevel@tonic-gate return (NULL); 26657c478bd9Sstevel@tonic-gate } 26667c478bd9Sstevel@tonic-gate 26677c478bd9Sstevel@tonic-gate (void) strcpy(s, path); 26687c478bd9Sstevel@tonic-gate if ((p = strrchr(s, '/')) != NULL) { 26697c478bd9Sstevel@tonic-gate *p = 0; 26707c478bd9Sstevel@tonic-gate } 26717c478bd9Sstevel@tonic-gate if (s[0] == 0) { 26727c478bd9Sstevel@tonic-gate (void) strcpy(s, "/"); 26737c478bd9Sstevel@tonic-gate } 26747c478bd9Sstevel@tonic-gate if (chdir(s) == -1) { 26757c478bd9Sstevel@tonic-gate err_print("cannot chdir() to %s - %s\n", 26767c478bd9Sstevel@tonic-gate s, strerror(errno)); 26777c478bd9Sstevel@tonic-gate goto exit; 26787c478bd9Sstevel@tonic-gate } 26797c478bd9Sstevel@tonic-gate 26807c478bd9Sstevel@tonic-gate level = 0; 26817c478bd9Sstevel@tonic-gate (void) strcpy(s, path); 26827c478bd9Sstevel@tonic-gate for (;;) { 26837c478bd9Sstevel@tonic-gate /* 26847c478bd9Sstevel@tonic-gate * See if there's a real file out there. If not, 26857c478bd9Sstevel@tonic-gate * we have a dangling link and we ignore it. 26867c478bd9Sstevel@tonic-gate */ 26877c478bd9Sstevel@tonic-gate if (stat(s, &stbuf) == -1) { 26887c478bd9Sstevel@tonic-gate goto exit; 26897c478bd9Sstevel@tonic-gate } 26907c478bd9Sstevel@tonic-gate if (lstat(s, &stbuf) == -1) { 26917c478bd9Sstevel@tonic-gate err_print("%s: lstat() failed - %s\n", 26927c478bd9Sstevel@tonic-gate s, strerror(errno)); 26937c478bd9Sstevel@tonic-gate goto exit; 26947c478bd9Sstevel@tonic-gate } 26957c478bd9Sstevel@tonic-gate /* 26967c478bd9Sstevel@tonic-gate * If the file is not a link, we're done one 26977c478bd9Sstevel@tonic-gate * way or the other. If there were links, 26987c478bd9Sstevel@tonic-gate * return the full pathname of the resulting 26997c478bd9Sstevel@tonic-gate * file. 27007c478bd9Sstevel@tonic-gate */ 27017c478bd9Sstevel@tonic-gate if (!S_ISLNK(stbuf.st_mode)) { 27027c478bd9Sstevel@tonic-gate if (level > 0) { 27037c478bd9Sstevel@tonic-gate /* 27047c478bd9Sstevel@tonic-gate * Strip trailing options from the 27057c478bd9Sstevel@tonic-gate * physical device name 27067c478bd9Sstevel@tonic-gate */ 27077c478bd9Sstevel@tonic-gate if ((p = strrchr(s, ':')) != NULL) { 27087c478bd9Sstevel@tonic-gate *p = 0; 27097c478bd9Sstevel@tonic-gate } 27107c478bd9Sstevel@tonic-gate /* 27117c478bd9Sstevel@tonic-gate * Get the current directory, and 27127c478bd9Sstevel@tonic-gate * glue the pieces together. 27137c478bd9Sstevel@tonic-gate */ 27147c478bd9Sstevel@tonic-gate if (getcwd(dir, sizeof (dir)) == NULL) { 27157c478bd9Sstevel@tonic-gate err_print("getcwd() failed - %s\n", 27167c478bd9Sstevel@tonic-gate strerror(errno)); 27177c478bd9Sstevel@tonic-gate goto exit; 27187c478bd9Sstevel@tonic-gate } 27197c478bd9Sstevel@tonic-gate (void) strcat(dir, "/"); 27207c478bd9Sstevel@tonic-gate (void) strcat(dir, s); 27217c478bd9Sstevel@tonic-gate /* 27227c478bd9Sstevel@tonic-gate * If we have the standard fixed 27237c478bd9Sstevel@tonic-gate * /devices prefix, remove it. 27247c478bd9Sstevel@tonic-gate */ 27257c478bd9Sstevel@tonic-gate p = (strstr(dir, DEVFS_PREFIX) == dir) ? 27267c478bd9Sstevel@tonic-gate dir+strlen(DEVFS_PREFIX) : dir; 27277c478bd9Sstevel@tonic-gate result = alloc_string(p); 27287c478bd9Sstevel@tonic-gate } 27297c478bd9Sstevel@tonic-gate goto exit; 27307c478bd9Sstevel@tonic-gate } 27317c478bd9Sstevel@tonic-gate i = readlink(s, buf, sizeof (buf)); 27327c478bd9Sstevel@tonic-gate if (i == -1) { 27337c478bd9Sstevel@tonic-gate err_print("%s: readlink() failed - %s\n", 27347c478bd9Sstevel@tonic-gate s, strerror(errno)); 27357c478bd9Sstevel@tonic-gate goto exit; 27367c478bd9Sstevel@tonic-gate } 27377c478bd9Sstevel@tonic-gate level++; 27387c478bd9Sstevel@tonic-gate buf[i] = 0; 27397c478bd9Sstevel@tonic-gate 27407c478bd9Sstevel@tonic-gate /* 27417c478bd9Sstevel@tonic-gate * Break up the pathname into the directory 27427c478bd9Sstevel@tonic-gate * reference, if applicable and simple filename. 27437c478bd9Sstevel@tonic-gate * chdir()'ing to the directory allows us to 27447c478bd9Sstevel@tonic-gate * handle links with relative pathnames correctly. 27457c478bd9Sstevel@tonic-gate */ 27467c478bd9Sstevel@tonic-gate (void) strcpy(dir, buf); 27477c478bd9Sstevel@tonic-gate if ((p = strrchr(dir, '/')) != NULL) { 27487c478bd9Sstevel@tonic-gate *p = 0; 27497c478bd9Sstevel@tonic-gate if (chdir(dir) == -1) { 27507c478bd9Sstevel@tonic-gate err_print("cannot chdir() to %s - %s\n", 27517c478bd9Sstevel@tonic-gate dir, strerror(errno)); 27527c478bd9Sstevel@tonic-gate goto exit; 27537c478bd9Sstevel@tonic-gate } 27547c478bd9Sstevel@tonic-gate (void) strcpy(s, p+1); 27557c478bd9Sstevel@tonic-gate } else { 27567c478bd9Sstevel@tonic-gate (void) strcpy(s, buf); 27577c478bd9Sstevel@tonic-gate } 27587c478bd9Sstevel@tonic-gate } 27597c478bd9Sstevel@tonic-gate 27607c478bd9Sstevel@tonic-gate exit: 27617c478bd9Sstevel@tonic-gate if (chdir(savedir) == -1) { 27627c478bd9Sstevel@tonic-gate err_print("cannot chdir() to %s - %s\n", 27637c478bd9Sstevel@tonic-gate savedir, strerror(errno)); 27647c478bd9Sstevel@tonic-gate } 27657c478bd9Sstevel@tonic-gate 27667c478bd9Sstevel@tonic-gate return (result); 27677c478bd9Sstevel@tonic-gate } 27687c478bd9Sstevel@tonic-gate 27697c478bd9Sstevel@tonic-gate 27707c478bd9Sstevel@tonic-gate static void 27717c478bd9Sstevel@tonic-gate sort_disk_list() 27727c478bd9Sstevel@tonic-gate { 27737c478bd9Sstevel@tonic-gate int n; 27747c478bd9Sstevel@tonic-gate struct disk_info **disks; 27757c478bd9Sstevel@tonic-gate struct disk_info *d; 27767c478bd9Sstevel@tonic-gate struct disk_info **dp; 27777c478bd9Sstevel@tonic-gate struct disk_info **dp2; 27787c478bd9Sstevel@tonic-gate 27797c478bd9Sstevel@tonic-gate /* 27807c478bd9Sstevel@tonic-gate * Count the number of disks in the list 27817c478bd9Sstevel@tonic-gate */ 27827c478bd9Sstevel@tonic-gate n = 0; 27837c478bd9Sstevel@tonic-gate for (d = disk_list; d != NULL; d = d->disk_next) { 27847c478bd9Sstevel@tonic-gate n++; 27857c478bd9Sstevel@tonic-gate } 27867c478bd9Sstevel@tonic-gate if (n == 0) { 27877c478bd9Sstevel@tonic-gate return; 27887c478bd9Sstevel@tonic-gate } 27897c478bd9Sstevel@tonic-gate 27907c478bd9Sstevel@tonic-gate /* 27917c478bd9Sstevel@tonic-gate * Allocate a simple disk list array and fill it in 27927c478bd9Sstevel@tonic-gate */ 27937c478bd9Sstevel@tonic-gate disks = (struct disk_info **) 27947c478bd9Sstevel@tonic-gate zalloc((n+1) * sizeof (struct disk_info *)); 27957c478bd9Sstevel@tonic-gate 27967c478bd9Sstevel@tonic-gate dp = disks; 27977c478bd9Sstevel@tonic-gate for (d = disk_list; d != NULL; d = d->disk_next) { 27987c478bd9Sstevel@tonic-gate *dp++ = d; 27997c478bd9Sstevel@tonic-gate } 28007c478bd9Sstevel@tonic-gate *dp = NULL; 28017c478bd9Sstevel@tonic-gate 28027c478bd9Sstevel@tonic-gate /* 28037c478bd9Sstevel@tonic-gate * Sort the disk list array 28047c478bd9Sstevel@tonic-gate */ 28057c478bd9Sstevel@tonic-gate qsort((void *) disks, n, sizeof (struct disk_info *), 28067c478bd9Sstevel@tonic-gate disk_name_compare); 28077c478bd9Sstevel@tonic-gate 28087c478bd9Sstevel@tonic-gate /* 28097c478bd9Sstevel@tonic-gate * Rebuild the linked list disk list structure 28107c478bd9Sstevel@tonic-gate */ 28117c478bd9Sstevel@tonic-gate dp = disks; 28127c478bd9Sstevel@tonic-gate disk_list = *dp; 28137c478bd9Sstevel@tonic-gate dp2 = dp + 1; 28147c478bd9Sstevel@tonic-gate do { 28157c478bd9Sstevel@tonic-gate (*dp++)->disk_next = *dp2++; 28167c478bd9Sstevel@tonic-gate } while (*dp != NULL); 28177c478bd9Sstevel@tonic-gate 28187c478bd9Sstevel@tonic-gate /* 28197c478bd9Sstevel@tonic-gate * Clean up 28207c478bd9Sstevel@tonic-gate */ 28217c478bd9Sstevel@tonic-gate (void) destroy_data((void *)disks); 28227c478bd9Sstevel@tonic-gate } 28237c478bd9Sstevel@tonic-gate 28247c478bd9Sstevel@tonic-gate 28257c478bd9Sstevel@tonic-gate /* 28267c478bd9Sstevel@tonic-gate * Compare two disk names 28277c478bd9Sstevel@tonic-gate */ 28287c478bd9Sstevel@tonic-gate static int 28297c478bd9Sstevel@tonic-gate disk_name_compare( 28307c478bd9Sstevel@tonic-gate const void *arg1, 28317c478bd9Sstevel@tonic-gate const void *arg2) 28327c478bd9Sstevel@tonic-gate { 28337c478bd9Sstevel@tonic-gate char *s1; 28347c478bd9Sstevel@tonic-gate char *s2; 28357c478bd9Sstevel@tonic-gate int n1; 28367c478bd9Sstevel@tonic-gate int n2; 28377c478bd9Sstevel@tonic-gate char *p1; 28387c478bd9Sstevel@tonic-gate char *p2; 28397c478bd9Sstevel@tonic-gate 28407c478bd9Sstevel@tonic-gate s1 = (*((struct disk_info **)arg1))->disk_name; 28417c478bd9Sstevel@tonic-gate s2 = (*((struct disk_info **)arg2))->disk_name; 28427c478bd9Sstevel@tonic-gate 28437c478bd9Sstevel@tonic-gate for (;;) { 28447c478bd9Sstevel@tonic-gate if (*s1 == 0 || *s2 == 0) 28457c478bd9Sstevel@tonic-gate break; 28467c478bd9Sstevel@tonic-gate if (isdigit(*s1) && isdigit(*s2)) { 28477c478bd9Sstevel@tonic-gate n1 = strtol(s1, &p1, 10); 28487c478bd9Sstevel@tonic-gate n2 = strtol(s2, &p2, 10); 28497c478bd9Sstevel@tonic-gate if (n1 != n2) { 28507c478bd9Sstevel@tonic-gate return (n1 - n2); 28517c478bd9Sstevel@tonic-gate } 28527c478bd9Sstevel@tonic-gate s1 = p1; 28537c478bd9Sstevel@tonic-gate s2 = p2; 28547c478bd9Sstevel@tonic-gate } else if (*s1 != *s2) { 28557c478bd9Sstevel@tonic-gate break; 28567c478bd9Sstevel@tonic-gate } else { 28577c478bd9Sstevel@tonic-gate s1++; 28587c478bd9Sstevel@tonic-gate s2++; 28597c478bd9Sstevel@tonic-gate } 28607c478bd9Sstevel@tonic-gate } 28617c478bd9Sstevel@tonic-gate 28627c478bd9Sstevel@tonic-gate return (*s1 - *s2); 28637c478bd9Sstevel@tonic-gate } 28647c478bd9Sstevel@tonic-gate 28657c478bd9Sstevel@tonic-gate static void 28667c478bd9Sstevel@tonic-gate make_controller_list() 28677c478bd9Sstevel@tonic-gate { 28687c478bd9Sstevel@tonic-gate int x; 28697c478bd9Sstevel@tonic-gate struct mctlr_list *ctlrp; 28707c478bd9Sstevel@tonic-gate 28717c478bd9Sstevel@tonic-gate ctlrp = controlp; 28727c478bd9Sstevel@tonic-gate 28737c478bd9Sstevel@tonic-gate for (x = nctypes; x != 0; x--) { 28747c478bd9Sstevel@tonic-gate ctlrp = zalloc(sizeof (struct mctlr_list)); 28757c478bd9Sstevel@tonic-gate ctlrp->next = controlp; 28767c478bd9Sstevel@tonic-gate ctlrp->ctlr_type = &ctlr_types[x - 1]; 28777c478bd9Sstevel@tonic-gate controlp = ctlrp; 28787c478bd9Sstevel@tonic-gate 28797c478bd9Sstevel@tonic-gate } 28807c478bd9Sstevel@tonic-gate } 28817c478bd9Sstevel@tonic-gate 28827c478bd9Sstevel@tonic-gate static void 28837c478bd9Sstevel@tonic-gate check_for_duplicate_disknames(arglist) 28847c478bd9Sstevel@tonic-gate char *arglist[]; 28857c478bd9Sstevel@tonic-gate { 28867c478bd9Sstevel@tonic-gate char *directory = "/dev/rdsk/"; 28877c478bd9Sstevel@tonic-gate char **disklist; 28887c478bd9Sstevel@tonic-gate int len; 28897c478bd9Sstevel@tonic-gate char s[MAXPATHLEN], t[MAXPATHLEN]; 28907c478bd9Sstevel@tonic-gate int diskno = 0; 28917c478bd9Sstevel@tonic-gate int i; 28927c478bd9Sstevel@tonic-gate 28937c478bd9Sstevel@tonic-gate 28947c478bd9Sstevel@tonic-gate len = strlen(directory); 28957c478bd9Sstevel@tonic-gate disklist = arglist; 28967c478bd9Sstevel@tonic-gate for (; *disklist != NULL; disklist++) { 28977c478bd9Sstevel@tonic-gate if (strncmp(directory, *disklist, len) == 0) { 28987c478bd9Sstevel@tonic-gate /* Disk is in conventional format */ 28997c478bd9Sstevel@tonic-gate canonicalize_name(s, *disklist); 29007c478bd9Sstevel@tonic-gate /* 29017c478bd9Sstevel@tonic-gate * check if the disk is already present in 29027c478bd9Sstevel@tonic-gate * disk list. 29037c478bd9Sstevel@tonic-gate */ 29047c478bd9Sstevel@tonic-gate for (i = 0; i < diskno; i++) { 29057c478bd9Sstevel@tonic-gate canonicalize_name(t, arglist[i]); 29067c478bd9Sstevel@tonic-gate if (strncmp(s, t, strlen(t)) == 0) 29077c478bd9Sstevel@tonic-gate break; 29087c478bd9Sstevel@tonic-gate } 29097c478bd9Sstevel@tonic-gate if (i != diskno) 29107c478bd9Sstevel@tonic-gate continue; 29117c478bd9Sstevel@tonic-gate } 29127c478bd9Sstevel@tonic-gate (void) strcpy(arglist[diskno], *disklist); 29137c478bd9Sstevel@tonic-gate diskno++; 29147c478bd9Sstevel@tonic-gate } 29157c478bd9Sstevel@tonic-gate arglist[diskno] = NULL; 29167c478bd9Sstevel@tonic-gate } 29177c478bd9Sstevel@tonic-gate 29187c478bd9Sstevel@tonic-gate #define DISK_PREFIX "/dev/rdsk/" 29197c478bd9Sstevel@tonic-gate 29207c478bd9Sstevel@tonic-gate /* 29217c478bd9Sstevel@tonic-gate * This Function checks if the non-conventional name is a a link to 29227c478bd9Sstevel@tonic-gate * one of the conventional whole disk name. 29237c478bd9Sstevel@tonic-gate */ 29247c478bd9Sstevel@tonic-gate static int 29257c478bd9Sstevel@tonic-gate name_represents_wholedisk(name) 29267c478bd9Sstevel@tonic-gate char *name; 29277c478bd9Sstevel@tonic-gate { 29287c478bd9Sstevel@tonic-gate char symname[MAXPATHLEN]; 29297c478bd9Sstevel@tonic-gate char localname[MAXPATHLEN]; 29307c478bd9Sstevel@tonic-gate char *nameptr; 29317c478bd9Sstevel@tonic-gate 29327c478bd9Sstevel@tonic-gate 29337c478bd9Sstevel@tonic-gate (void) memset(symname, 0, MAXPATHLEN); 29347c478bd9Sstevel@tonic-gate (void) memset(localname, 0, MAXPATHLEN); 29357c478bd9Sstevel@tonic-gate (void) strcpy(localname, name); 29367c478bd9Sstevel@tonic-gate 29377c478bd9Sstevel@tonic-gate while (readlink(localname, symname, MAXPATHLEN) != -1) { 29387c478bd9Sstevel@tonic-gate nameptr = symname; 29397c478bd9Sstevel@tonic-gate if (strncmp(symname, DISK_PREFIX, strlen(DISK_PREFIX)) == 0) 29407c478bd9Sstevel@tonic-gate nameptr += strlen(DISK_PREFIX); 29417c478bd9Sstevel@tonic-gate if (conventional_name(nameptr)) { 29427c478bd9Sstevel@tonic-gate if (whole_disk_name(nameptr)) 29437c478bd9Sstevel@tonic-gate return (0); 29447c478bd9Sstevel@tonic-gate else 29457c478bd9Sstevel@tonic-gate return (1); 29467c478bd9Sstevel@tonic-gate } 29477c478bd9Sstevel@tonic-gate (void) strcpy(localname, symname); 29487c478bd9Sstevel@tonic-gate (void) memset(symname, 0, MAXPATHLEN); 29497c478bd9Sstevel@tonic-gate } 29507c478bd9Sstevel@tonic-gate return (0); 29517c478bd9Sstevel@tonic-gate } 2952