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