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