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