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
580ab886dSwesolows * Common Development and Distribution License (the "License").
680ab886dSwesolows * 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 */
2180ab886dSwesolows
227c478bd9Sstevel@tonic-gate /*
237fc66be0Sjianfei wang - Sun Microsystems - Beijing China * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <stdio.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <stdarg.h>
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <sys/stat.h>
317c478bd9Sstevel@tonic-gate #include <fcntl.h>
327c478bd9Sstevel@tonic-gate #include <errno.h>
337c478bd9Sstevel@tonic-gate #include <unistd.h>
347c478bd9Sstevel@tonic-gate #include <stropts.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
367c478bd9Sstevel@tonic-gate #include <sys/param.h>
377c478bd9Sstevel@tonic-gate #include <libdevinfo.h>
387c478bd9Sstevel@tonic-gate #include <locale.h>
397c478bd9Sstevel@tonic-gate #include <libintl.h>
407c478bd9Sstevel@tonic-gate #include <devid.h>
41ed141cfcSsrivijitha dugganapalli #include <sys/libdevid.h>
42a0261a43SJames C. McPherson #include <sys/modctl.h> /* for MAXMODCONFNAME */
43a0261a43SJames C. McPherson #include <sys/scsi/adapters/scsi_vhci.h>
447c478bd9Sstevel@tonic-gate
457c478bd9Sstevel@tonic-gate /*
46a0261a43SJames C. McPherson * SAVE_DIR is the directory in which system files are saved.
47a0261a43SJames C. McPherson * SAVE_DIR must be under the root filesystem, as this program is
487c478bd9Sstevel@tonic-gate * typically run before any other filesystems are mounted.
497c478bd9Sstevel@tonic-gate */
507c478bd9Sstevel@tonic-gate #define SAVE_DIR "/etc/mpxio"
51a0261a43SJames C. McPherson #define VHCI_CTL_NODE "/devices/scsi_vhci:devctl"
527c478bd9Sstevel@tonic-gate
53a0261a43SJames C. McPherson /* nvlist property names, these are ALL string types */
54a0261a43SJames C. McPherson #define NVL_DEVID "nvl-devid"
55a0261a43SJames C. McPherson #define NVL_PATH "nvl-path"
56a0261a43SJames C. McPherson #define NVL_PHYSPATH "nvl-physpath"
57a0261a43SJames C. McPherson #define NVL_MPXPATH "nvl-mpxiopath"
58a0261a43SJames C. McPherson #define NVL_MPXEN "nvl-mpxioenabled"
597c478bd9Sstevel@tonic-gate
60a0261a43SJames C. McPherson #define MPX_LIST 0x01
61a0261a43SJames C. McPherson #define MPX_MAP 0x02
62a0261a43SJames C. McPherson #define MPX_CAPABLE_CTRL 0x04
637fc66be0Sjianfei wang - Sun Microsystems - Beijing China #define MPX_DEV_PATH 0x06
64a0261a43SJames C. McPherson #define MPX_INIT 0x08
65a0261a43SJames C. McPherson #define MPX_PHYSICAL 0x10
66a0261a43SJames C. McPherson #define MPX_BOOTPATH 0x20
67a0261a43SJames C. McPherson #define MPX_UPDATEVFSTAB 0x40
687fc66be0Sjianfei wang - Sun Microsystems - Beijing China #define MPX_GETPATH 0x60
69a0261a43SJames C. McPherson #define MPX_USAGE 0x80
70a0261a43SJames C. McPherson #define MSG_INFO 0x01
71a0261a43SJames C. McPherson #define MSG_ERROR 0x02
72a0261a43SJames C. McPherson #define MSG_PANIC 0x04
7360fffc19Sjw149990
747fc66be0Sjianfei wang - Sun Microsystems - Beijing China #define BOOT_PATH 0x02
75a0261a43SJames C. McPherson #define BOOT 0x01
76a0261a43SJames C. McPherson #define NONBOOT 0x00
777c478bd9Sstevel@tonic-gate
787fc66be0Sjianfei wang - Sun Microsystems - Beijing China #define DISPLAY_ONE_PATH 0x00
797fc66be0Sjianfei wang - Sun Microsystems - Beijing China #define DISPLAY_ALL_PATH 0x01
807fc66be0Sjianfei wang - Sun Microsystems - Beijing China
817c478bd9Sstevel@tonic-gate static di_node_t devinfo_root = DI_NODE_NIL;
82a0261a43SJames C. McPherson static char *ondiskname = "/etc/mpxio/devid_path.cache";
837c478bd9Sstevel@tonic-gate
847c478bd9Sstevel@tonic-gate /*
85a0261a43SJames C. McPherson * We use devid-keyed nvlists to keep track of the guid, traditional and
86a0261a43SJames C. McPherson * MPxIO-enabled /dev/rdsk paths. Each of these nvlists is eventually
87a0261a43SJames C. McPherson * added to our global nvlist and our on-disk nvlist.
887c478bd9Sstevel@tonic-gate */
89a0261a43SJames C. McPherson static nvlist_t *mapnvl;
90a0261a43SJames C. McPherson static int mpxenabled = 0;
91a0261a43SJames C. McPherson static int limctrl = -1;
9235c62094Sjianfei wang - Sun Microsystems - Beijing China static int mpxprop = 0;
93a0261a43SJames C. McPherson static int guid = 0;
94a0261a43SJames C. McPherson static char *drvlimit;
95a0261a43SJames C. McPherson static int globarg = 0;
96a0261a43SJames C. McPherson static int debugflag = 0;
97a0261a43SJames C. McPherson static char *devicep;
98a0261a43SJames C. McPherson static int readonlyroot = 0;
99a0261a43SJames C. McPherson static int cap_N_option = 0;
100a0261a43SJames C. McPherson
101a0261a43SJames C. McPherson static void print_mpx_capable(di_node_t curnode);
102a0261a43SJames C. McPherson static int popcheck_devnvl(di_node_t thisnode, nvlist_t *devnvl,
103a0261a43SJames C. McPherson char *strdevid);
104a0261a43SJames C. McPherson static int mpxio_nvl_boilerplate(di_node_t curnode);
105a0261a43SJames C. McPherson static int validate_devnvl();
106a0261a43SJames C. McPherson static void report_map(char *argdev, int physpath);
107a0261a43SJames C. McPherson static void list_devs(int listguids, int ctrl);
108a0261a43SJames C. McPherson static void logmsg(int level, const char *msg, ...);
109a0261a43SJames C. McPherson static char *find_link(di_node_t cnode);
110a0261a43SJames C. McPherson static void usage();
111a0261a43SJames C. McPherson static void parse_args(int argc, char *argv[]);
112a0261a43SJames C. McPherson static void get_devid(di_node_t node, ddi_devid_t *thisdevid);
113a0261a43SJames C. McPherson static int print_bootpath();
1147fc66be0Sjianfei wang - Sun Microsystems - Beijing China static void vhci_to_phci(char *devpath, char *slice, int d_flag);
115a0261a43SJames C. McPherson static int update_vfstab();
1167fc66be0Sjianfei wang - Sun Microsystems - Beijing China static void report_dev_node_name(char *strdevfspath);
1177fc66be0Sjianfei wang - Sun Microsystems - Beijing China static void print_node_name(char *drv_name, char *strdevfspath);
118a0261a43SJames C. McPherson int
main(int argc,char ** argv)119a0261a43SJames C. McPherson main(int argc, char **argv)
1207c478bd9Sstevel@tonic-gate {
121a0261a43SJames C. McPherson struct stat cachestat;
122a0261a43SJames C. McPherson int mapfd = 0;
123a0261a43SJames C. McPherson int rv = 0;
124a0261a43SJames C. McPherson char *ondiskbuf;
125a0261a43SJames C. McPherson size_t newsz = 0;
1267c478bd9Sstevel@tonic-gate
127a0261a43SJames C. McPherson parse_args(argc, argv);
128a0261a43SJames C. McPherson errno = 0;
129a0261a43SJames C. McPherson devinfo_root = di_init("/", DINFOCPYALL|DINFOFORCE);
130a0261a43SJames C. McPherson logmsg(MSG_INFO, "errno = %d after "
131a0261a43SJames C. McPherson "di_init(/,DINFOCPYALL|DINFOFORCE)\n", errno);
132a0261a43SJames C. McPherson if (devinfo_root == NULL) {
133a0261a43SJames C. McPherson logmsg(MSG_ERROR,
134a0261a43SJames C. McPherson gettext("Unable to take device tree snapshot "
135a0261a43SJames C. McPherson "(%s: %d)\n"), strerror(errno), errno);
136a0261a43SJames C. McPherson return (-1);
137a0261a43SJames C. McPherson }
138a0261a43SJames C. McPherson logmsg(MSG_INFO, "opened root di_node\n");
1397c478bd9Sstevel@tonic-gate
140a0261a43SJames C. McPherson if (globarg == MPX_CAPABLE_CTRL) {
141a0261a43SJames C. McPherson /* we just want to find MPxIO-capable controllers and exit */
142a0261a43SJames C. McPherson if (drvlimit != NULL) {
143a0261a43SJames C. McPherson print_mpx_capable(di_drv_first_node(drvlimit,
144a0261a43SJames C. McPherson devinfo_root));
145a0261a43SJames C. McPherson } else {
146a0261a43SJames C. McPherson print_mpx_capable(di_drv_first_node("fp",
147a0261a43SJames C. McPherson devinfo_root));
148a0261a43SJames C. McPherson print_mpx_capable(di_drv_first_node("mpt",
149a0261a43SJames C. McPherson devinfo_root));
1505b504601Sjiang wu - Sun Microsystems - Beijing China print_mpx_capable(di_drv_first_node("mpt_sas",
1515b504601Sjiang wu - Sun Microsystems - Beijing China devinfo_root));
1524c06356bSdh142964 print_mpx_capable(di_drv_first_node("pmcs",
1534c06356bSdh142964 devinfo_root));
154a0261a43SJames C. McPherson }
155a0261a43SJames C. McPherson di_fini(devinfo_root);
156a0261a43SJames C. McPherson return (0);
157a0261a43SJames C. McPherson }
158a0261a43SJames C. McPherson
159a0261a43SJames C. McPherson mapfd = open(ondiskname, O_RDWR|O_CREAT|O_SYNC, S_IRUSR | S_IWUSR);
160a0261a43SJames C. McPherson if (mapfd < 0) {
161a0261a43SJames C. McPherson /* we could be in single-user, so try for RO */
162a0261a43SJames C. McPherson if ((mapfd = open(ondiskname, O_RDONLY)) < 0) {
163a0261a43SJames C. McPherson logmsg(MSG_ERROR,
164a0261a43SJames C. McPherson gettext("Unable to open or create %s:%s\n"),
165a0261a43SJames C. McPherson ondiskname, strerror(errno));
166a0261a43SJames C. McPherson return (errno);
167a0261a43SJames C. McPherson }
168a0261a43SJames C. McPherson readonlyroot = 1;
169a0261a43SJames C. McPherson }
170a0261a43SJames C. McPherson
171a0261a43SJames C. McPherson if (stat(ondiskname, &cachestat) != 0) {
172a0261a43SJames C. McPherson logmsg(MSG_ERROR,
173a0261a43SJames C. McPherson gettext("Unable to stat() %s: %s\n"),
174a0261a43SJames C. McPherson ondiskname, strerror(errno));
175a0261a43SJames C. McPherson return (errno);
176a0261a43SJames C. McPherson }
177a0261a43SJames C. McPherson ondiskbuf = calloc(1, cachestat.st_size);
178a0261a43SJames C. McPherson if (ondiskbuf == NULL) {
179a0261a43SJames C. McPherson logmsg(MSG_ERROR,
180a0261a43SJames C. McPherson gettext("Unable to allocate memory for the devid "
181a0261a43SJames C. McPherson "cache file: %s\n"), strerror(errno));
182a0261a43SJames C. McPherson return (errno);
183a0261a43SJames C. McPherson }
184a0261a43SJames C. McPherson rv = read(mapfd, ondiskbuf, cachestat.st_size);
185a0261a43SJames C. McPherson if (rv != cachestat.st_size) {
186a0261a43SJames C. McPherson logmsg(MSG_ERROR,
187a0261a43SJames C. McPherson gettext("Unable to read all of devid cache file (got %d "
188a0261a43SJames C. McPherson "from expected %d bytes): %s\n"),
189a0261a43SJames C. McPherson rv, cachestat.st_size, strerror(errno));
190a0261a43SJames C. McPherson return (errno);
191a0261a43SJames C. McPherson }
192a0261a43SJames C. McPherson errno = 0;
193a0261a43SJames C. McPherson rv = nvlist_unpack(ondiskbuf, cachestat.st_size, &mapnvl, 0);
194a0261a43SJames C. McPherson if (rv) {
195a0261a43SJames C. McPherson logmsg(MSG_INFO,
196a0261a43SJames C. McPherson "Unable to unpack devid cache file %s: %s (%d)\n",
197a0261a43SJames C. McPherson ondiskname, strerror(rv), rv);
198a0261a43SJames C. McPherson if (nvlist_alloc(&mapnvl, NV_UNIQUE_NAME, 0) != 0) {
199a0261a43SJames C. McPherson logmsg(MSG_ERROR,
200a0261a43SJames C. McPherson gettext("Unable to allocate root property"
201a0261a43SJames C. McPherson "list\n"));
202a0261a43SJames C. McPherson return (errno);
203a0261a43SJames C. McPherson }
204a0261a43SJames C. McPherson }
205a0261a43SJames C. McPherson free(ondiskbuf);
206a0261a43SJames C. McPherson
207a0261a43SJames C. McPherson if (validate_devnvl() < 0) {
208a0261a43SJames C. McPherson logmsg(MSG_ERROR,
209a0261a43SJames C. McPherson gettext("unable to validate kernel with on-disk devid "
210a0261a43SJames C. McPherson "cache file\n"));
211a0261a43SJames C. McPherson return (errno);
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate /*
215a0261a43SJames C. McPherson * If we're in single-user mode or maintenance mode, we won't
216a0261a43SJames C. McPherson * necessarily have a writable root device (ZFSroot; ufs root is
217a0261a43SJames C. McPherson * different in that we _do_ have a writable root device.
218a0261a43SJames C. McPherson * This causes problems for the devlink calls (see
219a0261a43SJames C. McPherson * $SRC/lib/libdevinfo/devinfo_devlink.c) and we do not try to
220a0261a43SJames C. McPherson * write out the devnvl if root is readonly.
2217c478bd9Sstevel@tonic-gate */
222a0261a43SJames C. McPherson if (!readonlyroot) {
223a0261a43SJames C. McPherson rv = nvlist_size(mapnvl, &newsz, NV_ENCODE_NATIVE);
224a0261a43SJames C. McPherson if (rv) {
225a0261a43SJames C. McPherson logmsg(MSG_ERROR,
226a0261a43SJames C. McPherson gettext("Unable to determine size of packed "
227a0261a43SJames C. McPherson "on-disk devid cache file %s: %s (%d).\n"),
228a0261a43SJames C. McPherson ondiskname, strerror(rv), rv);
229a0261a43SJames C. McPherson logmsg(MSG_ERROR, gettext("Terminating\n"));
230a0261a43SJames C. McPherson nvlist_free(mapnvl);
231a0261a43SJames C. McPherson (void) close(mapfd);
232a0261a43SJames C. McPherson return (rv);
233a0261a43SJames C. McPherson }
234a0261a43SJames C. McPherson
235a0261a43SJames C. McPherson if ((ondiskbuf = calloc(1, newsz)) == NULL) {
236a0261a43SJames C. McPherson logmsg(MSG_ERROR,
237a0261a43SJames C. McPherson "Unable to allocate space for writing out new "
238a0261a43SJames C. McPherson "on-disk devid cache file: %s\n", strerror(errno));
239a0261a43SJames C. McPherson (void) close(mapfd);
240a0261a43SJames C. McPherson nvlist_free(mapnvl);
241a0261a43SJames C. McPherson return (errno);
242a0261a43SJames C. McPherson }
243a0261a43SJames C. McPherson
244a0261a43SJames C. McPherson rv = nvlist_pack(mapnvl, &ondiskbuf, &newsz,
245a0261a43SJames C. McPherson NV_ENCODE_NATIVE, 0);
246a0261a43SJames C. McPherson if (rv) {
247a0261a43SJames C. McPherson logmsg(MSG_ERROR,
248a0261a43SJames C. McPherson gettext("Unable to pack on-disk devid cache "
249a0261a43SJames C. McPherson "file: %s (%d)\n"), strerror(rv), rv);
250a0261a43SJames C. McPherson (void) close(mapfd);
251a0261a43SJames C. McPherson free(ondiskbuf);
252a0261a43SJames C. McPherson nvlist_free(mapnvl);
253a0261a43SJames C. McPherson return (rv);
254a0261a43SJames C. McPherson }
255a0261a43SJames C. McPherson
256a0261a43SJames C. McPherson rv = lseek(mapfd, 0, 0);
257a0261a43SJames C. McPherson if (rv == -1) {
258a0261a43SJames C. McPherson logmsg(MSG_ERROR,
259a0261a43SJames C. McPherson gettext("Unable to seek to start of devid cache "
260a0261a43SJames C. McPherson "file: %s (%d)\n"), strerror(errno), errno);
261a0261a43SJames C. McPherson (void) close(mapfd);
262a0261a43SJames C. McPherson free(ondiskbuf);
263a0261a43SJames C. McPherson nvlist_free(mapnvl);
264a0261a43SJames C. McPherson return (-1);
265a0261a43SJames C. McPherson }
266a0261a43SJames C. McPherson
267a0261a43SJames C. McPherson if (write(mapfd, ondiskbuf, newsz) != newsz) {
268a0261a43SJames C. McPherson logmsg(MSG_ERROR,
269a0261a43SJames C. McPherson gettext("Unable to completely write out "
270a0261a43SJames C. McPherson "on-disk devid cache file: %s\n"), strerror(errno));
271a0261a43SJames C. McPherson (void) close(mapfd);
272a0261a43SJames C. McPherson nvlist_free(mapnvl);
273a0261a43SJames C. McPherson free(ondiskbuf);
274a0261a43SJames C. McPherson return (errno);
275a0261a43SJames C. McPherson }
276a0261a43SJames C. McPherson } /* !readonlyroot */
277a0261a43SJames C. McPherson
278a0261a43SJames C. McPherson /* Now we can process the command line args */
279a0261a43SJames C. McPherson if (globarg == MPX_PHYSICAL) {
280a0261a43SJames C. McPherson report_map(devicep, BOOT);
281a0261a43SJames C. McPherson } else if (globarg == MPX_BOOTPATH) {
282a0261a43SJames C. McPherson rv = print_bootpath();
283a0261a43SJames C. McPherson di_fini(devinfo_root);
284a0261a43SJames C. McPherson return (rv);
285a0261a43SJames C. McPherson } else if (globarg == MPX_UPDATEVFSTAB) {
286a0261a43SJames C. McPherson rv = update_vfstab();
287a0261a43SJames C. McPherson di_fini(devinfo_root);
288a0261a43SJames C. McPherson return (rv);
2897fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else if (globarg == MPX_GETPATH) {
2907fc66be0Sjianfei wang - Sun Microsystems - Beijing China report_dev_node_name(devicep);
2917fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else if (globarg == MPX_DEV_PATH) {
2927fc66be0Sjianfei wang - Sun Microsystems - Beijing China report_map(devicep, BOOT_PATH);
293a0261a43SJames C. McPherson } else if (globarg != MPX_INIT) {
294a0261a43SJames C. McPherson if (globarg & MPX_LIST)
295a0261a43SJames C. McPherson list_devs(guid, limctrl);
296a0261a43SJames C. McPherson
297a0261a43SJames C. McPherson if (globarg == MPX_MAP)
298a0261a43SJames C. McPherson report_map(devicep, NONBOOT);
299a0261a43SJames C. McPherson } else {
300a0261a43SJames C. McPherson logmsg(MSG_INFO, "\nprivate devid cache file initialised\n");
301a0261a43SJames C. McPherson }
302a0261a43SJames C. McPherson
303a0261a43SJames C. McPherson nvlist_free(mapnvl);
304a0261a43SJames C. McPherson di_fini(devinfo_root);
305a0261a43SJames C. McPherson return (0);
306a0261a43SJames C. McPherson }
307a0261a43SJames C. McPherson
308a0261a43SJames C. McPherson static void
usage()309a0261a43SJames C. McPherson usage()
310a0261a43SJames C. McPherson {
311a0261a43SJames C. McPherson (void) fprintf(stderr,
312a0261a43SJames C. McPherson gettext("usage: stmsboot_util -b | -m devname | "
313a0261a43SJames C. McPherson "-l <ctrl> | -L | [-g] | -n | -N | -i | -p devname\n"));
314a0261a43SJames C. McPherson (void) fprintf(stderr, "\n\n");
315a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-h\tprint this usage message\n"));
316a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-b\tretrieve the system's bootpath "
317a0261a43SJames C. McPherson "setting\n"));
318a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-m devname\n"));
319a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tReports the current mapping for "
320a0261a43SJames C. McPherson "devname\n"));
321a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-g\tprint the GUID for MPxIO-capable "
322a0261a43SJames C. McPherson "devices. This\n"));
323a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\toption is only valid with the -L "
324a0261a43SJames C. McPherson "or -l options\n"));
325a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-L | -l <ctrl>\n"));
326a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tList the 'native' to 'MPxIO' "
327a0261a43SJames C. McPherson "device mappings. If <ctrl>\n"));
328a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tis specified, only print mappings "
329a0261a43SJames C. McPherson "for those devices\n"));
330a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tattached via the specified "
331a0261a43SJames C. McPherson "controller.\n"));
332a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-i\tinitialise the private devid "
333a0261a43SJames C. McPherson "cache file and exit\n"));
334a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tThis option excludes all "
335a0261a43SJames C. McPherson "others.\n"));
336a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-n\tprint the devfs paths for "
337a0261a43SJames C. McPherson "multipath-capable\n"));
338a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tcontroller ports.\n"));
339a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-N\tprint the device aliases of "
340a0261a43SJames C. McPherson "multipath-capable\n"));
341a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tcontroller ports.\n"));
342a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-p\tdevname\n"));
343a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tThis option provides the physical "
344a0261a43SJames C. McPherson "devfs path for\n"));
345a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\ta specific device (devname). Used "
346a0261a43SJames C. McPherson "to set the bootpath\n"));
347a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\tvariable on x86/x64 systems\n"));
348a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t-u\ttranslates device mappings in "
349a0261a43SJames C. McPherson "/etc/vfstab as \n"));
350a0261a43SJames C. McPherson (void) fprintf(stderr, gettext("\t\trequired. The output is written "
351a0261a43SJames C. McPherson "to /etc/mpxio/vfstab.new\n\n"));
352a0261a43SJames C. McPherson exit(2);
353a0261a43SJames C. McPherson }
354a0261a43SJames C. McPherson
3557c478bd9Sstevel@tonic-gate static void
parse_args(int argc,char * argv[])3567c478bd9Sstevel@tonic-gate parse_args(int argc, char *argv[])
3577c478bd9Sstevel@tonic-gate {
358*ef150c2bSRichard Lowe int opt;
3597c478bd9Sstevel@tonic-gate
360a0261a43SJames C. McPherson if (argc == 1)
361a0261a43SJames C. McPherson usage();
3627c478bd9Sstevel@tonic-gate
363a0261a43SJames C. McPherson /*
364a0261a43SJames C. McPherson * -b prints the bootpath property
365a0261a43SJames C. McPherson * -d turns on debug mode for this utility (copious output!)
366a0261a43SJames C. McPherson * -D drvname
367a0261a43SJames C. McPherson * if supplied, indicates that we're going to operate on
368a0261a43SJames C. McPherson * devices attached to this driver.
369a0261a43SJames C. McPherson * -g if (-l or -L), prints guids for devices rather than paths
370a0261a43SJames C. McPherson * -h prints the usage() help text.
371a0261a43SJames C. McPherson * -i initialises the cache file and exits.
372a0261a43SJames C. McPherson * -l controller
373a0261a43SJames C. McPherson * list non-STMS to STMS device name mappings for the specific
374a0261a43SJames C. McPherson * controller, when MPxIO is enabled only.
375a0261a43SJames C. McPherson * -L list non-STMS to STMS device name mappings for all controllers
376a0261a43SJames C. McPherson * when MPxIO is enabled only.
377a0261a43SJames C. McPherson * -m devname
378a0261a43SJames C. McPherson * prints the device path (/dev/rdsk) that devname maps to
379a0261a43SJames C. McPherson * in the currently-running system.
380a0261a43SJames C. McPherson * -n
381a0261a43SJames C. McPherson * if supplied, returns name of STMS-capable controller nodes.
382a0261a43SJames C. McPherson * If the -D drvname option is specified as well, we only report
383a0261a43SJames C. McPherson * nodes attached with drvname.
384a0261a43SJames C. McPherson * -N
385a0261a43SJames C. McPherson * same as the -n option, except that we only print the
386a0261a43SJames C. McPherson * node-name (dev_info :: devi_node_name). Multiple instances
387a0261a43SJames C. McPherson * through the libdevinfo snapshot are uniqified and separated
388a0261a43SJames C. McPherson * by the "|" character for direct use by egrep(1).
389a0261a43SJames C. McPherson * -p devname
390a0261a43SJames C. McPherson * prints the physical devfs path for devname. Only used to
391a0261a43SJames C. McPherson * determine the bootpath.
392a0261a43SJames C. McPherson * -u
393a0261a43SJames C. McPherson * remaps devices in /etc/vfstab, saving the newly generated
394a0261a43SJames C. McPherson * file to /etc/mpxio/vfstab.new. If we have any remapped
395a0261a43SJames C. McPherson * devices, exit with status 0, otherwise -1 for error.
396a0261a43SJames C. McPherson */
3977fc66be0Sjianfei wang - Sun Microsystems - Beijing China while ((opt = getopt(argc, argv, "bdD:ghil:Lm:nNo:p:q:u")) != EOF) {
3987c478bd9Sstevel@tonic-gate switch (opt) {
399a0261a43SJames C. McPherson case 'b':
400a0261a43SJames C. McPherson globarg = MPX_BOOTPATH;
4017c478bd9Sstevel@tonic-gate break;
4027c478bd9Sstevel@tonic-gate case 'd':
403a0261a43SJames C. McPherson debugflag = 1;
4047c478bd9Sstevel@tonic-gate break;
40560fffc19Sjw149990 case 'D':
406a0261a43SJames C. McPherson if ((drvlimit = calloc(1, MAXMODCONFNAME)) == NULL) {
407a0261a43SJames C. McPherson logmsg(MSG_ERROR,
408a0261a43SJames C. McPherson gettext("Unable to allocate memory for a "
409a0261a43SJames C. McPherson "driver name: %s\n"), strerror(errno));
410a0261a43SJames C. McPherson exit(errno);
41160fffc19Sjw149990 }
4126cb11604SToomas Soome if (strlcpy(drvlimit, optarg, MAXMODCONFNAME) >=
4136cb11604SToomas Soome MAXMODCONFNAME) {
4146cb11604SToomas Soome logmsg(MSG_ERROR,
4156cb11604SToomas Soome gettext("invalid parent driver (%s) "
4166cb11604SToomas Soome "specified"), optarg);
4176cb11604SToomas Soome usage();
4186cb11604SToomas Soome }
419a0261a43SJames C. McPherson /* update this if adding support for a new driver */
4206cb11604SToomas Soome if (strcmp(drvlimit, "fp") != 0 &&
4216cb11604SToomas Soome strcmp(drvlimit, "mpt") != 0 &&
4226cb11604SToomas Soome strcmp(drvlimit, "mpt_sas") != 0 &&
4236cb11604SToomas Soome strcmp(drvlimit, "pmcs") != 0) {
424a0261a43SJames C. McPherson logmsg(MSG_ERROR,
425a0261a43SJames C. McPherson gettext("invalid parent driver (%s) "
426a0261a43SJames C. McPherson "specified"), drvlimit);
427a0261a43SJames C. McPherson usage();
428a0261a43SJames C. McPherson }
42960fffc19Sjw149990 break;
430a0261a43SJames C. McPherson case 'h':
431a0261a43SJames C. McPherson /* Just drop out and print the usage() output */
432a0261a43SJames C. McPherson globarg = MPX_USAGE;
433a0261a43SJames C. McPherson break;
434a0261a43SJames C. McPherson case 'i':
435a0261a43SJames C. McPherson globarg = MPX_INIT;
436a0261a43SJames C. McPherson break;
437a0261a43SJames C. McPherson case 'l':
438a0261a43SJames C. McPherson globarg |= MPX_LIST;
439a0261a43SJames C. McPherson limctrl = (int)atol(optarg);
440a0261a43SJames C. McPherson if (limctrl < 0) {
441a0261a43SJames C. McPherson logmsg(MSG_INFO,
442a0261a43SJames C. McPherson gettext("invalid controller number "
443a0261a43SJames C. McPherson "(%d), checking all controllers\n"),
444a0261a43SJames C. McPherson limctrl);
445a0261a43SJames C. McPherson }
446a0261a43SJames C. McPherson break;
447a0261a43SJames C. McPherson case 'L':
448a0261a43SJames C. McPherson globarg |= MPX_LIST;
449a0261a43SJames C. McPherson break;
450a0261a43SJames C. McPherson case 'g':
451a0261a43SJames C. McPherson guid = 1;
452a0261a43SJames C. McPherson break;
453a0261a43SJames C. McPherson case 'm':
454a0261a43SJames C. McPherson globarg = MPX_MAP;
455a0261a43SJames C. McPherson if ((devicep = calloc(1, MAXPATHLEN)) == NULL) {
456a0261a43SJames C. McPherson logmsg(MSG_ERROR,
457a0261a43SJames C. McPherson gettext("Unable to allocate space for a "
458a0261a43SJames C. McPherson "device name\n"));
459a0261a43SJames C. McPherson exit(errno);
460a0261a43SJames C. McPherson }
461a0261a43SJames C. McPherson devicep = strdup(optarg);
462a0261a43SJames C. McPherson break;
463a0261a43SJames C. McPherson case 'N':
464a0261a43SJames C. McPherson cap_N_option = 1;
465a0261a43SJames C. McPherson globarg = MPX_CAPABLE_CTRL;
466a0261a43SJames C. McPherson break;
46760fffc19Sjw149990 case 'n':
468a0261a43SJames C. McPherson globarg = MPX_CAPABLE_CTRL;
46960fffc19Sjw149990 break;
4707fc66be0Sjianfei wang - Sun Microsystems - Beijing China case 'o':
4717fc66be0Sjianfei wang - Sun Microsystems - Beijing China globarg = MPX_GETPATH;
4727fc66be0Sjianfei wang - Sun Microsystems - Beijing China if ((devicep = calloc(1, MAXPATHLEN)) == NULL) {
4737fc66be0Sjianfei wang - Sun Microsystems - Beijing China logmsg(MSG_ERROR,
4747fc66be0Sjianfei wang - Sun Microsystems - Beijing China gettext("Unable to allocate space for a "
4757fc66be0Sjianfei wang - Sun Microsystems - Beijing China "device name\n"));
4767fc66be0Sjianfei wang - Sun Microsystems - Beijing China exit(errno);
4777fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
4787fc66be0Sjianfei wang - Sun Microsystems - Beijing China devicep = strdup(optarg);
4797fc66be0Sjianfei wang - Sun Microsystems - Beijing China break;
480a0261a43SJames C. McPherson case 'p':
481a0261a43SJames C. McPherson globarg = MPX_PHYSICAL;
482a0261a43SJames C. McPherson if ((devicep = calloc(1, MAXPATHLEN)) == NULL) {
483a0261a43SJames C. McPherson logmsg(MSG_ERROR,
484a0261a43SJames C. McPherson gettext("Unable to allocate space for a "
485a0261a43SJames C. McPherson "device name\n"));
486a0261a43SJames C. McPherson exit(errno);
487a0261a43SJames C. McPherson }
488a0261a43SJames C. McPherson devicep = strdup(optarg);
489a0261a43SJames C. McPherson break;
4907fc66be0Sjianfei wang - Sun Microsystems - Beijing China case 'q':
4917fc66be0Sjianfei wang - Sun Microsystems - Beijing China globarg = MPX_DEV_PATH;
4927fc66be0Sjianfei wang - Sun Microsystems - Beijing China if ((devicep = calloc(1, MAXPATHLEN)) == NULL) {
4937fc66be0Sjianfei wang - Sun Microsystems - Beijing China logmsg(MSG_ERROR,
4947fc66be0Sjianfei wang - Sun Microsystems - Beijing China gettext("Unable to allocate space for a "
4957fc66be0Sjianfei wang - Sun Microsystems - Beijing China "device name\n"));
4967fc66be0Sjianfei wang - Sun Microsystems - Beijing China exit(errno);
4977fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
4987fc66be0Sjianfei wang - Sun Microsystems - Beijing China devicep = strdup(optarg);
4997fc66be0Sjianfei wang - Sun Microsystems - Beijing China break;
500a0261a43SJames C. McPherson case 'u':
501a0261a43SJames C. McPherson globarg = MPX_UPDATEVFSTAB;
502a0261a43SJames C. McPherson break;
5037c478bd9Sstevel@tonic-gate default:
504a0261a43SJames C. McPherson logmsg(MSG_ERROR,
505a0261a43SJames C. McPherson gettext("Invalid command line option (%c)\n"),
506a0261a43SJames C. McPherson opt);
507a0261a43SJames C. McPherson usage();
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate }
5107c478bd9Sstevel@tonic-gate
511a0261a43SJames C. McPherson if ((globarg >= MPX_USAGE) || (guid && (globarg != MPX_LIST)))
512a0261a43SJames C. McPherson usage();
513a0261a43SJames C. McPherson
514a0261a43SJames C. McPherson if ((drvlimit != NULL) &&
515a0261a43SJames C. McPherson ((globarg != MPX_LIST) &&
516a0261a43SJames C. McPherson (globarg != MPX_CAPABLE_CTRL)))
517a0261a43SJames C. McPherson usage();
51860fffc19Sjw149990 }
5197c478bd9Sstevel@tonic-gate
520a0261a43SJames C. McPherson static void
logmsg(int level,const char * msg,...)521a0261a43SJames C. McPherson logmsg(int level, const char *msg, ...)
5227c478bd9Sstevel@tonic-gate {
523a0261a43SJames C. McPherson va_list ap;
5247c478bd9Sstevel@tonic-gate
525a0261a43SJames C. McPherson if ((level >= MSG_ERROR) ||
526a0261a43SJames C. McPherson ((debugflag > 0) && (level >= MSG_INFO))) {
527a0261a43SJames C. McPherson (void) fprintf(stdout, "stmsboot: ");
528a0261a43SJames C. McPherson va_start(ap, msg);
529a0261a43SJames C. McPherson (void) vfprintf(stdout, msg, ap);
530a0261a43SJames C. McPherson va_end(ap);
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate }
5337c478bd9Sstevel@tonic-gate
5347c478bd9Sstevel@tonic-gate /*
535a0261a43SJames C. McPherson * It's up to the caller to do any sorting or pretty-printing of the device
536a0261a43SJames C. McPherson * mappings we report. Since we're storing the device links as just the cXtYdZ
537a0261a43SJames C. McPherson * part, we'll add /dev/rdsk/ back on when we print the listing so we maintain
538a0261a43SJames C. McPherson * compatibility with previous versions of this tool. There's a little bit
539a0261a43SJames C. McPherson * of footwork involved to make sure that we show all the paths to a device
540a0261a43SJames C. McPherson * rather than just the first one we stashed away.
5417c478bd9Sstevel@tonic-gate */
5427c478bd9Sstevel@tonic-gate static void
list_devs(int listguids,int ctrl)543a0261a43SJames C. McPherson list_devs(int listguids, int ctrl)
5447c478bd9Sstevel@tonic-gate {
545a0261a43SJames C. McPherson nvlist_t *thisdevnvl;
546a0261a43SJames C. McPherson nvpair_t *pair;
547a0261a43SJames C. McPherson char *diskpath, *livepath, *key, *querydev;
548a0261a43SJames C. McPherson char *matchctrl = NULL;
549a0261a43SJames C. McPherson char checkctrl[MAXPATHLEN];
550a0261a43SJames C. McPherson int rv;
5517c478bd9Sstevel@tonic-gate
552a0261a43SJames C. McPherson if (!mpxenabled) {
55335c62094Sjianfei wang - Sun Microsystems - Beijing China if (mpxprop) {
55435c62094Sjianfei wang - Sun Microsystems - Beijing China logmsg(MSG_ERROR, gettext("MPXIO disabled\n"));
55535c62094Sjianfei wang - Sun Microsystems - Beijing China } else {
55635c62094Sjianfei wang - Sun Microsystems - Beijing China logmsg(MSG_ERROR, gettext("No STMS devices have "
55735c62094Sjianfei wang - Sun Microsystems - Beijing China "been found\n"));
55835c62094Sjianfei wang - Sun Microsystems - Beijing China }
559a0261a43SJames C. McPherson return;
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate
562a0261a43SJames C. McPherson if (listguids) {
563a0261a43SJames C. McPherson (void) printf(gettext("non-STMS device name\t\t\tGUID\n"
564a0261a43SJames C. McPherson "------------------------------------------"
565a0261a43SJames C. McPherson "------------------------\n"));
5667c478bd9Sstevel@tonic-gate } else {
567a0261a43SJames C. McPherson (void) printf(gettext("non-STMS device name\t\t\t"
568a0261a43SJames C. McPherson "STMS device name\n"
569a0261a43SJames C. McPherson "------------------------------------------"
570a0261a43SJames C. McPherson "------------------------\n"));
571a0261a43SJames C. McPherson }
572a0261a43SJames C. McPherson
573a0261a43SJames C. McPherson bzero(checkctrl, MAXPATHLEN);
574a0261a43SJames C. McPherson pair = NULL;
575a0261a43SJames C. McPherson while ((pair = nvlist_next_nvpair(mapnvl, pair))
576a0261a43SJames C. McPherson != NULL) {
577a0261a43SJames C. McPherson boolean_t livescsivhcip = B_FALSE;
578a0261a43SJames C. McPherson
579a0261a43SJames C. McPherson if ((((rv = nvpair_value_string(pair, &querydev)) < 0) ||
580a0261a43SJames C. McPherson ((key = nvpair_name(pair)) == NULL)) ||
581a0261a43SJames C. McPherson ((strstr(key, "/pci") != NULL) ||
582a0261a43SJames C. McPherson (strstr(key, "/sbus") != NULL) ||
583a0261a43SJames C. McPherson (strstr(key, "/scsi_vhci") != NULL) ||
584a0261a43SJames C. McPherson (strncmp(key, "id1", 3) == 0))) {
585a0261a43SJames C. McPherson logmsg(MSG_INFO,
586a0261a43SJames C. McPherson "list_devs: rv = %d; (%s) is not a devlink, "
587a0261a43SJames C. McPherson "continuing.\n", rv,
588a0261a43SJames C. McPherson (key != NULL) ? key : "null");
589a0261a43SJames C. McPherson querydev = NULL;
590a0261a43SJames C. McPherson continue;
591a0261a43SJames C. McPherson }
592a0261a43SJames C. McPherson
593a0261a43SJames C. McPherson (void) nvlist_lookup_nvlist(mapnvl, querydev, &thisdevnvl);
594a0261a43SJames C. McPherson (void) nvlist_lookup_boolean_value(thisdevnvl, NVL_MPXEN,
595a0261a43SJames C. McPherson &livescsivhcip);
596a0261a43SJames C. McPherson (void) nvlist_lookup_string(thisdevnvl, NVL_MPXPATH,
597a0261a43SJames C. McPherson &livepath);
598a0261a43SJames C. McPherson
599a0261a43SJames C. McPherson if ((!livescsivhcip) ||
600a0261a43SJames C. McPherson (livescsivhcip &&
601a0261a43SJames C. McPherson (strncmp(key, livepath, strlen(key)) == 0)))
602a0261a43SJames C. McPherson continue;
603a0261a43SJames C. McPherson
604a0261a43SJames C. McPherson (void) nvlist_lookup_string(thisdevnvl, NVL_PATH,
605a0261a43SJames C. McPherson &diskpath);
606a0261a43SJames C. McPherson
607a0261a43SJames C. McPherson logmsg(MSG_INFO,
608a0261a43SJames C. McPherson "list_devs: %s :: %s ::%s :: MPXEN (%s)\n",
609a0261a43SJames C. McPherson key, diskpath, livepath,
610a0261a43SJames C. McPherson ((livescsivhcip) ? "TRUE" : "FALSE"));
611a0261a43SJames C. McPherson
612a0261a43SJames C. McPherson if (ctrl > -1) {
613a0261a43SJames C. McPherson (void) sprintf(checkctrl, "c%dt", ctrl);
614a0261a43SJames C. McPherson matchctrl = strstr(key, checkctrl);
615a0261a43SJames C. McPherson if (matchctrl == NULL)
616a0261a43SJames C. McPherson continue;
617a0261a43SJames C. McPherson }
618a0261a43SJames C. McPherson if (listguids != 0) {
619a0261a43SJames C. McPherson char *tempguid;
620a0261a43SJames C. McPherson ddi_devid_t curdevid;
621a0261a43SJames C. McPherson int rv;
622a0261a43SJames C. McPherson
623a0261a43SJames C. McPherson rv = devid_str_decode(querydev, &curdevid, NULL);
624a0261a43SJames C. McPherson if (rv == -1) {
625a0261a43SJames C. McPherson logmsg(MSG_INFO, "Unable to decode devid %s\n",
626a0261a43SJames C. McPherson key);
627a0261a43SJames C. McPherson continue;
628a0261a43SJames C. McPherson }
629a0261a43SJames C. McPherson tempguid = devid_to_guid(curdevid);
630a0261a43SJames C. McPherson if (tempguid != NULL)
631a0261a43SJames C. McPherson (void) printf("/dev/rdsk/%s\t%s\n",
632a0261a43SJames C. McPherson diskpath, tempguid);
633a0261a43SJames C. McPherson
634a0261a43SJames C. McPherson devid_free_guid(tempguid);
635a0261a43SJames C. McPherson devid_free(curdevid);
636a0261a43SJames C. McPherson continue;
637a0261a43SJames C. McPherson }
638a0261a43SJames C. McPherson
639a0261a43SJames C. McPherson (void) printf("/dev/rdsk/%s\t/dev/rdsk/%s\n",
640a0261a43SJames C. McPherson (strstr(key, diskpath) == NULL) ? key : diskpath,
641a0261a43SJames C. McPherson livepath);
6427c478bd9Sstevel@tonic-gate }
6437c478bd9Sstevel@tonic-gate }
6447c478bd9Sstevel@tonic-gate
6457c478bd9Sstevel@tonic-gate /*
646a0261a43SJames C. McPherson * We get passed a device name which we search the mapnvl for. If we find
647a0261a43SJames C. McPherson * it, we print the mapping as it is found. It is up to the caller of this
648a0261a43SJames C. McPherson * utility to do any pretty-printing of the results. If a device listed on
649a0261a43SJames C. McPherson * the command line does not exist in the mapnvl, then we print NOT_MAPPED.
650a0261a43SJames C. McPherson * Otherwise we print the command-line device name as it maps to what is
651a0261a43SJames C. McPherson * stashed in the mapnvl - even if that's a "no change" device mapping.
6527c478bd9Sstevel@tonic-gate *
653a0261a43SJames C. McPherson * Example output (-p maps to physpath=BOOT)
654a0261a43SJames C. McPherson * # /lib/mpxio/stmsboot_util -p \
655a0261a43SJames C. McPherson * /pci@0,0/pci1022,7450@2/pci1000,3060@3/sd@1,0:a
656a0261a43SJames C. McPherson * /scsi_vhci/disk@g500000e011e17720:a
6577c478bd9Sstevel@tonic-gate *
658a0261a43SJames C. McPherson * Or the reverse:
659a0261a43SJames C. McPherson * # /lib/mpxio/stmsboot_util -p /scsi_vhci/disk@g500000e011e17720:a
660a0261a43SJames C. McPherson * /pci@0,0/pci1022,7450@2/pci1000,3060@3/sd@1,0:a
661a0261a43SJames C. McPherson *
662a0261a43SJames C. McPherson * For the -m option, used when we're trying to find the root device mapping:
663a0261a43SJames C. McPherson *
664a0261a43SJames C. McPherson * # /lib/mpxio/stmsboot_util -m /dev/dsk/c2t0d0s2
665a0261a43SJames C. McPherson * /dev/dsk/c3t500000E011637CF0d0s2
666a0261a43SJames C. McPherson */
667a0261a43SJames C. McPherson static void
report_map(char * argdev,int physpath)668a0261a43SJames C. McPherson report_map(char *argdev, int physpath)
669a0261a43SJames C. McPherson {
670a0261a43SJames C. McPherson nvlist_t *thisdev;
671a0261a43SJames C. McPherson int rv = 0;
672a0261a43SJames C. McPherson char *thisdevid;
673a0261a43SJames C. McPherson char *mpxpath = NULL;
674a0261a43SJames C. McPherson char *prefixt = NULL;
675a0261a43SJames C. McPherson char *prefixp = NULL;
676a0261a43SJames C. McPherson char *stripdev = NULL;
677a0261a43SJames C. McPherson char *slice = NULL;
678a0261a43SJames C. McPherson boolean_t mpxenp;
679a0261a43SJames C. McPherson uint_t slicelen = 0;
680a0261a43SJames C. McPherson
681a0261a43SJames C. McPherson mpxenp = B_FALSE;
682a0261a43SJames C. McPherson
683a0261a43SJames C. McPherson if ((prefixt = calloc(1, strlen(argdev) + 1)) == NULL) {
684a0261a43SJames C. McPherson logmsg(MSG_INFO, "Unable to allocate memory\n");
685a0261a43SJames C. McPherson (void) printf("NOT_MAPPED\n");
686a0261a43SJames C. McPherson return;
687a0261a43SJames C. McPherson }
688a0261a43SJames C. McPherson
689a0261a43SJames C. McPherson (void) strlcpy(prefixt, argdev, strlen(argdev) + 1);
690a0261a43SJames C. McPherson
6917fc66be0Sjianfei wang - Sun Microsystems - Beijing China slice = strrchr(argdev, (physpath == NONBOOT) ? 's' : ':');
692a0261a43SJames C. McPherson if (slice != NULL) {
693a0261a43SJames C. McPherson slicelen = strlen(slice);
694a0261a43SJames C. McPherson if (slicelen > 3)
695a0261a43SJames C. McPherson /* invalid size - max is 3 chars */
696a0261a43SJames C. McPherson slicelen = 0;
697a0261a43SJames C. McPherson }
698a0261a43SJames C. McPherson
699a0261a43SJames C. McPherson if ((stripdev = calloc(1, strlen(prefixt) + 1)) == NULL) {
700a0261a43SJames C. McPherson logmsg(MSG_INFO, "Unable to allocate memory\n");
701a0261a43SJames C. McPherson (void) printf("NOT_MAPPED\n");
702a0261a43SJames C. McPherson free(prefixt);
703a0261a43SJames C. McPherson return;
704a0261a43SJames C. McPherson }
705a0261a43SJames C. McPherson
706a0261a43SJames C. McPherson if ((strstr(prefixt, "/scsi_vhci") == NULL) &&
707a0261a43SJames C. McPherson (strstr(prefixt, "/pci") == NULL) &&
708a0261a43SJames C. McPherson (strstr(prefixt, "/sbus") == NULL)) {
709a0261a43SJames C. McPherson prefixp = strrchr(prefixt, '/');
710a0261a43SJames C. McPherson (void) strlcpy(stripdev,
711a0261a43SJames C. McPherson (prefixp == NULL) ? prefixt : prefixp + 1,
712a0261a43SJames C. McPherson (prefixp == NULL) ?
713a0261a43SJames C. McPherson strlen(prefixt) + 1: strlen(prefixp) + 1);
714a0261a43SJames C. McPherson if (prefixp != NULL)
715a0261a43SJames C. McPherson prefixt[strlen(argdev) - strlen(prefixp) + 1] = '\0';
716a0261a43SJames C. McPherson } else {
7177fc66be0Sjianfei wang - Sun Microsystems - Beijing China if ((physpath != BOOT) &&
7187fc66be0Sjianfei wang - Sun Microsystems - Beijing China (physpath != BOOT_PATH)) {
719a0261a43SJames C. McPherson logmsg(MSG_INFO, "Invalid device path provided\n");
720a0261a43SJames C. McPherson (void) printf("NOT_MAPPED\n");
721a0261a43SJames C. McPherson free(stripdev);
722a0261a43SJames C. McPherson free(prefixt);
723a0261a43SJames C. McPherson return;
724a0261a43SJames C. McPherson }
725a0261a43SJames C. McPherson (void) strlcpy(stripdev, argdev, strlen(argdev) + 1);
726a0261a43SJames C. McPherson }
727a0261a43SJames C. McPherson
728a0261a43SJames C. McPherson logmsg(MSG_INFO,
729a0261a43SJames C. McPherson "stripdev (%s), prefixt(%s), prefixp(%s), slice(%s)\n",
730a0261a43SJames C. McPherson (stripdev == NULL) ? "null" : stripdev,
731a0261a43SJames C. McPherson (prefixt == NULL) ? "null" : prefixt,
732a0261a43SJames C. McPherson (prefixp == NULL) ? "null" : prefixp,
733a0261a43SJames C. McPherson (slice == NULL) ? "null" : slice);
734a0261a43SJames C. McPherson
735a0261a43SJames C. McPherson if (slicelen > 0)
736a0261a43SJames C. McPherson stripdev[strlen(stripdev) - slicelen] = '\0';
737a0261a43SJames C. McPherson
738a0261a43SJames C. McPherson /* search for the shortened version */
739a0261a43SJames C. McPherson rv = nvlist_lookup_string(mapnvl, stripdev, &thisdevid);
740a0261a43SJames C. McPherson if (rv) {
7417fc66be0Sjianfei wang - Sun Microsystems - Beijing China if ((physpath != BOOT) &&
7427fc66be0Sjianfei wang - Sun Microsystems - Beijing China (physpath != BOOT_PATH)) {
743a0261a43SJames C. McPherson logmsg(MSG_INFO,
744a0261a43SJames C. McPherson "searched mapnvl for '%s', got %s (%d)\n",
745a0261a43SJames C. McPherson stripdev, strerror(rv), rv);
746a0261a43SJames C. McPherson (void) printf("NOT_MAPPED\n");
747a0261a43SJames C. McPherson free(stripdev);
748a0261a43SJames C. McPherson free(prefixt);
749a0261a43SJames C. McPherson return;
750a0261a43SJames C. McPherson }
751a0261a43SJames C. McPherson }
752a0261a43SJames C. McPherson
753a0261a43SJames C. McPherson logmsg(MSG_INFO, "device %s has devid %s\n", stripdev, thisdevid);
754a0261a43SJames C. McPherson
755a0261a43SJames C. McPherson if (nvlist_lookup_nvlist(mapnvl, thisdevid, &thisdev) != 0) {
756a0261a43SJames C. McPherson logmsg(MSG_INFO, "device (%s) in mapnvl but "
757a0261a43SJames C. McPherson "not mapped!\n", thisdevid);
758a0261a43SJames C. McPherson (void) printf("NOT_MAPPED\n");
759a0261a43SJames C. McPherson free(stripdev);
760a0261a43SJames C. McPherson free(prefixt);
761a0261a43SJames C. McPherson return;
762a0261a43SJames C. McPherson }
763a0261a43SJames C. McPherson
764a0261a43SJames C. McPherson /* quick exit */
765a0261a43SJames C. McPherson if (!mpxenabled && (strstr(argdev, "/pci") != NULL ||
766a0261a43SJames C. McPherson strstr(argdev, "/sbus") != NULL)) {
767a0261a43SJames C. McPherson (void) printf("%s\n", argdev);
768a0261a43SJames C. McPherson free(stripdev);
769a0261a43SJames C. McPherson free(prefixt);
770a0261a43SJames C. McPherson return;
771a0261a43SJames C. McPherson }
772a0261a43SJames C. McPherson
773a0261a43SJames C. McPherson (void) nvlist_lookup_boolean_value(thisdev, NVL_MPXEN, &mpxenp);
774a0261a43SJames C. McPherson
775a0261a43SJames C. McPherson if (physpath == BOOT) {
776a0261a43SJames C. McPherson (void) nvlist_lookup_string(thisdev, NVL_PHYSPATH, &mpxpath);
777a0261a43SJames C. McPherson if ((strstr(argdev, "/scsi_vhci") != NULL) &&
778a0261a43SJames C. McPherson (strncmp(argdev, mpxpath, strlen(mpxpath)) == 0)) {
779a0261a43SJames C. McPherson /* Need to translate vhci to phci */
7807fc66be0Sjianfei wang - Sun Microsystems - Beijing China vhci_to_phci(stripdev, slice, DISPLAY_ONE_PATH);
7817fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else {
7827fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("%s%s\n", mpxpath,
783a0261a43SJames C. McPherson ((slicelen > 0) && slice != NULL) ? slice : "");
7847fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
7857fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else if (physpath == BOOT_PATH) {
7867fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) nvlist_lookup_string(thisdev, NVL_PHYSPATH, &mpxpath);
7877fc66be0Sjianfei wang - Sun Microsystems - Beijing China if ((strstr(argdev, "/scsi_vhci") != NULL) &&
7887fc66be0Sjianfei wang - Sun Microsystems - Beijing China (strncmp(argdev, mpxpath, strlen(mpxpath)) == 0)) {
7897fc66be0Sjianfei wang - Sun Microsystems - Beijing China /* Need to translate vhci to phci */
7907fc66be0Sjianfei wang - Sun Microsystems - Beijing China vhci_to_phci(stripdev, slice, DISPLAY_ALL_PATH);
791a0261a43SJames C. McPherson } else {
792a0261a43SJames C. McPherson (void) printf("%s%s\n", mpxpath,
793a0261a43SJames C. McPherson ((slicelen > 0) && slice != NULL) ? slice : "");
794a0261a43SJames C. McPherson }
795a0261a43SJames C. McPherson } else {
796a0261a43SJames C. McPherson (void) nvlist_lookup_string(thisdev,
797a0261a43SJames C. McPherson ((readonlyroot) ? NVL_PHYSPATH :
798a0261a43SJames C. McPherson ((mpxenp == B_TRUE) ? NVL_MPXPATH : NVL_PATH)),
799a0261a43SJames C. McPherson &mpxpath);
800a0261a43SJames C. McPherson logmsg(MSG_INFO, "mpxpath = %s\n",
801a0261a43SJames C. McPherson (mpxpath == NULL) ? "null" : mpxpath);
802a0261a43SJames C. McPherson if (readonlyroot ||
803a0261a43SJames C. McPherson (strstr(mpxpath, "/scsi_vhci") != NULL) ||
804a0261a43SJames C. McPherson (strstr(mpxpath, "/pci") != NULL) ||
805a0261a43SJames C. McPherson (strstr(mpxpath, "/sbus") != NULL)) {
806a0261a43SJames C. McPherson /*
807a0261a43SJames C. McPherson * If we see a physical path here it means that
808a0261a43SJames C. McPherson * devlinks aren't fully initialised yet, so we
809a0261a43SJames C. McPherson * are still in maintenance/single-user mode.
810a0261a43SJames C. McPherson */
811a0261a43SJames C. McPherson (void) printf("/devices%s:%c\n", mpxpath,
812a0261a43SJames C. McPherson slice[1] + '1');
813a0261a43SJames C. McPherson } else {
814a0261a43SJames C. McPherson (void) printf("%s%s%s\n",
815a0261a43SJames C. McPherson (prefixt[0] == '/') ? prefixt : "",
816a0261a43SJames C. McPherson mpxpath,
817a0261a43SJames C. McPherson ((slicelen > 0) && slice != NULL) ? slice : "");
818a0261a43SJames C. McPherson }
819a0261a43SJames C. McPherson }
820a0261a43SJames C. McPherson free(prefixt);
821a0261a43SJames C. McPherson free(stripdev);
822a0261a43SJames C. McPherson }
823a0261a43SJames C. McPherson
824a0261a43SJames C. McPherson /*
825a0261a43SJames C. McPherson * Validate the in-kernel and on-disk forms of our devid cache,
826a0261a43SJames C. McPherson * returns -1 for unfixable error and 0 for success.
8277c478bd9Sstevel@tonic-gate */
8287c478bd9Sstevel@tonic-gate static int
validate_devnvl()829a0261a43SJames C. McPherson validate_devnvl()
830a0261a43SJames C. McPherson {
831a0261a43SJames C. McPherson di_node_t curnode;
832a0261a43SJames C. McPherson int rv1 = -1;
833a0261a43SJames C. McPherson int rv2 = -1;
834a0261a43SJames C. McPherson
835a0261a43SJames C. McPherson /*
836a0261a43SJames C. McPherson * Method: we walk through the kernel's concept of the device tree
837a0261a43SJames C. McPherson * looking for "ssd" then "sd" nodes.
838a0261a43SJames C. McPherson * We check to see whether the device's devid is already in our nvlist
839a0261a43SJames C. McPherson * (on disk) nvlist cache file. If it is, we check that it's components
840a0261a43SJames C. McPherson * match what we've got already and fill any missing fields.
841a0261a43SJames C. McPherson * If the devid isn't in our on-disk nvlist already then we add it
842a0261a43SJames C. McPherson * and populate the property nvpairs.
843a0261a43SJames C. McPherson *
844a0261a43SJames C. McPherson * At the end of this function we should have this program's concept
845a0261a43SJames C. McPherson * of the devid-keyed nvlist matching what is in the ondisk form which
846a0261a43SJames C. McPherson * is ready to be written out.
847a0261a43SJames C. McPherson * If we can't do this, then we return -1.
848a0261a43SJames C. McPherson */
849a0261a43SJames C. McPherson curnode = di_drv_first_node("ssd", devinfo_root);
850a0261a43SJames C. McPherson if (curnode != DI_NODE_NIL)
851a0261a43SJames C. McPherson rv1 = mpxio_nvl_boilerplate(curnode);
852a0261a43SJames C. McPherson
853a0261a43SJames C. McPherson curnode = di_drv_first_node("sd", devinfo_root);
854a0261a43SJames C. McPherson if (curnode != DI_NODE_NIL)
855a0261a43SJames C. McPherson rv2 = mpxio_nvl_boilerplate(curnode);
856a0261a43SJames C. McPherson
857a0261a43SJames C. McPherson if (rv1 + rv2 == -2)
858a0261a43SJames C. McPherson return (-1);
859a0261a43SJames C. McPherson
860a0261a43SJames C. McPherson return (0);
861a0261a43SJames C. McPherson }
862a0261a43SJames C. McPherson
8637fc66be0Sjianfei wang - Sun Microsystems - Beijing China /*
8647fc66be0Sjianfei wang - Sun Microsystems - Beijing China * According to devfs path name, it will print device node name.
8657fc66be0Sjianfei wang - Sun Microsystems - Beijing China */
8667fc66be0Sjianfei wang - Sun Microsystems - Beijing China static void
print_node_name(char * drv_name,char * strdevfspath)8677fc66be0Sjianfei wang - Sun Microsystems - Beijing China print_node_name(char *drv_name, char *strdevfspath)
8687fc66be0Sjianfei wang - Sun Microsystems - Beijing China {
8697fc66be0Sjianfei wang - Sun Microsystems - Beijing China di_node_t curnode;
8707fc66be0Sjianfei wang - Sun Microsystems - Beijing China char *devfspath = NULL;
8717fc66be0Sjianfei wang - Sun Microsystems - Beijing China char *node_name = NULL;
8727fc66be0Sjianfei wang - Sun Microsystems - Beijing China
8737fc66be0Sjianfei wang - Sun Microsystems - Beijing China curnode = di_drv_first_node(drv_name, devinfo_root);
8747fc66be0Sjianfei wang - Sun Microsystems - Beijing China for (; curnode != DI_NODE_NIL; curnode = di_drv_next_node(curnode)) {
8757fc66be0Sjianfei wang - Sun Microsystems - Beijing China devfspath = di_devfs_path(curnode);
8767fc66be0Sjianfei wang - Sun Microsystems - Beijing China logmsg(MSG_INFO, "find: devfspath %s\n", devfspath);
8777fc66be0Sjianfei wang - Sun Microsystems - Beijing China
8787fc66be0Sjianfei wang - Sun Microsystems - Beijing China if (devfspath == NULL)
8797fc66be0Sjianfei wang - Sun Microsystems - Beijing China continue;
8807fc66be0Sjianfei wang - Sun Microsystems - Beijing China
8819955cef3Sjianfei wang - Sun Microsystems - Beijing China if ((strlen(strdevfspath) == strlen(devfspath)) &&
8829955cef3Sjianfei wang - Sun Microsystems - Beijing China (strncmp(strdevfspath, devfspath,
8839955cef3Sjianfei wang - Sun Microsystems - Beijing China strlen(devfspath)) == 0)) {
8847fc66be0Sjianfei wang - Sun Microsystems - Beijing China node_name = find_link(curnode);
8857fc66be0Sjianfei wang - Sun Microsystems - Beijing China if (node_name == NULL) {
8867fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("NOT MAPPED\n");
8877fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else {
8887fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("%s\n", node_name);
8897fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
8907fc66be0Sjianfei wang - Sun Microsystems - Beijing China return;
8917fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
8927fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
8937fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
8947fc66be0Sjianfei wang - Sun Microsystems - Beijing China
8957fc66be0Sjianfei wang - Sun Microsystems - Beijing China /*
8967fc66be0Sjianfei wang - Sun Microsystems - Beijing China * report device node name, search "ssd" and "sd" nodes,
8977fc66be0Sjianfei wang - Sun Microsystems - Beijing China * print the device node name which device path is same as
8987fc66be0Sjianfei wang - Sun Microsystems - Beijing China * parameter.
8997fc66be0Sjianfei wang - Sun Microsystems - Beijing China */
9007fc66be0Sjianfei wang - Sun Microsystems - Beijing China static void
report_dev_node_name(char * strdevfspath)9017fc66be0Sjianfei wang - Sun Microsystems - Beijing China report_dev_node_name(char *strdevfspath)
9027fc66be0Sjianfei wang - Sun Microsystems - Beijing China {
9037fc66be0Sjianfei wang - Sun Microsystems - Beijing China logmsg(MSG_INFO, "strdevfspath: %s\n", strdevfspath);
9047fc66be0Sjianfei wang - Sun Microsystems - Beijing China print_node_name("ssd", strdevfspath);
9057fc66be0Sjianfei wang - Sun Microsystems - Beijing China print_node_name("sd", strdevfspath);
9067fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
9077fc66be0Sjianfei wang - Sun Microsystems - Beijing China
908a0261a43SJames C. McPherson static int
mpxio_nvl_boilerplate(di_node_t curnode)909a0261a43SJames C. McPherson mpxio_nvl_boilerplate(di_node_t curnode)
910a0261a43SJames C. McPherson {
911a0261a43SJames C. McPherson int rv;
912a0261a43SJames C. McPherson char *strdevid;
913a0261a43SJames C. McPherson ddi_devid_t curdevid;
914a0261a43SJames C. McPherson nvlist_t *newnvl;
915a0261a43SJames C. McPherson
916a0261a43SJames C. McPherson for (; curnode != DI_NODE_NIL; curnode = di_drv_next_node(curnode)) {
917a0261a43SJames C. McPherson errno = 0;
918a0261a43SJames C. McPherson
919a0261a43SJames C. McPherson curdevid = NULL;
920a0261a43SJames C. McPherson get_devid(curnode, &curdevid);
921a0261a43SJames C. McPherson if (curdevid == NULL)
922a0261a43SJames C. McPherson /*
923a0261a43SJames C. McPherson * There's no devid registered for this device
924a0261a43SJames C. McPherson * so it's not cool enough to play with us
925a0261a43SJames C. McPherson */
926a0261a43SJames C. McPherson continue;
927a0261a43SJames C. McPherson
928a0261a43SJames C. McPherson strdevid = devid_str_encode(curdevid, NULL);
929a0261a43SJames C. McPherson /* does this exist in the on-disk cache? */
930a0261a43SJames C. McPherson rv = nvlist_lookup_nvlist(mapnvl, strdevid, &newnvl);
931a0261a43SJames C. McPherson if (rv == ENOENT) {
932a0261a43SJames C. McPherson logmsg(MSG_INFO, "nvlist for %s not found\n", strdevid);
933a0261a43SJames C. McPherson /* no, so alloc a new nvl to store it */
934a0261a43SJames C. McPherson if (nvlist_alloc(&newnvl, NV_UNIQUE_NAME, 0) != 0) {
935a0261a43SJames C. McPherson logmsg(MSG_ERROR,
936a0261a43SJames C. McPherson gettext("Unable to allocate space for "
937a0261a43SJames C. McPherson "a devid property list: %s\n"),
938a0261a43SJames C. McPherson strerror(errno));
939a0261a43SJames C. McPherson return (-1);
940a0261a43SJames C. McPherson }
941a0261a43SJames C. McPherson } else {
942a0261a43SJames C. McPherson if ((rv != ENOTSUP) && (rv != EINVAL))
943a0261a43SJames C. McPherson logmsg(MSG_INFO,
944a0261a43SJames C. McPherson "%s exists in ondisknvl, verifying\n",
945a0261a43SJames C. McPherson strdevid);
946a0261a43SJames C. McPherson }
947a0261a43SJames C. McPherson
948a0261a43SJames C. McPherson if (popcheck_devnvl(curnode, newnvl, strdevid) != 0) {
949a0261a43SJames C. McPherson logmsg(MSG_ERROR,
950a0261a43SJames C. McPherson gettext("Unable to populate devid nvpair "
951a0261a43SJames C. McPherson "for device with devid %s\n"),
952a0261a43SJames C. McPherson strdevid);
953a0261a43SJames C. McPherson devid_str_free(strdevid);
954a0261a43SJames C. McPherson nvlist_free(newnvl);
955a0261a43SJames C. McPherson return (-1);
956a0261a43SJames C. McPherson }
957a0261a43SJames C. McPherson
958a0261a43SJames C. McPherson /* Now add newnvl into our cache. */
959a0261a43SJames C. McPherson errno = 0;
960a0261a43SJames C. McPherson rv = nvlist_add_nvlist(mapnvl, strdevid, newnvl);
961a0261a43SJames C. McPherson if (rv) {
962a0261a43SJames C. McPherson logmsg(MSG_ERROR,
963a0261a43SJames C. McPherson gettext("Unable to add device (devid %s) "
964a0261a43SJames C. McPherson "to in-kernel nvl: %s (%d)\n"),
965a0261a43SJames C. McPherson strdevid, strerror(rv), rv);
966a0261a43SJames C. McPherson devid_str_free(strdevid);
967a0261a43SJames C. McPherson nvlist_free(newnvl);
968a0261a43SJames C. McPherson return (-1);
969a0261a43SJames C. McPherson }
970a0261a43SJames C. McPherson logmsg(MSG_INFO,
971a0261a43SJames C. McPherson gettext("added device (devid %s) to mapnvl\n\n"),
972a0261a43SJames C. McPherson strdevid);
973a0261a43SJames C. McPherson devid_str_free(strdevid);
974a0261a43SJames C. McPherson }
975a0261a43SJames C. McPherson return (0);
976a0261a43SJames C. McPherson }
977a0261a43SJames C. McPherson
978a0261a43SJames C. McPherson /*
979a0261a43SJames C. McPherson * Operates on a single di_node_t, collecting all the device properties
980a0261a43SJames C. McPherson * that we need. devnvl is allocated by the caller, and we add our nvpairs
981a0261a43SJames C. McPherson * to it if they don't already exist.
982a0261a43SJames C. McPherson *
983a0261a43SJames C. McPherson * We are _only_ interested in devices which have a devid. We pull in
984a0261a43SJames C. McPherson * devices even when they're excluded via stmsboot -D (driver), because
985a0261a43SJames C. McPherson * we don't want to miss out on any devid data that might be handy later.
986a0261a43SJames C. McPherson */
987a0261a43SJames C. McPherson static int
popcheck_devnvl(di_node_t thisnode,nvlist_t * devnvl,char * strdevid)988a0261a43SJames C. McPherson popcheck_devnvl(di_node_t thisnode, nvlist_t *devnvl, char *strdevid)
989a0261a43SJames C. McPherson {
990a0261a43SJames C. McPherson char *path = NULL;
991a0261a43SJames C. McPherson char *curpath = NULL;
992a0261a43SJames C. McPherson char *devfspath = NULL;
99335c62094Sjianfei wang - Sun Microsystems - Beijing China char *prop = NULL;
994a0261a43SJames C. McPherson int scsivhciparent = 0;
995a0261a43SJames C. McPherson int rv = 0;
996a0261a43SJames C. McPherson boolean_t mpxenp = B_FALSE;
997a0261a43SJames C. McPherson
998a0261a43SJames C. McPherson errno = 0;
999a0261a43SJames C. McPherson devfspath = di_devfs_path(thisnode);
1000a0261a43SJames C. McPherson if (devfspath == NULL) {
1001a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1002a0261a43SJames C. McPherson gettext("Unable to determine devfs path for node: %s\n"),
1003a0261a43SJames C. McPherson strerror(errno));
1004a0261a43SJames C. McPherson return (-1);
1005a0261a43SJames C. McPherson }
1006a0261a43SJames C. McPherson
1007a0261a43SJames C. McPherson /* Add a convenient devfspath to devid inverse map */
1008a0261a43SJames C. McPherson if (nvlist_add_string(mapnvl, devfspath, strdevid) != 0) {
1009a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1010a0261a43SJames C. McPherson gettext("Unable to add device path %s with devid "
1011a0261a43SJames C. McPherson "%s to mapnvl\n"), devfspath, strdevid);
1012a0261a43SJames C. McPherson return (-1);
1013a0261a43SJames C. McPherson }
101435c62094Sjianfei wang - Sun Microsystems - Beijing China if (di_prop_lookup_strings(DDI_DEV_T_ANY, di_parent_node(thisnode),
101535c62094Sjianfei wang - Sun Microsystems - Beijing China "mpxio-disable", &prop) >= 0) {
101635c62094Sjianfei wang - Sun Microsystems - Beijing China if (strncmp(prop, "yes", 3) == 0) {
101735c62094Sjianfei wang - Sun Microsystems - Beijing China if (!mpxprop)
101835c62094Sjianfei wang - Sun Microsystems - Beijing China mpxprop++;
101935c62094Sjianfei wang - Sun Microsystems - Beijing China }
102035c62094Sjianfei wang - Sun Microsystems - Beijing China }
102135c62094Sjianfei wang - Sun Microsystems - Beijing China
1022a0261a43SJames C. McPherson if (strncmp(di_driver_name(di_parent_node(thisnode)),
1023a0261a43SJames C. McPherson "scsi_vhci", 9) == 0) {
1024a0261a43SJames C. McPherson scsivhciparent = 1;
1025a0261a43SJames C. McPherson if (!mpxenabled)
1026a0261a43SJames C. McPherson mpxenabled++;
1027a0261a43SJames C. McPherson
1028a0261a43SJames C. McPherson rv = nvlist_lookup_boolean_value(devnvl, NVL_MPXEN, &mpxenp);
1029a0261a43SJames C. McPherson if (rv || (mpxenp == B_FALSE)) {
1030a0261a43SJames C. McPherson rv = nvlist_add_boolean_value(devnvl,
1031a0261a43SJames C. McPherson NVL_MPXEN, B_TRUE);
1032a0261a43SJames C. McPherson if (rv) {
1033a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1034a0261a43SJames C. McPherson gettext("Unable to add property %s "
1035a0261a43SJames C. McPherson "(set to B_TRUE) for device %s: "
1036a0261a43SJames C. McPherson "%s (%d)\n"),
1037a0261a43SJames C. McPherson NVL_MPXEN, devfspath,
1038a0261a43SJames C. McPherson strerror(rv), rv);
1039a0261a43SJames C. McPherson return (-1);
1040a0261a43SJames C. McPherson }
1041a0261a43SJames C. McPherson logmsg(MSG_INFO, "NVL_MPXEN :: (B_FALSE->B_TRUE)\n");
1042a0261a43SJames C. McPherson }
1043a0261a43SJames C. McPherson } else {
1044a0261a43SJames C. McPherson /* turn _off_ the flag if it was enabled */
1045a0261a43SJames C. McPherson rv = nvlist_add_boolean_value(devnvl, NVL_MPXEN, B_FALSE);
1046a0261a43SJames C. McPherson if (rv) {
1047a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1048a0261a43SJames C. McPherson gettext("Unable to add property %s "
1049a0261a43SJames C. McPherson "(set to B_FALSE) for device %s: %s (%d)\n"),
1050a0261a43SJames C. McPherson NVL_MPXEN, devfspath,
1051a0261a43SJames C. McPherson strerror(rv), rv);
1052a0261a43SJames C. McPherson return (-1);
1053a0261a43SJames C. McPherson }
1054a0261a43SJames C. McPherson logmsg(MSG_INFO, "NVL_MPXEN :: (B_TRUE-> B_FALSE)\n");
1055a0261a43SJames C. McPherson }
1056a0261a43SJames C. McPherson
1057a0261a43SJames C. McPherson rv = nvlist_add_string(devnvl, NVL_PHYSPATH, devfspath);
1058a0261a43SJames C. McPherson if (rv) {
1059a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1060a0261a43SJames C. McPherson gettext("Unable to add physical device path (%s) "
1061a0261a43SJames C. McPherson "property to nvl\n"));
1062a0261a43SJames C. McPherson return (-1);
1063a0261a43SJames C. McPherson }
1064a0261a43SJames C. McPherson
1065a0261a43SJames C. McPherson if ((curpath = calloc(1, MAXPATHLEN)) == NULL) {
1066a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1067a0261a43SJames C. McPherson gettext("Unable to allocate space for current path\n"));
1068a0261a43SJames C. McPherson return (-1);
1069a0261a43SJames C. McPherson }
1070a0261a43SJames C. McPherson curpath = find_link(thisnode);
1071a0261a43SJames C. McPherson if (curpath == NULL) {
1072a0261a43SJames C. McPherson if (readonlyroot) {
1073a0261a43SJames C. McPherson return (0);
1074a0261a43SJames C. McPherson }
1075a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1076a0261a43SJames C. McPherson gettext("Unable to determine device path for node %s\n"),
1077a0261a43SJames C. McPherson devfspath);
1078a0261a43SJames C. McPherson return (-1);
1079a0261a43SJames C. McPherson }
1080a0261a43SJames C. McPherson
1081a0261a43SJames C. McPherson rv = nvlist_lookup_string(devnvl, NVL_MPXPATH, &path);
1082a0261a43SJames C. McPherson
10837fc66be0Sjianfei wang - Sun Microsystems - Beijing China if (scsivhciparent) {
1084a0261a43SJames C. McPherson (void) nvlist_add_string(devnvl, NVL_MPXPATH, curpath);
10857fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else {
1086a0261a43SJames C. McPherson (void) nvlist_add_string(devnvl, NVL_PATH, curpath);
1087a0261a43SJames C. McPherson path = curpath;
1088a0261a43SJames C. McPherson }
1089a0261a43SJames C. McPherson
1090a0261a43SJames C. McPherson /*
1091a0261a43SJames C. McPherson * This next block provides the path to devid inverse mapping
1092a0261a43SJames C. McPherson * that other functions require
1093a0261a43SJames C. McPherson */
1094a0261a43SJames C. McPherson if (path != NULL) {
1095a0261a43SJames C. McPherson if (nvlist_add_string(mapnvl, path, strdevid) != 0) {
1096a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1097a0261a43SJames C. McPherson gettext("Unable to add device %s with devid "
1098a0261a43SJames C. McPherson "%s to mapnvl\n"), path, strdevid);
1099a0261a43SJames C. McPherson return (-1);
1100a0261a43SJames C. McPherson }
1101a0261a43SJames C. McPherson logmsg(MSG_INFO, "popcheck_devnvl: added path %s :: %s\n",
1102a0261a43SJames C. McPherson path, strdevid);
11037fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
11047fc66be0Sjianfei wang - Sun Microsystems - Beijing China
1105a0261a43SJames C. McPherson if (nvlist_add_string(mapnvl, curpath, strdevid) != 0) {
1106a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1107a0261a43SJames C. McPherson gettext("Unable to add device %s with devid "
1108a0261a43SJames C. McPherson "%s to mapnvl: %s\n"),
1109a0261a43SJames C. McPherson curpath, strdevid, strerror(errno));
1110a0261a43SJames C. McPherson return (-1);
1111a0261a43SJames C. McPherson }
1112a0261a43SJames C. McPherson logmsg(MSG_INFO, "popcheck_devnvl: added curpath %s :: %s\n",
1113a0261a43SJames C. McPherson curpath, strdevid);
11147fc66be0Sjianfei wang - Sun Microsystems - Beijing China
1115a0261a43SJames C. McPherson return (0);
1116a0261a43SJames C. McPherson }
1117a0261a43SJames C. McPherson
1118a0261a43SJames C. McPherson static void
print_mpx_capable(di_node_t curnode)1119a0261a43SJames C. McPherson print_mpx_capable(di_node_t curnode)
1120a0261a43SJames C. McPherson {
1121a0261a43SJames C. McPherson char *prop;
1122a0261a43SJames C. McPherson char *path;
1123a0261a43SJames C. McPherson char *aliases = NULL;
1124a0261a43SJames C. McPherson
1125a0261a43SJames C. McPherson if (cap_N_option) {
1126a0261a43SJames C. McPherson aliases = calloc(1, MAXPATHLEN + 1);
1127a0261a43SJames C. McPherson if (aliases == NULL) {
1128a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1129a0261a43SJames C. McPherson gettext("Unable to allocate memory for a device "
1130a0261a43SJames C. McPherson "alias list\n"));
1131a0261a43SJames C. McPherson return;
1132a0261a43SJames C. McPherson }
1133a0261a43SJames C. McPherson }
1134a0261a43SJames C. McPherson
1135a0261a43SJames C. McPherson for (; curnode != DI_NODE_NIL; curnode = di_drv_next_node(curnode)) {
1136a0261a43SJames C. McPherson if (di_prop_lookup_strings(DDI_DEV_T_ANY, curnode,
1137a0261a43SJames C. McPherson "initiator-port", &prop) >= 0) {
1138a0261a43SJames C. McPherson if ((path = di_devfs_path(curnode)) == NULL) {
1139a0261a43SJames C. McPherson logmsg(MSG_INFO,
1140a0261a43SJames C. McPherson "Unable to find devfs path for device "
1141a0261a43SJames C. McPherson "%s: %s\n", &curnode, strerror(errno));
1142a0261a43SJames C. McPherson continue;
1143a0261a43SJames C. McPherson }
1144a0261a43SJames C. McPherson if (cap_N_option) {
1145a0261a43SJames C. McPherson char *nodename = di_node_name(curnode);
1146a0261a43SJames C. McPherson /* nodename is never going to be null */
1147a0261a43SJames C. McPherson if (strstr(aliases, nodename) == NULL)
1148a0261a43SJames C. McPherson /* haven't seen this nodename before */
1149a0261a43SJames C. McPherson (void) snprintf(aliases,
1150a0261a43SJames C. McPherson MAXPATHLEN + 1, "%s|%s",
1151a0261a43SJames C. McPherson ((aliases != NULL) ? aliases : ""),
1152a0261a43SJames C. McPherson nodename);
1153a0261a43SJames C. McPherson } else
1154a0261a43SJames C. McPherson (void) printf("%s\n", path);
1155a0261a43SJames C. McPherson }
1156a0261a43SJames C. McPherson }
1157a0261a43SJames C. McPherson if (cap_N_option)
1158a0261a43SJames C. McPherson (void) printf("%s\n", aliases);
1159a0261a43SJames C. McPherson }
1160a0261a43SJames C. McPherson
1161a0261a43SJames C. McPherson static int
link_cb(di_devlink_t devlink,void * arg)1162a0261a43SJames C. McPherson link_cb(di_devlink_t devlink, void *arg)
1163a0261a43SJames C. McPherson {
1164a0261a43SJames C. McPherson const char *result;
1165a0261a43SJames C. McPherson
1166a0261a43SJames C. McPherson result = di_devlink_path(devlink);
1167a0261a43SJames C. McPherson if (result == NULL) {
1168a0261a43SJames C. McPherson arg = (void *)"(null)";
1169a0261a43SJames C. McPherson } else {
1170a0261a43SJames C. McPherson (void) strlcpy(arg, result, strlen(result));
1171a0261a43SJames C. McPherson }
1172a0261a43SJames C. McPherson logmsg(MSG_INFO, "\nlink_cb::linkdata->resultstr = %s\n",
1173a0261a43SJames C. McPherson ((result != NULL) ? result : "(null)"));
1174a0261a43SJames C. McPherson return (DI_WALK_CONTINUE);
1175a0261a43SJames C. McPherson }
1176a0261a43SJames C. McPherson
1177a0261a43SJames C. McPherson static char *
find_link(di_node_t cnode)1178a0261a43SJames C. McPherson find_link(di_node_t cnode)
1179a0261a43SJames C. McPherson {
1180a0261a43SJames C. McPherson di_minor_t devminor = DI_MINOR_NIL;
1181a0261a43SJames C. McPherson di_devlink_handle_t hdl;
1182a0261a43SJames C. McPherson char *devfspath = NULL;
1183a0261a43SJames C. McPherson char *minorpath = NULL;
1184a0261a43SJames C. McPherson char *linkname = NULL;
1185a0261a43SJames C. McPherson char *cbresult = NULL;
1186a0261a43SJames C. McPherson
1187a0261a43SJames C. McPherson devfspath = di_devfs_path(cnode);
1188a0261a43SJames C. McPherson if (cnode == DI_NODE_NIL) {
1189a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1190a0261a43SJames C. McPherson gettext("find_ctrl must be called with non-null "
1191a0261a43SJames C. McPherson "di_node_t\n"));
1192a0261a43SJames C. McPherson return (NULL);
1193a0261a43SJames C. McPherson }
1194a0261a43SJames C. McPherson logmsg(MSG_INFO, "find_link: devfspath %s\n", devfspath);
1195a0261a43SJames C. McPherson
1196a0261a43SJames C. McPherson if (((cbresult = calloc(1, MAXPATHLEN)) == NULL) ||
1197a0261a43SJames C. McPherson ((minorpath = calloc(1, MAXPATHLEN)) == NULL) ||
1198a0261a43SJames C. McPherson ((linkname = calloc(1, MAXPATHLEN)) == NULL)) {
1199a0261a43SJames C. McPherson logmsg(MSG_ERROR, "unable to allocate space for dev link\n");
1200a0261a43SJames C. McPherson return (NULL);
1201a0261a43SJames C. McPherson }
1202a0261a43SJames C. McPherson
1203a0261a43SJames C. McPherson devminor = di_minor_next(cnode, devminor);
1204a0261a43SJames C. McPherson hdl = di_devlink_init(di_devfs_minor_path(devminor), DI_MAKE_LINK);
1205a0261a43SJames C. McPherson if (hdl == NULL) {
1206a0261a43SJames C. McPherson logmsg((readonlyroot ? MSG_INFO : MSG_ERROR),
1207a0261a43SJames C. McPherson gettext("unable to take devlink snapshot: %s\n"),
1208a0261a43SJames C. McPherson strerror(errno));
1209a0261a43SJames C. McPherson return (NULL);
1210a0261a43SJames C. McPherson }
1211a0261a43SJames C. McPherson
1212a0261a43SJames C. McPherson linkname = "^dsk/";
1213a0261a43SJames C. McPherson (void) snprintf(minorpath, MAXPATHLEN, "%s:c", devfspath);
1214a0261a43SJames C. McPherson
1215a0261a43SJames C. McPherson errno = 0;
1216a0261a43SJames C. McPherson if (di_devlink_walk(hdl, linkname, minorpath, DI_PRIMARY_LINK,
1217a0261a43SJames C. McPherson (void *)cbresult, link_cb) < 0) {
1218a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1219a0261a43SJames C. McPherson gettext("Unable to walk devlink snapshot for %s: %s\n"),
1220a0261a43SJames C. McPherson minorpath, strerror(errno));
1221a0261a43SJames C. McPherson return (NULL);
1222a0261a43SJames C. McPherson }
1223a0261a43SJames C. McPherson
1224a0261a43SJames C. McPherson if (di_devlink_fini(&hdl) < 0) {
1225a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1226a0261a43SJames C. McPherson gettext("Unable to close devlink snapshot: %s\n"),
1227a0261a43SJames C. McPherson strerror(errno));
1228a0261a43SJames C. McPherson }
1229a0261a43SJames C. McPherson if (strstr(cbresult, "dsk/") == NULL)
1230a0261a43SJames C. McPherson return (devfspath);
1231a0261a43SJames C. McPherson
1232a0261a43SJames C. McPherson bzero(minorpath, MAXPATHLEN);
1233a0261a43SJames C. McPherson /* strip off the trailing "s2" */
1234a0261a43SJames C. McPherson bcopy(cbresult, minorpath, strlen(cbresult) - 1);
1235a0261a43SJames C. McPherson /* Now strip off the /dev/dsk/ prefix for output flexibility */
1236a0261a43SJames C. McPherson linkname = strrchr(minorpath, '/');
1237a0261a43SJames C. McPherson return (++linkname);
1238a0261a43SJames C. McPherson }
1239a0261a43SJames C. McPherson
1240a0261a43SJames C. McPherson /*
1241a0261a43SJames C. McPherson * handle case where device has been probed but its target driver is not
1242a0261a43SJames C. McPherson * attached so enumeration has not quite finished. Opening the /devices
1243a0261a43SJames C. McPherson * pathname will force the kernel to finish the enumeration process and
1244a0261a43SJames C. McPherson * let us get the data we need.
1245a0261a43SJames C. McPherson */
1246a0261a43SJames C. McPherson static void
get_devid(di_node_t node,ddi_devid_t * thisdevid)1247a0261a43SJames C. McPherson get_devid(di_node_t node, ddi_devid_t *thisdevid)
12487c478bd9Sstevel@tonic-gate {
12497c478bd9Sstevel@tonic-gate int fd;
1250a0261a43SJames C. McPherson char realpath[MAXPATHLEN];
1251a0261a43SJames C. McPherson char *openpath = di_devfs_path(node);
12527c478bd9Sstevel@tonic-gate
1253a0261a43SJames C. McPherson errno = 0;
1254a0261a43SJames C. McPherson bzero(realpath, MAXPATHLEN);
1255a0261a43SJames C. McPherson if (strstr(openpath, "/devices") == NULL) {
1256a0261a43SJames C. McPherson (void) snprintf(realpath, MAXPATHLEN,
1257a0261a43SJames C. McPherson "/devices%s:c,raw", openpath);
1258a0261a43SJames C. McPherson fd = open(realpath, O_RDONLY|O_NDELAY);
125960fffc19Sjw149990 } else {
1260a0261a43SJames C. McPherson fd = open(openpath, O_RDONLY|O_NDELAY);
126160fffc19Sjw149990 }
126260fffc19Sjw149990
1263a0261a43SJames C. McPherson if (fd < 0) {
1264a0261a43SJames C. McPherson logmsg(MSG_INFO, "Unable to open path %s: %s\n",
1265a0261a43SJames C. McPherson openpath, strerror(errno));
1266a0261a43SJames C. McPherson return;
12677c478bd9Sstevel@tonic-gate }
12687c478bd9Sstevel@tonic-gate
1269a0261a43SJames C. McPherson if (devid_get(fd, thisdevid) != 0) {
1270a0261a43SJames C. McPherson logmsg(MSG_INFO,
1271a0261a43SJames C. McPherson "'%s' node (%s) without a devid registered\n",
1272a0261a43SJames C. McPherson di_driver_name(node), di_devfs_path(node));
127360fffc19Sjw149990 }
12747c478bd9Sstevel@tonic-gate (void) close(fd);
12757c478bd9Sstevel@tonic-gate }
12767c478bd9Sstevel@tonic-gate
12778cecff49Sgp87344 static int
print_bootpath()1278a0261a43SJames C. McPherson print_bootpath()
12798cecff49Sgp87344 {
1280a0261a43SJames C. McPherson char *bootprop = NULL;
12818cecff49Sgp87344
1282a0261a43SJames C. McPherson if (di_prop_lookup_strings(DDI_DEV_T_ANY, devinfo_root,
1283a0261a43SJames C. McPherson "bootpath", &bootprop) >= 0) {
1284a0261a43SJames C. McPherson (void) printf("%s\n", bootprop);
12858cecff49Sgp87344 return (0);
1286a0261a43SJames C. McPherson } else if (di_prop_lookup_strings(DDI_DEV_T_ANY, devinfo_root,
1287a0261a43SJames C. McPherson "boot-path", &bootprop) >= 0) {
1288a0261a43SJames C. McPherson (void) printf("%s\n", bootprop);
1289a0261a43SJames C. McPherson return (0);
1290a0261a43SJames C. McPherson } else {
1291a0261a43SJames C. McPherson (void) printf("ERROR: no bootpath/boot-path property found\n");
1292a0261a43SJames C. McPherson return (ENOENT);
1293a0261a43SJames C. McPherson }
12948cecff49Sgp87344 }
12958cecff49Sgp87344
12965b504601Sjiang wu - Sun Microsystems - Beijing China static void
get_phci_driver_name(char * phci_path,char ** driver_name)12975b504601Sjiang wu - Sun Microsystems - Beijing China get_phci_driver_name(char *phci_path, char **driver_name)
12985b504601Sjiang wu - Sun Microsystems - Beijing China {
12995b504601Sjiang wu - Sun Microsystems - Beijing China di_node_t phci_node = DI_NODE_NIL;
13005b504601Sjiang wu - Sun Microsystems - Beijing China char *tmp = NULL;
13015b504601Sjiang wu - Sun Microsystems - Beijing China
13025b504601Sjiang wu - Sun Microsystems - Beijing China phci_node = di_init(phci_path, DINFOCPYONE);
13035b504601Sjiang wu - Sun Microsystems - Beijing China if (phci_node == DI_NODE_NIL) {
13045b504601Sjiang wu - Sun Microsystems - Beijing China logmsg(MSG_ERROR,
13055b504601Sjiang wu - Sun Microsystems - Beijing China gettext("Unable to take phci snapshot "
13065b504601Sjiang wu - Sun Microsystems - Beijing China "(%s: %d)\n"), strerror(errno), errno);
13075b504601Sjiang wu - Sun Microsystems - Beijing China return;
13085b504601Sjiang wu - Sun Microsystems - Beijing China }
13095b504601Sjiang wu - Sun Microsystems - Beijing China tmp = di_driver_name(phci_node);
13105b504601Sjiang wu - Sun Microsystems - Beijing China if (tmp != NULL) {
13115b504601Sjiang wu - Sun Microsystems - Beijing China (void) strncpy(*driver_name, tmp, 10);
13125b504601Sjiang wu - Sun Microsystems - Beijing China }
13135b504601Sjiang wu - Sun Microsystems - Beijing China di_fini(phci_node);
13145b504601Sjiang wu - Sun Microsystems - Beijing China }
13157fc66be0Sjianfei wang - Sun Microsystems - Beijing China
13168cecff49Sgp87344 /*
1317a0261a43SJames C. McPherson * We only call this routine if we have a scsi_vhci node and must
1318a0261a43SJames C. McPherson * determine the actual physical path of its first online client
1319a0261a43SJames C. McPherson * path.
13207c478bd9Sstevel@tonic-gate */
1321a0261a43SJames C. McPherson static void
vhci_to_phci(char * devpath,char * slice,int d_flag)13227fc66be0Sjianfei wang - Sun Microsystems - Beijing China vhci_to_phci(char *devpath, char *slice, int d_flag)
13237c478bd9Sstevel@tonic-gate {
13247c478bd9Sstevel@tonic-gate sv_iocdata_t ioc;
13255a4c37c9Sqh201292 sv_path_info_t *pi;
1326a0261a43SJames C. McPherson int vhci_fd;
1327a0261a43SJames C. McPherson int rv;
1328a0261a43SJames C. McPherson uint_t npaths = 0;
13297fc66be0Sjianfei wang - Sun Microsystems - Beijing China char nodename[MAXPATHLEN];
13307fc66be0Sjianfei wang - Sun Microsystems - Beijing China char *phci_driver = NULL;
13315a4c37c9Sqh201292
1332a0261a43SJames C. McPherson vhci_fd = open(VHCI_CTL_NODE, O_RDWR);
1333a0261a43SJames C. McPherson if (vhci_fd < 0)
1334a0261a43SJames C. McPherson goto failure;
13355a4c37c9Sqh201292
13365a4c37c9Sqh201292 bzero(&ioc, sizeof (sv_iocdata_t));
1337a0261a43SJames C. McPherson ioc.client = devpath;
13385a4c37c9Sqh201292 ioc.ret_elem = &npaths;
1339a0261a43SJames C. McPherson rv = ioctl(vhci_fd, SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO, &ioc);
1340a0261a43SJames C. McPherson if (rv || npaths == 0) {
1341a0261a43SJames C. McPherson logmsg(MSG_INFO,
1342a0261a43SJames C. McPherson "SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO ioctl() failed, "
1343a0261a43SJames C. McPherson "%s (%d)\n", strerror(rv), rv);
1344a0261a43SJames C. McPherson goto failure;
13455a4c37c9Sqh201292 }
13465a4c37c9Sqh201292
13475a4c37c9Sqh201292 bzero(&ioc, sizeof (sv_iocdata_t));
1348a0261a43SJames C. McPherson ioc.client = devpath;
13495a4c37c9Sqh201292 ioc.buf_elem = npaths;
13505a4c37c9Sqh201292 ioc.ret_elem = &npaths;
1351a0261a43SJames C. McPherson if ((ioc.ret_buf = calloc(npaths, sizeof (sv_path_info_t)))
1352a0261a43SJames C. McPherson == NULL)
1353a0261a43SJames C. McPherson goto failure;
1354a0261a43SJames C. McPherson rv = ioctl(vhci_fd, SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO, &ioc);
1355a0261a43SJames C. McPherson if (rv || npaths == 0) {
1356a0261a43SJames C. McPherson logmsg(MSG_INFO,
1357a0261a43SJames C. McPherson "SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO ioctl() (#2) "
1358a0261a43SJames C. McPherson "failed, %s (%d)\n", strerror(rv), rv);
13597fc66be0Sjianfei wang - Sun Microsystems - Beijing China free(ioc.ret_buf);
1360a0261a43SJames C. McPherson goto failure;
13615a4c37c9Sqh201292 }
13625a4c37c9Sqh201292
13635a4c37c9Sqh201292 if (ioc.buf_elem < npaths)
13645a4c37c9Sqh201292 npaths = ioc.buf_elem;
13655a4c37c9Sqh201292
13665b504601Sjiang wu - Sun Microsystems - Beijing China phci_driver = malloc(10);
13675b504601Sjiang wu - Sun Microsystems - Beijing China if (phci_driver == NULL) {
13685b504601Sjiang wu - Sun Microsystems - Beijing China logmsg(MSG_INFO,
13695b504601Sjiang wu - Sun Microsystems - Beijing China "vhci_to_phci: Memory allocation failed\n");
13707fc66be0Sjianfei wang - Sun Microsystems - Beijing China free(ioc.ret_buf);
13715b504601Sjiang wu - Sun Microsystems - Beijing China goto failure;
13725b504601Sjiang wu - Sun Microsystems - Beijing China }
13737fc66be0Sjianfei wang - Sun Microsystems - Beijing China
13747fc66be0Sjianfei wang - Sun Microsystems - Beijing China pi = (sv_path_info_t *)ioc.ret_buf;
13757fc66be0Sjianfei wang - Sun Microsystems - Beijing China while (npaths--) {
13767fc66be0Sjianfei wang - Sun Microsystems - Beijing China bzero(nodename, MAXPATHLEN);
13775b504601Sjiang wu - Sun Microsystems - Beijing China bzero(phci_driver, 10);
13787fc66be0Sjianfei wang - Sun Microsystems - Beijing China
13795b504601Sjiang wu - Sun Microsystems - Beijing China get_phci_driver_name(pi->device.ret_phci,
13805b504601Sjiang wu - Sun Microsystems - Beijing China &phci_driver);
13815b504601Sjiang wu - Sun Microsystems - Beijing China logmsg(MSG_INFO, "phci driver name: %s\n", phci_driver);
13825b504601Sjiang wu - Sun Microsystems - Beijing China /*
13835b504601Sjiang wu - Sun Microsystems - Beijing China * A hack, but nicer than a platform-specific ifdef
13845b504601Sjiang wu - Sun Microsystems - Beijing China * fp on SPARC using "ssd" as nodename
13855b504601Sjiang wu - Sun Microsystems - Beijing China * mpt use "sd" when mpxio disabled, use "disk" when
13865b504601Sjiang wu - Sun Microsystems - Beijing China * mpxio is enabled
13875b504601Sjiang wu - Sun Microsystems - Beijing China * for alll other cases, "disk" should be used as the
13885b504601Sjiang wu - Sun Microsystems - Beijing China * nodename
13895b504601Sjiang wu - Sun Microsystems - Beijing China */
1390a0261a43SJames C. McPherson if (strstr(devpath, "ssd") != NULL) {
13915b504601Sjiang wu - Sun Microsystems - Beijing China (void) snprintf(nodename, 5, "ssd");
13925b504601Sjiang wu - Sun Microsystems - Beijing China } else if (strncmp(phci_driver, "mpt", 10) == 0) {
13935b504601Sjiang wu - Sun Microsystems - Beijing China (void) snprintf(nodename, 5, "sd");
1394a0261a43SJames C. McPherson } else {
13955b504601Sjiang wu - Sun Microsystems - Beijing China (void) snprintf(nodename, 5, "disk");
1396a0261a43SJames C. McPherson }
13979955cef3Sjianfei wang - Sun Microsystems - Beijing China if ((d_flag == DISPLAY_ONE_PATH) &&
13989955cef3Sjianfei wang - Sun Microsystems - Beijing China (pi->ret_state == MDI_PATHINFO_STATE_ONLINE)) {
13997fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("%s/%s@%s", pi->device.ret_phci,
14007fc66be0Sjianfei wang - Sun Microsystems - Beijing China nodename, pi->ret_addr);
14017fc66be0Sjianfei wang - Sun Microsystems - Beijing China if ((slice != NULL) && (strlen(slice) <= 3)) {
14027fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("%s\n", slice);
14037fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else {
14047fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("\n");
14057fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
14067fc66be0Sjianfei wang - Sun Microsystems - Beijing China break;
14077fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else if (d_flag == DISPLAY_ALL_PATH) {
14087fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("%s/%s@%s", pi->device.ret_phci,
14097fc66be0Sjianfei wang - Sun Microsystems - Beijing China nodename, pi->ret_addr);
14107fc66be0Sjianfei wang - Sun Microsystems - Beijing China if ((slice != NULL) && (strlen(slice) <= 3)) {
14117fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("%s\n", slice);
14127fc66be0Sjianfei wang - Sun Microsystems - Beijing China } else {
14137fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("\n");
14147fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
14157fc66be0Sjianfei wang - Sun Microsystems - Beijing China }
14165a4c37c9Sqh201292 pi++;
14175a4c37c9Sqh201292 }
14187fc66be0Sjianfei wang - Sun Microsystems - Beijing China free(ioc.ret_buf);
14197fc66be0Sjianfei wang - Sun Microsystems - Beijing China free(phci_driver);
14207fc66be0Sjianfei wang - Sun Microsystems - Beijing China return;
14215a4c37c9Sqh201292
1422a0261a43SJames C. McPherson failure:
14237fc66be0Sjianfei wang - Sun Microsystems - Beijing China (void) printf("NOT_MAPPED\n");
14245a4c37c9Sqh201292 }
14255a4c37c9Sqh201292
14265a4c37c9Sqh201292 /*
1427a0261a43SJames C. McPherson * Write /etc/vfstab to /etc/vfstab.new, with any remapped device
1428a0261a43SJames C. McPherson * names substituted.
14297c478bd9Sstevel@tonic-gate *
14307c478bd9Sstevel@tonic-gate * Returns:
1431a0261a43SJames C. McPherson * 0 successful operation
14327c478bd9Sstevel@tonic-gate * -1 failed
14337c478bd9Sstevel@tonic-gate */
14347c478bd9Sstevel@tonic-gate static int
update_vfstab()1435a0261a43SJames C. McPherson update_vfstab()
14367c478bd9Sstevel@tonic-gate {
1437a0261a43SJames C. McPherson FILE *fdin, *fdout;
14387c478bd9Sstevel@tonic-gate char *buf, *tmpbuf;
1439a0261a43SJames C. McPherson char fname[MAXPATHLEN];
1440a0261a43SJames C. McPherson int rv = -1, rval = -1;
14417c478bd9Sstevel@tonic-gate char cdev[MAXPATHLEN];
14427c478bd9Sstevel@tonic-gate char bdev[MAXPATHLEN];
14437c478bd9Sstevel@tonic-gate char mntpt[MAXPATHLEN];
14447c478bd9Sstevel@tonic-gate char fstype[512];
14457c478bd9Sstevel@tonic-gate char fsckpass[512];
14467c478bd9Sstevel@tonic-gate char mntboot[512];
1447a0261a43SJames C. McPherson char mntopt[MAXPATHLEN];
14487c478bd9Sstevel@tonic-gate char fmt[80];
1449a0261a43SJames C. McPherson char *prefixt = NULL;
1450a0261a43SJames C. McPherson char *curdev = NULL;
1451a0261a43SJames C. McPherson char *thisdevid = NULL;
1452a0261a43SJames C. McPherson char *slice = NULL;
1453a0261a43SJames C. McPherson nvlist_t *thisdev;
1454a0261a43SJames C. McPherson boolean_t devmpx = B_FALSE;
14557c478bd9Sstevel@tonic-gate
1456a0261a43SJames C. McPherson buf = calloc(1, MAXPATHLEN);
1457a0261a43SJames C. McPherson tmpbuf = calloc(1, MAXPATHLEN);
1458a0261a43SJames C. McPherson if (buf == NULL || tmpbuf == NULL)
14597c478bd9Sstevel@tonic-gate return (-1);
14607c478bd9Sstevel@tonic-gate
1461a0261a43SJames C. McPherson (void) snprintf(fname, MAXPATHLEN, "/etc/mpxio/vfstab.new");
1462a0261a43SJames C. McPherson
1463a0261a43SJames C. McPherson fdin = fopen("/etc/vfstab", "r");
1464a0261a43SJames C. McPherson fdout = fopen(fname, "w+");
1465a0261a43SJames C. McPherson if (fdin == NULL || fdout == NULL) {
1466a0261a43SJames C. McPherson logmsg(MSG_INFO, "Unable to open vfstab or create a backup "
1467a0261a43SJames C. McPherson "vfstab %s\n");
1468a0261a43SJames C. McPherson return (-1);
1469a0261a43SJames C. McPherson }
14707c478bd9Sstevel@tonic-gate
14717c478bd9Sstevel@tonic-gate (void) snprintf(fmt, sizeof (fmt),
14727c478bd9Sstevel@tonic-gate "%%%ds %%%ds %%%ds %%%ds %%%ds %%%ds %%%ds", sizeof (bdev) - 1,
14737c478bd9Sstevel@tonic-gate sizeof (cdev) - 1, sizeof (mntpt) - 1, sizeof (fstype) - 1,
14747c478bd9Sstevel@tonic-gate sizeof (fsckpass) - 1, sizeof (mntboot) - 1, sizeof (mntopt) - 1);
14757c478bd9Sstevel@tonic-gate
1476a0261a43SJames C. McPherson while (fgets(buf, MAXPATHLEN, fdin) != NULL) {
1477a0261a43SJames C. McPherson if (strlen(buf) == (MAXPATHLEN - 1) &&
1478a0261a43SJames C. McPherson buf[MAXPATHLEN-2] != '\n') {
1479a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1480a0261a43SJames C. McPherson gettext("/etc/vfstab line length too long, "
14817c478bd9Sstevel@tonic-gate "exceeded %2$d: \"%3$s\"\n"),
1482a0261a43SJames C. McPherson MAXPATHLEN - 2, buf);
14837c478bd9Sstevel@tonic-gate goto out;
14847c478bd9Sstevel@tonic-gate }
14857c478bd9Sstevel@tonic-gate
1486a0261a43SJames C. McPherson prefixt = NULL;
1487a0261a43SJames C. McPherson curdev = NULL;
1488a0261a43SJames C. McPherson slice = NULL;
1489a0261a43SJames C. McPherson thisdevid = NULL;
1490a0261a43SJames C. McPherson thisdev = NULL;
14917c478bd9Sstevel@tonic-gate
1492a0261a43SJames C. McPherson /* LINTED - variable format specifier */
1493a0261a43SJames C. McPherson rv = sscanf(buf, fmt, bdev, cdev, mntpt, fstype, fsckpass,
1494a0261a43SJames C. McPherson mntboot, mntopt);
14957c478bd9Sstevel@tonic-gate
14967c478bd9Sstevel@tonic-gate /*
1497a0261a43SJames C. McPherson * Walk through the lines in the input file (/etc/vfstab),
1498a0261a43SJames C. McPherson * skipping anything which is _not_ a COGD (common or garden
1499a0261a43SJames C. McPherson * disk), ie all the /devices, /system, /dev/md, /dev/vx and
1500a0261a43SJames C. McPherson * /dev/zvol and so forth.
15017c478bd9Sstevel@tonic-gate */
1502a0261a43SJames C. McPherson if ((rv == 7) && (bdev[0] == '/') &&
1503a0261a43SJames C. McPherson (strstr(bdev, "/dev/dsk"))) {
1504a0261a43SJames C. McPherson slice = strrchr(bdev, 's');
1505a0261a43SJames C. McPherson /* take a copy, strip off /dev/dsk/ */
1506a0261a43SJames C. McPherson prefixt = strrchr(bdev, 'c');
1507a0261a43SJames C. McPherson prefixt[strlen(bdev) - 9 - strlen(slice)] = '\0';
1508a0261a43SJames C. McPherson slice++; /* advance past the s */
1509a0261a43SJames C. McPherson rval = nvlist_lookup_string(mapnvl, prefixt,
1510a0261a43SJames C. McPherson &thisdevid);
1511a0261a43SJames C. McPherson if (rval) {
1512a0261a43SJames C. McPherson /* Whoa, where did this device go?! */
1513a0261a43SJames C. McPherson logmsg(MSG_INFO,
1514a0261a43SJames C. McPherson "error looking up device %s\n", prefixt);
1515a0261a43SJames C. McPherson /* Comment-out this line in the new version */
1516a0261a43SJames C. McPherson (void) snprintf(tmpbuf, MAXPATHLEN,
1517a0261a43SJames C. McPherson "# DEVICE NOT FOUND %s", buf);
1518a0261a43SJames C. McPherson (void) fprintf(fdout, "%s", tmpbuf);
1519a0261a43SJames C. McPherson continue;
1520a0261a43SJames C. McPherson } else {
1521a0261a43SJames C. McPherson /* The device exists in our mapnvl */
1522a0261a43SJames C. McPherson (void) nvlist_lookup_nvlist(mapnvl, thisdevid,
1523a0261a43SJames C. McPherson &thisdev);
1524a0261a43SJames C. McPherson (void) nvlist_lookup_boolean_value(thisdev,
1525a0261a43SJames C. McPherson NVL_MPXEN, &devmpx);
1526a0261a43SJames C. McPherson (void) nvlist_lookup_string(thisdev,
1527a0261a43SJames C. McPherson ((devmpx == B_TRUE)
1528a0261a43SJames C. McPherson ? NVL_MPXPATH : NVL_PATH),
1529a0261a43SJames C. McPherson &curdev);
1530a0261a43SJames C. McPherson }
15317c478bd9Sstevel@tonic-gate }
15327c478bd9Sstevel@tonic-gate
1533a0261a43SJames C. McPherson if ((prefixt != NULL) && (curdev != NULL) &&
1534a0261a43SJames C. McPherson (rv = (strncmp(prefixt, curdev, strlen(prefixt)) != 0))) {
1535a0261a43SJames C. McPherson /* Mapping change for this device */
1536a0261a43SJames C. McPherson if (strcmp(fstype, "swap") == 0) {
1537a0261a43SJames C. McPherson (void) snprintf(tmpbuf, MAXPATHLEN,
1538a0261a43SJames C. McPherson "/dev/dsk/%ss%s\t-\t-\tswap\t"
1539a0261a43SJames C. McPherson "%s\t%s\t%s\n",
1540a0261a43SJames C. McPherson curdev, slice, fsckpass, mntboot, mntopt);
1541a0261a43SJames C. McPherson } else {
1542a0261a43SJames C. McPherson (void) snprintf(tmpbuf, MAXPATHLEN,
1543a0261a43SJames C. McPherson "/dev/dsk/%ss%s\t/dev/rdsk/%ss%s\t"
1544a0261a43SJames C. McPherson "%s\t%s\t%s\t%s\t%s\n",
1545a0261a43SJames C. McPherson curdev, slice, curdev, slice,
1546a0261a43SJames C. McPherson mntpt, fstype, fsckpass, mntboot, mntopt);
1547a0261a43SJames C. McPherson }
1548a0261a43SJames C. McPherson errno = 0;
1549a0261a43SJames C. McPherson (void) fprintf(fdout, "%s", tmpbuf);
1550a0261a43SJames C. McPherson } else {
1551a0261a43SJames C. McPherson (void) fprintf(fdout, "%s", buf);
1552a0261a43SJames C. McPherson }
1553a0261a43SJames C. McPherson
1554a0261a43SJames C. McPherson errno = 0;
1555a0261a43SJames C. McPherson if (fflush(fdout) != 0) {
1556a0261a43SJames C. McPherson logmsg(MSG_ERROR,
1557a0261a43SJames C. McPherson gettext("fprintf failed to write to %s: %s (%d)\n"),
1558a0261a43SJames C. McPherson fname, strerror(errno), errno);
15597c478bd9Sstevel@tonic-gate goto out;
15607c478bd9Sstevel@tonic-gate }
15617c478bd9Sstevel@tonic-gate }
15627c478bd9Sstevel@tonic-gate out:
1563a0261a43SJames C. McPherson (void) fclose(fdin);
1564a0261a43SJames C. McPherson (void) fclose(fdout);
15657c478bd9Sstevel@tonic-gate free(buf);
15667c478bd9Sstevel@tonic-gate free(tmpbuf);
1567a0261a43SJames C. McPherson return (errno);
15688cecff49Sgp87344 }
1569