1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte /*
22fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23fcf3ce44SJohn Forte * Use is subject to license terms.
24fcf3ce44SJohn Forte */
25fcf3ce44SJohn Forte
26fcf3ce44SJohn Forte
27fcf3ce44SJohn Forte
28fcf3ce44SJohn Forte /*LINTLIBRARY*/
29fcf3ce44SJohn Forte
30fcf3ce44SJohn Forte
31fcf3ce44SJohn Forte /*
32fcf3ce44SJohn Forte * Hotplug program for SENA, RSM and SSA
33fcf3ce44SJohn Forte * subsystems and individual FC_AL devices.
34fcf3ce44SJohn Forte */
35fcf3ce44SJohn Forte
36fcf3ce44SJohn Forte /* #define _POSIX_SOURCE 1 */
37fcf3ce44SJohn Forte
38fcf3ce44SJohn Forte /*
39fcf3ce44SJohn Forte * I18N message number ranges
40fcf3ce44SJohn Forte * This file: 5500 - 5999
41fcf3ce44SJohn Forte * Shared common messages: 1 - 1999
42fcf3ce44SJohn Forte */
43fcf3ce44SJohn Forte
44fcf3ce44SJohn Forte
45fcf3ce44SJohn Forte /* Includes */
46fcf3ce44SJohn Forte #include <stdlib.h>
47fcf3ce44SJohn Forte #include <stdio.h>
48fcf3ce44SJohn Forte #include <sys/file.h>
49fcf3ce44SJohn Forte #include <sys/errno.h>
50fcf3ce44SJohn Forte #include <sys/types.h>
51fcf3ce44SJohn Forte #include <sys/stat.h>
52fcf3ce44SJohn Forte #include <sys/utsname.h>
53fcf3ce44SJohn Forte #include <fcntl.h>
54fcf3ce44SJohn Forte #include <unistd.h>
55fcf3ce44SJohn Forte #include <errno.h>
56fcf3ce44SJohn Forte #include <string.h>
57fcf3ce44SJohn Forte #include <sys/sunddi.h>
58fcf3ce44SJohn Forte #include <sys/ddi.h> /* for min */
59fcf3ce44SJohn Forte #include <sys/scsi/scsi.h>
60fcf3ce44SJohn Forte #include <nl_types.h>
61fcf3ce44SJohn Forte #include <dirent.h>
62fcf3ce44SJohn Forte #include <sys/wait.h>
63fcf3ce44SJohn Forte #include <l_common.h>
64fcf3ce44SJohn Forte #include <l_error.h>
65fcf3ce44SJohn Forte #include <stgcom.h>
66fcf3ce44SJohn Forte #include <a_state.h>
67fcf3ce44SJohn Forte #include <a5k.h>
68fcf3ce44SJohn Forte #include <rom.h>
69fcf3ce44SJohn Forte #include "hot.h"
70fcf3ce44SJohn Forte #include "common.h"
71fcf3ce44SJohn Forte #include "luxadm.h"
72fcf3ce44SJohn Forte
73fcf3ce44SJohn Forte
74fcf3ce44SJohn Forte /* Internal variables. */
75fcf3ce44SJohn Forte static char *cmdStrg[][4] = {
76fcf3ce44SJohn Forte { "disks", "-C", 0, 0 },
77fcf3ce44SJohn Forte { "disks", 0, 0, 0 },
78fcf3ce44SJohn Forte { "drvconfig", "-i", "ssd", 0 },
79fcf3ce44SJohn Forte { "drvconfig", 0, 0, 0 },
80fcf3ce44SJohn Forte { "devlinks", 0, 0, 0 },
81fcf3ce44SJohn Forte { "tapes", "-C", 0, 0 }
82fcf3ce44SJohn Forte };
83fcf3ce44SJohn Forte
84fcf3ce44SJohn Forte /* External variables */
85fcf3ce44SJohn Forte extern char *dtype[]; /* From adm.c */
86fcf3ce44SJohn Forte extern int Options;
87fcf3ce44SJohn Forte extern const int OPTION_CAPF;
88fcf3ce44SJohn Forte
89fcf3ce44SJohn Forte /* Internal functions */
90fcf3ce44SJohn Forte /* SENA and Individual FC device Hotplug */
91fcf3ce44SJohn Forte static int h_pre_insert_encl_dev(timestruc_t *, timestruc_t *,
92fcf3ce44SJohn Forte timestruc_t *);
93fcf3ce44SJohn Forte static int h_post_insert_dev(timestruc_t, timestruc_t);
94fcf3ce44SJohn Forte static int h_pre_remove_dev(Hotplug_Devlist *,
95fcf3ce44SJohn Forte WWN_list *wwn_list, int, int);
96fcf3ce44SJohn Forte static int h_post_remove_dev(Hotplug_Devlist *, int, int);
97fcf3ce44SJohn Forte static int h_pre_hotplug(Hotplug_Devlist **,
98fcf3ce44SJohn Forte WWN_list *, int, int, int);
99fcf3ce44SJohn Forte static int h_post_hotplug(Hotplug_Devlist *,
100fcf3ce44SJohn Forte WWN_list *, int, int, int, int);
101fcf3ce44SJohn Forte static int h_post_insert_encl(timestruc_t);
102fcf3ce44SJohn Forte static int h_pre_hotplug_sena(Hotplug_Devlist *,
103fcf3ce44SJohn Forte WWN_list *, int, int, int);
104fcf3ce44SJohn Forte static int h_post_hotplug_sena(Hotplug_Devlist *,
105fcf3ce44SJohn Forte WWN_list *, int, int, int, int);
106fcf3ce44SJohn Forte static int h_remove_ses_nodes(struct dlist *);
107525fef19SToomas Soome static int h_print_list_warn(Hotplug_Devlist *, int, int);
108fcf3ce44SJohn Forte static int h_display_logical_nodes(struct dlist *);
109fcf3ce44SJohn Forte static void h_print_logical_nodes(struct dlist *);
110fcf3ce44SJohn Forte static int h_remove_nodes(struct dlist *);
111fcf3ce44SJohn Forte static int h_print_list(Hotplug_Devlist *, int *, int);
112fcf3ce44SJohn Forte static int h_get_fcdev_state(char *, char *, int, int *, int *, int);
113fcf3ce44SJohn Forte static int h_chk_dev_busy(Hotplug_Devlist *,
114fcf3ce44SJohn Forte WWN_list *, int *, int, int);
115fcf3ce44SJohn Forte static int h_execCmnd(char **, int);
116fcf3ce44SJohn Forte int hotplug(int, char **, int, int);
117fcf3ce44SJohn Forte int h_insertSena_fcdev();
118fcf3ce44SJohn Forte static int h_find_new_device_link(char *, timestruc_t);
119fcf3ce44SJohn Forte
120fcf3ce44SJohn Forte
121fcf3ce44SJohn Forte
122fcf3ce44SJohn Forte /*
123fcf3ce44SJohn Forte * Assists the user in hot inserting FC_AL
124fcf3ce44SJohn Forte * individual device(s) and SENA enclosure(s).
125fcf3ce44SJohn Forte *
126fcf3ce44SJohn Forte * RETURNS:
127fcf3ce44SJohn Forte * 0 if OK
128fcf3ce44SJohn Forte * non-zero otherwise
129fcf3ce44SJohn Forte */
130fcf3ce44SJohn Forte int
h_insertSena_fcdev()131fcf3ce44SJohn Forte h_insertSena_fcdev()
132fcf3ce44SJohn Forte {
133fcf3ce44SJohn Forte timestruc_t ses_time, dsk_time, rmt_time;
134fcf3ce44SJohn Forte int err;
135fcf3ce44SJohn Forte struct stat ses_stat;
136fcf3ce44SJohn Forte
137fcf3ce44SJohn Forte if ((err = h_pre_insert_encl_dev(&ses_time, &dsk_time,
138fcf3ce44SJohn Forte &rmt_time)) != 0) {
139fcf3ce44SJohn Forte return (err);
140fcf3ce44SJohn Forte }
141fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5500,
142fcf3ce44SJohn Forte "Please hit <RETURN> when you have finished"
143fcf3ce44SJohn Forte " adding Fibre Channel Enclosure(s)/Device(s): "));
144fcf3ce44SJohn Forte (void) getchar();
145fcf3ce44SJohn Forte
146fcf3ce44SJohn Forte if ((err = h_post_insert_dev(dsk_time, rmt_time)) != 0) {
147fcf3ce44SJohn Forte return (err);
148fcf3ce44SJohn Forte }
149fcf3ce44SJohn Forte
150fcf3ce44SJohn Forte if (stat(SES_DIR, &ses_stat) < 0) {
151fcf3ce44SJohn Forte /*
152fcf3ce44SJohn Forte * Non existence of /dev/es dir indicates
153fcf3ce44SJohn Forte * no ses devices inserted.
154fcf3ce44SJohn Forte * No need to call h_post_insert_encl().
155fcf3ce44SJohn Forte */
156fcf3ce44SJohn Forte if (errno == ENOENT) {
157fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5662,
158fcf3ce44SJohn Forte " No new enclosure(s) were added!!\n\n"));
159fcf3ce44SJohn Forte return (0);
160fcf3ce44SJohn Forte } else {
161fcf3ce44SJohn Forte return (L_LSTAT_ES_DIR_ERROR);
162fcf3ce44SJohn Forte }
163fcf3ce44SJohn Forte }
164fcf3ce44SJohn Forte
165fcf3ce44SJohn Forte /*
166fcf3ce44SJohn Forte * if the latest mod time of /dev/es is not newer than
167fcf3ce44SJohn Forte * the original mod time no need to call
168fcf3ce44SJohn Forte * h_post_insert_encl().
169fcf3ce44SJohn Forte */
170fcf3ce44SJohn Forte if ((&ses_time != (timestruc_t *)NULL) &&
171fcf3ce44SJohn Forte !(NEWER(ses_stat.st_ctim, ses_time))) {
172fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5662,
173fcf3ce44SJohn Forte " No new enclosure(s) were added!!\n\n"));
174fcf3ce44SJohn Forte return (0);
175fcf3ce44SJohn Forte }
176fcf3ce44SJohn Forte if ((err = h_post_insert_encl(ses_time)) != 0) {
177fcf3ce44SJohn Forte return (err);
178fcf3ce44SJohn Forte }
179fcf3ce44SJohn Forte return (0);
180fcf3ce44SJohn Forte }
181fcf3ce44SJohn Forte
182fcf3ce44SJohn Forte
183fcf3ce44SJohn Forte
184fcf3ce44SJohn Forte /*
185fcf3ce44SJohn Forte * gets the devices state - check for disk's reservations.
186fcf3ce44SJohn Forte *
187fcf3ce44SJohn Forte * RETURNS:
188fcf3ce44SJohn Forte * 0 if OK
189fcf3ce44SJohn Forte * non-zero otherwise
190fcf3ce44SJohn Forte */
191fcf3ce44SJohn Forte static int
h_get_fcdev_state(char * fc_dev,char * path_phys,int force_flag,int * busy_flag,int * reserve_flag,int verbose_flag)192fcf3ce44SJohn Forte h_get_fcdev_state(char *fc_dev, char *path_phys, int force_flag,
193fcf3ce44SJohn Forte int *busy_flag, int *reserve_flag, int verbose_flag)
194fcf3ce44SJohn Forte {
195fcf3ce44SJohn Forte int err;
196fcf3ce44SJohn Forte L_inquiry inq;
197fcf3ce44SJohn Forte L_disk_state l_disk_state;
198fcf3ce44SJohn Forte
199fcf3ce44SJohn Forte
200fcf3ce44SJohn Forte if ((err = g_get_inquiry(path_phys, &inq)) != 0) {
201fcf3ce44SJohn Forte (void) fprintf(stderr,
202fcf3ce44SJohn Forte MSGSTR(5501,
203fcf3ce44SJohn Forte "Inquiry failed for %s\n"),
204fcf3ce44SJohn Forte path_phys);
205fcf3ce44SJohn Forte return (err);
206fcf3ce44SJohn Forte }
207fcf3ce44SJohn Forte if (inq.inq_port) {
208fcf3ce44SJohn Forte if ((err = l_get_disk_port_status(path_phys, &l_disk_state,
209fcf3ce44SJohn Forte FC_PORT_B, verbose_flag)) != 0) {
210fcf3ce44SJohn Forte return (err);
211fcf3ce44SJohn Forte }
212fcf3ce44SJohn Forte } else {
213fcf3ce44SJohn Forte if ((err = l_get_disk_port_status(path_phys, &l_disk_state,
214fcf3ce44SJohn Forte FC_PORT_A, verbose_flag)) != 0) {
215fcf3ce44SJohn Forte return (err);
216fcf3ce44SJohn Forte }
217fcf3ce44SJohn Forte }
218fcf3ce44SJohn Forte
219fcf3ce44SJohn Forte /*
220fcf3ce44SJohn Forte * Don't print error msg. if disk is reserved
221fcf3ce44SJohn Forte * and tried to be removed from the same port.
222fcf3ce44SJohn Forte * If force flag is set, remove the disk without
223fcf3ce44SJohn Forte * checking the disk reservations.
224fcf3ce44SJohn Forte */
225fcf3ce44SJohn Forte if (!force_flag) {
226fcf3ce44SJohn Forte if (((inq.inq_port) &&
227fcf3ce44SJohn Forte (l_disk_state.g_disk_state.d_state_flags[FC_PORT_B] &
228fcf3ce44SJohn Forte L_RESERVED)) ||
229fcf3ce44SJohn Forte ((!inq.inq_port) &&
230fcf3ce44SJohn Forte (l_disk_state.g_disk_state.d_state_flags[FC_PORT_A] &
231fcf3ce44SJohn Forte L_RESERVED))) {
232fcf3ce44SJohn Forte *reserve_flag = 1;
233fcf3ce44SJohn Forte }
234fcf3ce44SJohn Forte }
235fcf3ce44SJohn Forte return (0);
236fcf3ce44SJohn Forte }
237fcf3ce44SJohn Forte
238fcf3ce44SJohn Forte
239fcf3ce44SJohn Forte /*
240fcf3ce44SJohn Forte * Forks a child process and let the child to
241fcf3ce44SJohn Forte * execute a given command string by calling the
242fcf3ce44SJohn Forte * the execvp() function. Then, the parent process
243fcf3ce44SJohn Forte * waits for the child to exit. Once the parent process
244fcf3ce44SJohn Forte * is notified by the kernel with the termination of
245fcf3ce44SJohn Forte * the child, then the parent checks for the exit
246fcf3ce44SJohn Forte * status of the child and return to the caller with -1 in case
247fcf3ce44SJohn Forte * of error and zero otherwise.
248fcf3ce44SJohn Forte *
249fcf3ce44SJohn Forte * RETURNS:
250fcf3ce44SJohn Forte * 0 if OK
251fcf3ce44SJohn Forte * non-zero otherwise
252fcf3ce44SJohn Forte */
253fcf3ce44SJohn Forte int
h_execCmnd(char * argStr[],int nArg)254fcf3ce44SJohn Forte h_execCmnd(char *argStr[], int nArg)
255fcf3ce44SJohn Forte {
256fcf3ce44SJohn Forte pid_t pid;
257fcf3ce44SJohn Forte int ix, status;
258fcf3ce44SJohn Forte
259fcf3ce44SJohn Forte if ((pid = fork()) < 0) {
260fcf3ce44SJohn Forte (void) fprintf(stderr,
261fcf3ce44SJohn Forte MSGSTR(133,
262fcf3ce44SJohn Forte "Error: Failed to fork a process.\n"));
263fcf3ce44SJohn Forte return (-1);
264fcf3ce44SJohn Forte } else if (pid == 0) {
265fcf3ce44SJohn Forte /* child process */
266fcf3ce44SJohn Forte if (execvp(argStr[0], argStr) < 0) {
267fcf3ce44SJohn Forte (void) fprintf(stderr,
268fcf3ce44SJohn Forte MSGSTR(5502,
269fcf3ce44SJohn Forte " Error: execvp() failed to run "
270fcf3ce44SJohn Forte "the command:"));
271fcf3ce44SJohn Forte for (ix = 0; ix < nArg; ix++) {
272fcf3ce44SJohn Forte (void) fprintf(stderr,
273fcf3ce44SJohn Forte " %s", argStr[ix]);
274fcf3ce44SJohn Forte }
275fcf3ce44SJohn Forte (void) fprintf(stderr, "\n");
276fcf3ce44SJohn Forte /* let parent know about the error. */
277fcf3ce44SJohn Forte exit(ENOEXEC);
278fcf3ce44SJohn Forte }
279fcf3ce44SJohn Forte }
280fcf3ce44SJohn Forte
281fcf3ce44SJohn Forte /* parent executes the following. */
282fcf3ce44SJohn Forte if (waitpid(pid, &status, 0) != pid) {
283fcf3ce44SJohn Forte (void) fprintf(stderr,
284fcf3ce44SJohn Forte MSGSTR(5503,
285fcf3ce44SJohn Forte "Error: waitpid() failed.\n"));
286fcf3ce44SJohn Forte return (-1);
287fcf3ce44SJohn Forte }
288fcf3ce44SJohn Forte if (WIFEXITED(status) &&
289fcf3ce44SJohn Forte WEXITSTATUS(status) == ENOEXEC) {
290fcf3ce44SJohn Forte /* child failed to run the command string. */
291fcf3ce44SJohn Forte return (-1);
292fcf3ce44SJohn Forte }
293fcf3ce44SJohn Forte return (0);
294fcf3ce44SJohn Forte
295fcf3ce44SJohn Forte }
296fcf3ce44SJohn Forte
297fcf3ce44SJohn Forte
298fcf3ce44SJohn Forte
299fcf3ce44SJohn Forte
300fcf3ce44SJohn Forte /*
301fcf3ce44SJohn Forte * frees the hotplug disk list structure.
302fcf3ce44SJohn Forte *
303fcf3ce44SJohn Forte * RETURNS:
304fcf3ce44SJohn Forte * N/A
305fcf3ce44SJohn Forte */
306fcf3ce44SJohn Forte void
h_free_hotplug_dlist(Hotplug_Devlist ** hotplug_dlist)307fcf3ce44SJohn Forte h_free_hotplug_dlist(Hotplug_Devlist **hotplug_dlist)
308fcf3ce44SJohn Forte {
309fcf3ce44SJohn Forte Hotplug_Devlist *list = NULL;
310fcf3ce44SJohn Forte
311fcf3ce44SJohn Forte while (*hotplug_dlist != NULL) {
312fcf3ce44SJohn Forte list = *hotplug_dlist;
313fcf3ce44SJohn Forte *hotplug_dlist = (*hotplug_dlist)->next;
314fcf3ce44SJohn Forte (void) g_free_multipath(list->seslist);
315fcf3ce44SJohn Forte (void) g_free_multipath(list->dlhead);
316fcf3ce44SJohn Forte (void) free((void *)list);
317fcf3ce44SJohn Forte }
318fcf3ce44SJohn Forte }
319fcf3ce44SJohn Forte
320fcf3ce44SJohn Forte
321fcf3ce44SJohn Forte /*
322fcf3ce44SJohn Forte * finds whether device (SENA or an FCAL device) is busy or not.
323fcf3ce44SJohn Forte *
324fcf3ce44SJohn Forte * OUTPUT:
325fcf3ce44SJohn Forte * busy_flag = 1 (if device busy)
326fcf3ce44SJohn Forte *
327fcf3ce44SJohn Forte * RETURNS:
328fcf3ce44SJohn Forte * 0 if O.K.
329fcf3ce44SJohn Forte * non-zero otherwise
330fcf3ce44SJohn Forte */
331fcf3ce44SJohn Forte static int
h_chk_dev_busy(Hotplug_Devlist * hotplug_dev,WWN_list * wwn_list,int * busy_flag,int force_flag,int verbose_flag)332fcf3ce44SJohn Forte h_chk_dev_busy(Hotplug_Devlist *hotplug_dev, WWN_list *wwn_list,
333fcf3ce44SJohn Forte int *busy_flag, int force_flag, int verbose_flag)
334fcf3ce44SJohn Forte {
335fcf3ce44SJohn Forte int err;
336fcf3ce44SJohn Forte struct dlist *dlist;
337fcf3ce44SJohn Forte
338fcf3ce44SJohn Forte if (hotplug_dev->dev_type == DTYPE_ESI) {
339fcf3ce44SJohn Forte if ((err = l_offline_photon(hotplug_dev, wwn_list,
340fcf3ce44SJohn Forte force_flag, verbose_flag)) != 0) {
341fcf3ce44SJohn Forte if (err == L_DEV_BUSY) {
342fcf3ce44SJohn Forte *busy_flag = 1;
343fcf3ce44SJohn Forte } else {
344fcf3ce44SJohn Forte return (err);
345fcf3ce44SJohn Forte }
346fcf3ce44SJohn Forte }
347fcf3ce44SJohn Forte for (dlist = hotplug_dev->dlhead;
348fcf3ce44SJohn Forte dlist != NULL; dlist = dlist->next) {
349fcf3ce44SJohn Forte (void) g_online_drive(dlist->multipath,
350fcf3ce44SJohn Forte force_flag);
351fcf3ce44SJohn Forte }
352fcf3ce44SJohn Forte } else {
353fcf3ce44SJohn Forte if ((err = g_offline_drive(hotplug_dev->dlhead,
354fcf3ce44SJohn Forte force_flag)) != 0) {
355fcf3ce44SJohn Forte if (err == L_DEV_BUSY) {
356fcf3ce44SJohn Forte *busy_flag = 1;
357fcf3ce44SJohn Forte } else {
358fcf3ce44SJohn Forte return (err);
359fcf3ce44SJohn Forte }
360fcf3ce44SJohn Forte }
361fcf3ce44SJohn Forte (void) g_online_drive(hotplug_dev->dlhead, force_flag);
362fcf3ce44SJohn Forte }
363fcf3ce44SJohn Forte return (0);
364fcf3ce44SJohn Forte }
365fcf3ce44SJohn Forte
366fcf3ce44SJohn Forte
367fcf3ce44SJohn Forte
368fcf3ce44SJohn Forte /*
369fcf3ce44SJohn Forte * prints the given list to stdout,
370fcf3ce44SJohn Forte * gets the input from user whether
371fcf3ce44SJohn Forte * to skip the busy devices or quit
372fcf3ce44SJohn Forte * and passes that input to the calling
373fcf3ce44SJohn Forte * function.
374fcf3ce44SJohn Forte *
375fcf3ce44SJohn Forte * OUTPUT:
376fcf3ce44SJohn Forte * int *action
377fcf3ce44SJohn Forte * s = Skip
378fcf3ce44SJohn Forte * q = Quit
379fcf3ce44SJohn Forte *
380fcf3ce44SJohn Forte * RETURNS:
381fcf3ce44SJohn Forte * 0 if OK
382fcf3ce44SJohn Forte * non-zero otherwise
383fcf3ce44SJohn Forte */
384fcf3ce44SJohn Forte static int
h_print_list(Hotplug_Devlist * bsyRsrv_disk_list,int * action,int enc_type)385fcf3ce44SJohn Forte h_print_list(Hotplug_Devlist *bsyRsrv_disk_list, int *action, int enc_type)
386fcf3ce44SJohn Forte {
387fcf3ce44SJohn Forte Hotplug_Devlist *list;
388fcf3ce44SJohn Forte int i = 1;
389fcf3ce44SJohn Forte char choice[2];
390fcf3ce44SJohn Forte
391fcf3ce44SJohn Forte (void) fprintf(stdout,
392fcf3ce44SJohn Forte MSGSTR(5504, "The list of devices being used"
393fcf3ce44SJohn Forte " (either busy or reserved) by the host:\n"));
394fcf3ce44SJohn Forte for (list = bsyRsrv_disk_list; list != NULL; list = list->next, i++) {
395fcf3ce44SJohn Forte if ((list->dev_type == DTYPE_DIRECT) &&
396fcf3ce44SJohn Forte (list->dev_location == SENA)) {
397525fef19SToomas Soome if (list->f_flag != 0) {
398fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) {
399fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5663,
400fcf3ce44SJohn Forte " %d: Box Name: \"%s\" slot %d\n"),
401fcf3ce44SJohn Forte i, list->box_name, list->slot);
402fcf3ce44SJohn Forte } else {
403fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(137,
404fcf3ce44SJohn Forte " %d: Box Name: \"%s\" front slot %d\n"),
405fcf3ce44SJohn Forte i, list->box_name, list->slot);
406fcf3ce44SJohn Forte }
407fcf3ce44SJohn Forte } else {
408fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) {
409fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5663,
410fcf3ce44SJohn Forte " %d: Box Name: \"%s\" slot %d\n"),
411fcf3ce44SJohn Forte i, list->box_name, list->slot + (MAX_DRIVES_DAK/2));
412fcf3ce44SJohn Forte } else {
413fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(136,
414fcf3ce44SJohn Forte " %d: Box Name: \"%s\" rear slot %d\n"),
415fcf3ce44SJohn Forte i, list->box_name, list->slot);
416fcf3ce44SJohn Forte }
417fcf3ce44SJohn Forte }
418fcf3ce44SJohn Forte } else if (((list->dev_type == DTYPE_DIRECT) ||
419fcf3ce44SJohn Forte (list->dev_type == DTYPE_SEQUENTIAL)) &&
420fcf3ce44SJohn Forte (list->dev_location == NON_SENA)) {
421fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5505,
422fcf3ce44SJohn Forte " %d: Device %s\n"),
423fcf3ce44SJohn Forte i, list->dev_name);
424fcf3ce44SJohn Forte } else if (list->dev_type == DTYPE_ESI) {
425fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5506,
426fcf3ce44SJohn Forte " %d: Box: %s\n"),
427fcf3ce44SJohn Forte i, list->box_name);
428fcf3ce44SJohn Forte }
429fcf3ce44SJohn Forte }
430fcf3ce44SJohn Forte
431fcf3ce44SJohn Forte /* Get the user input and continue accordingly. */
432fcf3ce44SJohn Forte (void) fprintf(stdout,
433fcf3ce44SJohn Forte MSGSTR(5507,
434fcf3ce44SJohn Forte "\n\nPlease enter 's' or <CR> to Skip the \"busy/reserved\""
435fcf3ce44SJohn Forte " device(s) or\n'q' to Quit and run the"
436fcf3ce44SJohn Forte " subcommand with\n-F (force) option. [Default: s]: "));
437fcf3ce44SJohn Forte for (;;) {
438fcf3ce44SJohn Forte (void) gets(choice);
439fcf3ce44SJohn Forte if (choice[0] == 'q' || choice[0] == 'Q' ||
440fcf3ce44SJohn Forte choice[0] == 's' || choice[0] == 'S' ||
441fcf3ce44SJohn Forte choice[0] == '\0') {
442fcf3ce44SJohn Forte break;
443fcf3ce44SJohn Forte }
444fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5508,
445fcf3ce44SJohn Forte " Enter an appropriate option [s,<CR>,q]: "));
446fcf3ce44SJohn Forte }
447fcf3ce44SJohn Forte if (choice[0] == 'q' || choice[0] == 'Q') {
448fcf3ce44SJohn Forte *action = QUIT;
449fcf3ce44SJohn Forte } else {
450fcf3ce44SJohn Forte *action = SKIP;
451fcf3ce44SJohn Forte }
452fcf3ce44SJohn Forte (void) fprintf(stdout, "\n\n");
453fcf3ce44SJohn Forte return (0);
454fcf3ce44SJohn Forte }
455fcf3ce44SJohn Forte
456fcf3ce44SJohn Forte
457fcf3ce44SJohn Forte
458fcf3ce44SJohn Forte /*
459fcf3ce44SJohn Forte * prints the warning message.
460fcf3ce44SJohn Forte *
461fcf3ce44SJohn Forte * RETURNS:
462fcf3ce44SJohn Forte * None.
463fcf3ce44SJohn Forte */
464fcf3ce44SJohn Forte static void
h_prt_warning()465fcf3ce44SJohn Forte h_prt_warning()
466fcf3ce44SJohn Forte {
467fcf3ce44SJohn Forte (void) fprintf(stderr,
468fcf3ce44SJohn Forte MSGSTR(5509,
469fcf3ce44SJohn Forte "\n WARNING!!! Please ensure that no"
470fcf3ce44SJohn Forte " filesystems are mounted on these device(s).\n"
471fcf3ce44SJohn Forte " All data on these devices should have been"
472fcf3ce44SJohn Forte " backed up.\n\n\n"));
473fcf3ce44SJohn Forte }
474fcf3ce44SJohn Forte
475fcf3ce44SJohn Forte
476fcf3ce44SJohn Forte
477fcf3ce44SJohn Forte /*
478fcf3ce44SJohn Forte * handle helper-mode hotplug commands
479fcf3ce44SJohn Forte *
480fcf3ce44SJohn Forte * RETURNS:
481fcf3ce44SJohn Forte * 0 if OK
482fcf3ce44SJohn Forte * non-zero otherwise
483fcf3ce44SJohn Forte */
484fcf3ce44SJohn Forte int
hotplug(int todo,char ** argv,int verbose_flag,int force_flag)485fcf3ce44SJohn Forte hotplug(int todo, char **argv, int verbose_flag, int force_flag)
486fcf3ce44SJohn Forte {
487fcf3ce44SJohn Forte char ses_path[MAXPATHLEN], dev_path[MAXPATHLEN];
488fcf3ce44SJohn Forte char *path_phys = NULL, code, node_wwn_s[WWN_S_LEN];
489fcf3ce44SJohn Forte char inq_path[MAXNAMELEN], *ptr = NULL;
490fcf3ce44SJohn Forte uchar_t node_wwn[WWN_SIZE], port_wwn[WWN_SIZE];
491*e9175934SKlaus Ziegler int tid, slot = 0, path_index, dtype, f_r, err = 0;
492*e9175934SKlaus Ziegler int al_pa, i, dev_location = 0, found_nullwwn = 0;
493fcf3ce44SJohn Forte int busy_flag = 0, reserve_flag = 0, action = 0;
494fcf3ce44SJohn Forte int pathcnt = 1;
495fcf3ce44SJohn Forte L_state l_state;
496fcf3ce44SJohn Forte gfc_map_t map;
497fcf3ce44SJohn Forte Path_struct *path_struct;
498fcf3ce44SJohn Forte WWN_list *wwn_list = NULL;
499fcf3ce44SJohn Forte Box_list *box_list;
500fcf3ce44SJohn Forte Hotplug_Devlist *disk_list, *disk_list_head, *disk_list_tail;
501fcf3ce44SJohn Forte Hotplug_Devlist *bsyRsrv_dskLst_head, *bsyRsrv_dskLst_tail;
502*e9175934SKlaus Ziegler int enc_type = 0;
503fcf3ce44SJohn Forte L_inquiry inq;
504fcf3ce44SJohn Forte char *physpath;
505fcf3ce44SJohn Forte Path_struct *p_pathstruct;
506fcf3ce44SJohn Forte char temp2path[MAXPATHLEN];
507fcf3ce44SJohn Forte mp_pathlist_t pathlist;
508fcf3ce44SJohn Forte int p_pw = 0, p_on = 0, p_st = 0;
509fcf3ce44SJohn Forte
510fcf3ce44SJohn Forte /* Initialize structures and pointers here */
511fcf3ce44SJohn Forte disk_list_head = disk_list_tail = (Hotplug_Devlist *)NULL;
512fcf3ce44SJohn Forte bsyRsrv_dskLst_head = (Hotplug_Devlist *)NULL;
513fcf3ce44SJohn Forte bsyRsrv_dskLst_tail = (Hotplug_Devlist *)NULL;
514fcf3ce44SJohn Forte map.dev_addr = NULL;
515fcf3ce44SJohn Forte
516fcf3ce44SJohn Forte #ifdef DEBUG
517fcf3ce44SJohn Forte (void) fprintf(stderr,
518fcf3ce44SJohn Forte "DEBUG: luxadm: hotplug() entering for \"%s\" ...\n",
519fcf3ce44SJohn Forte argv[0] ? argv[0] : "<null ptr>");
520fcf3ce44SJohn Forte #endif
521fcf3ce44SJohn Forte if ((err = l_get_box_list(&box_list, 0)) != 0) {
522fcf3ce44SJohn Forte return (err);
523fcf3ce44SJohn Forte }
524fcf3ce44SJohn Forte
525fcf3ce44SJohn Forte if (todo == REMOVE_DEVICE) {
526fcf3ce44SJohn Forte (void) h_prt_warning();
527fcf3ce44SJohn Forte }
528fcf3ce44SJohn Forte
529fcf3ce44SJohn Forte /*
530fcf3ce44SJohn Forte * At this point user want to insert or remove
531fcf3ce44SJohn Forte * one or more pathnames they've specified.
532fcf3ce44SJohn Forte */
533fcf3ce44SJohn Forte if ((err = g_get_wwn_list(&wwn_list, verbose_flag)) != 0) {
534fcf3ce44SJohn Forte (void) l_free_box_list(&box_list);
535fcf3ce44SJohn Forte return (err);
536fcf3ce44SJohn Forte }
537fcf3ce44SJohn Forte for (path_index = 0; argv[path_index] != NULL; path_index++) {
538fcf3ce44SJohn Forte if ((err = l_convert_name(argv[path_index], &path_phys,
539fcf3ce44SJohn Forte &path_struct, verbose_flag)) != 0) {
540fcf3ce44SJohn Forte /* Make sure we have a device path. */
541fcf3ce44SJohn Forte (void) strcpy(inq_path, argv[path_index]);
542fcf3ce44SJohn Forte if (((ptr = strstr(inq_path, ",")) != NULL) &&
543fcf3ce44SJohn Forte ((*(ptr + 1) == 'f') || (*(ptr + 1) == 'r') ||
544fcf3ce44SJohn Forte (*(ptr +1) == 's')) &&
545fcf3ce44SJohn Forte todo == REMOVE_DEVICE) {
546fcf3ce44SJohn Forte if (err != -1) {
547fcf3ce44SJohn Forte (void) print_errString(err,
548fcf3ce44SJohn Forte argv[path_index]);
549fcf3ce44SJohn Forte err = 0;
550fcf3ce44SJohn Forte continue;
551fcf3ce44SJohn Forte }
552525fef19SToomas Soome *ptr = '\0';
553fcf3ce44SJohn Forte slot = path_struct->slot;
554fcf3ce44SJohn Forte f_r = path_struct->f_flag;
555fcf3ce44SJohn Forte if ((err = l_convert_name(inq_path, &path_phys,
556fcf3ce44SJohn Forte &path_struct, verbose_flag)) != 0) {
557fcf3ce44SJohn Forte (void) fprintf(stderr, "\n");
558fcf3ce44SJohn Forte (void) fprintf(stderr,
559fcf3ce44SJohn Forte MSGSTR(33,
560fcf3ce44SJohn Forte " Error: converting"
561fcf3ce44SJohn Forte " %s to physical path.\n"
562fcf3ce44SJohn Forte " Invalid pathname.\n"),
563fcf3ce44SJohn Forte argv[path_index]);
564fcf3ce44SJohn Forte if (err != -1) {
565fcf3ce44SJohn Forte (void) print_errString(err,
566fcf3ce44SJohn Forte argv[path_index]);
567fcf3ce44SJohn Forte }
568fcf3ce44SJohn Forte err = 0;
569fcf3ce44SJohn Forte continue;
570fcf3ce44SJohn Forte }
571fcf3ce44SJohn Forte if ((err = print_devState(argv[path_index],
572fcf3ce44SJohn Forte path_struct->p_physical_path,
573fcf3ce44SJohn Forte f_r, slot, verbose_flag)) != 0) {
574fcf3ce44SJohn Forte err = 0;
575fcf3ce44SJohn Forte continue;
576fcf3ce44SJohn Forte }
577fcf3ce44SJohn Forte }
578fcf3ce44SJohn Forte if (path_struct->ib_path_flag) {
579fcf3ce44SJohn Forte path_phys = path_struct->p_physical_path;
580fcf3ce44SJohn Forte } else {
581fcf3ce44SJohn Forte if (err != -1) {
582fcf3ce44SJohn Forte (void) print_errString(err,
583fcf3ce44SJohn Forte argv[path_index]);
584fcf3ce44SJohn Forte } else {
585fcf3ce44SJohn Forte (void) fprintf(stderr, "\n");
586fcf3ce44SJohn Forte (void) fprintf(stderr,
587fcf3ce44SJohn Forte MSGSTR(33,
588fcf3ce44SJohn Forte " Error: converting"
589fcf3ce44SJohn Forte " %s to physical path.\n"
590fcf3ce44SJohn Forte " Invalid pathname.\n"),
591fcf3ce44SJohn Forte argv[path_index]);
592fcf3ce44SJohn Forte }
593fcf3ce44SJohn Forte err = 0;
594fcf3ce44SJohn Forte continue;
595fcf3ce44SJohn Forte }
596fcf3ce44SJohn Forte }
597fcf3ce44SJohn Forte if (path_struct->slot_valid ||
598fcf3ce44SJohn Forte strstr(path_phys, DRV_NAME_SSD)) {
599fcf3ce44SJohn Forte dtype = DTYPE_DIRECT;
600fcf3ce44SJohn Forte } else if (strstr(path_phys, SLSH_DRV_NAME_ST)) {
601fcf3ce44SJohn Forte dtype = DTYPE_SEQUENTIAL;
602fcf3ce44SJohn Forte } else {
603fcf3ce44SJohn Forte dtype = DTYPE_ESI;
604fcf3ce44SJohn Forte }
605fcf3ce44SJohn Forte
606fcf3ce44SJohn Forte if (strstr(path_phys, SCSI_VHCI) != NULL) {
607fcf3ce44SJohn Forte /* obtain phci */
608fcf3ce44SJohn Forte (void) strcpy(temp2path, path_phys);
609fcf3ce44SJohn Forte if (err = g_get_pathlist(temp2path, &pathlist)) {
610fcf3ce44SJohn Forte (void) print_errString(err, NULL);
611fcf3ce44SJohn Forte exit(-1);
612fcf3ce44SJohn Forte }
613fcf3ce44SJohn Forte pathcnt = pathlist.path_count;
614fcf3ce44SJohn Forte p_pw = p_on = p_st = 0;
615fcf3ce44SJohn Forte for (i = 0; i < pathcnt; i++) {
616fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state <
617fcf3ce44SJohn Forte MAXPATHSTATE) {
618fcf3ce44SJohn Forte if (strstr(pathlist.path_info[i].
619fcf3ce44SJohn Forte path_addr,
620fcf3ce44SJohn Forte path_struct->argv) != NULL) {
621fcf3ce44SJohn Forte p_pw = i;
622fcf3ce44SJohn Forte break;
623fcf3ce44SJohn Forte }
624fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state ==
625fcf3ce44SJohn Forte MDI_PATHINFO_STATE_ONLINE) {
626fcf3ce44SJohn Forte p_on = i;
627fcf3ce44SJohn Forte }
628fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state ==
629fcf3ce44SJohn Forte MDI_PATHINFO_STATE_STANDBY) {
630fcf3ce44SJohn Forte p_st = i;
631fcf3ce44SJohn Forte }
632fcf3ce44SJohn Forte }
633fcf3ce44SJohn Forte }
634fcf3ce44SJohn Forte if (strstr(pathlist.path_info[p_pw].path_addr,
635fcf3ce44SJohn Forte path_struct->argv) != NULL) {
636fcf3ce44SJohn Forte /* matching input pwwn */
637fcf3ce44SJohn Forte (void) strcpy(temp2path,
638fcf3ce44SJohn Forte pathlist.path_info[p_pw].path_hba);
639fcf3ce44SJohn Forte } else if (pathlist.path_info[p_on].path_state ==
640fcf3ce44SJohn Forte MDI_PATHINFO_STATE_ONLINE) {
641fcf3ce44SJohn Forte /* on_line path */
642fcf3ce44SJohn Forte (void) strcpy(temp2path,
643fcf3ce44SJohn Forte pathlist.path_info[p_on].path_hba);
644fcf3ce44SJohn Forte } else {
645fcf3ce44SJohn Forte /* standby or path0 */
646fcf3ce44SJohn Forte (void) strcpy(temp2path,
647fcf3ce44SJohn Forte pathlist.path_info[p_st].path_hba);
648fcf3ce44SJohn Forte }
649fcf3ce44SJohn Forte free(pathlist.path_info);
650fcf3ce44SJohn Forte (void) strcat(temp2path, FC_CTLR);
651fcf3ce44SJohn Forte } else {
652fcf3ce44SJohn Forte (void) strcpy(temp2path, path_phys);
653fcf3ce44SJohn Forte }
654fcf3ce44SJohn Forte
655fcf3ce44SJohn Forte if ((err = g_get_dev_map(temp2path, &map, verbose_flag))
656fcf3ce44SJohn Forte != 0) {
657fcf3ce44SJohn Forte return (err);
658fcf3ce44SJohn Forte }
659fcf3ce44SJohn Forte
660fcf3ce44SJohn Forte if ((map.hba_addr.port_topology == FC_TOP_PUBLIC_LOOP) ||
661fcf3ce44SJohn Forte (map.hba_addr.port_topology == FC_TOP_FABRIC)) {
662fcf3ce44SJohn Forte /* public or fabric loop device */
663fcf3ce44SJohn Forte free((void *)map.dev_addr);
664fcf3ce44SJohn Forte (void) fprintf(stderr, MSGSTR(5540,
665fcf3ce44SJohn Forte "This operation is not "
666fcf3ce44SJohn Forte "supported in this topology.\n"));
667fcf3ce44SJohn Forte exit(-1);
668fcf3ce44SJohn Forte }
669fcf3ce44SJohn Forte
670fcf3ce44SJohn Forte if (todo == REPLACE_DEVICE) {
671fcf3ce44SJohn Forte (void) fprintf(stderr,
672fcf3ce44SJohn Forte MSGSTR(5511,
673fcf3ce44SJohn Forte "Error:"
674fcf3ce44SJohn Forte " replace_device is not supported"
675fcf3ce44SJohn Forte " on this subsystem.\n"));
676fcf3ce44SJohn Forte exit(-1);
677fcf3ce44SJohn Forte }
678fcf3ce44SJohn Forte
679fcf3ce44SJohn Forte if ((todo == REMOVE_DEVICE) &&
680fcf3ce44SJohn Forte (dtype == DTYPE_DIRECT ||
681fcf3ce44SJohn Forte dtype == DTYPE_SEQUENTIAL ||
682fcf3ce44SJohn Forte dtype == DTYPE_UNKNOWN)) {
683fcf3ce44SJohn Forte if (l_chk_null_wwn(path_struct, ses_path,
684fcf3ce44SJohn Forte &l_state, verbose_flag) == 1) {
685fcf3ce44SJohn Forte found_nullwwn = 1;
686fcf3ce44SJohn Forte /*
687fcf3ce44SJohn Forte * set dev_path to NULL,
688fcf3ce44SJohn Forte * if disk has null wwn.
689fcf3ce44SJohn Forte */
690525fef19SToomas Soome *dev_path = '\0';
691fcf3ce44SJohn Forte dev_location = SENA;
692fcf3ce44SJohn Forte goto getinfo;
693fcf3ce44SJohn Forte }
694fcf3ce44SJohn Forte }
695fcf3ce44SJohn Forte
696fcf3ce44SJohn Forte (void) strcpy(ses_path, path_phys);
697fcf3ce44SJohn Forte
698fcf3ce44SJohn Forte if (strstr(ses_path, "ses") == NULL &&
699fcf3ce44SJohn Forte l_get_ses_path(path_phys, ses_path, &map,
700fcf3ce44SJohn Forte verbose_flag) != 0) {
701fcf3ce44SJohn Forte
702fcf3ce44SJohn Forte /* Could be a non-photon disk device */
703fcf3ce44SJohn Forte if ((todo == REMOVE_DEVICE) &&
704fcf3ce44SJohn Forte (dtype == DTYPE_DIRECT ||
705fcf3ce44SJohn Forte dtype == DTYPE_SEQUENTIAL)) {
706fcf3ce44SJohn Forte dev_location = NON_SENA;
707fcf3ce44SJohn Forte
708fcf3ce44SJohn Forte if ((err = h_get_fcdev_state(argv[path_index],
709fcf3ce44SJohn Forte path_phys, force_flag,
710fcf3ce44SJohn Forte &busy_flag, &reserve_flag,
711fcf3ce44SJohn Forte verbose_flag)) != 0) {
712fcf3ce44SJohn Forte goto done;
713fcf3ce44SJohn Forte }
714fcf3ce44SJohn Forte (void) strcpy(dev_path, path_phys);
715fcf3ce44SJohn Forte if ((err = g_get_wwn(dev_path, port_wwn,
716fcf3ce44SJohn Forte node_wwn, &al_pa,
717fcf3ce44SJohn Forte verbose_flag)) != 0) {
718fcf3ce44SJohn Forte goto done;
719fcf3ce44SJohn Forte }
720fcf3ce44SJohn Forte (void) sprintf(node_wwn_s,
721fcf3ce44SJohn Forte "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x",
722fcf3ce44SJohn Forte node_wwn[0], node_wwn[1], node_wwn[2],
723fcf3ce44SJohn Forte node_wwn[3], node_wwn[4], node_wwn[5],
724fcf3ce44SJohn Forte node_wwn[6], node_wwn[7]);
725fcf3ce44SJohn Forte tid = g_sf_alpa_to_switch[al_pa];
726fcf3ce44SJohn Forte goto loop;
727fcf3ce44SJohn Forte }
728fcf3ce44SJohn Forte continue;
729fcf3ce44SJohn Forte }
730fcf3ce44SJohn Forte
731fcf3ce44SJohn Forte if (strstr(ses_path, "ses") != NULL) {
732fcf3ce44SJohn Forte dev_location = SENA;
733fcf3ce44SJohn Forte if ((err = l_convert_name(ses_path, &physpath,
734fcf3ce44SJohn Forte &p_pathstruct, 0)) != 0) {
735fcf3ce44SJohn Forte free(physpath);
736fcf3ce44SJohn Forte free(p_pathstruct);
737fcf3ce44SJohn Forte goto done;
738fcf3ce44SJohn Forte
739fcf3ce44SJohn Forte }
740fcf3ce44SJohn Forte if ((err = g_get_inquiry(physpath, &inq)) != 0) {
741fcf3ce44SJohn Forte free(physpath);
742fcf3ce44SJohn Forte free(p_pathstruct);
743fcf3ce44SJohn Forte goto done;
744fcf3ce44SJohn Forte }
745fcf3ce44SJohn Forte enc_type = l_get_enc_type(inq);
746fcf3ce44SJohn Forte
747fcf3ce44SJohn Forte }
748fcf3ce44SJohn Forte if ((err = l_get_status(ses_path,
749fcf3ce44SJohn Forte &l_state, verbose_flag)) != 0) {
750fcf3ce44SJohn Forte goto done;
751fcf3ce44SJohn Forte }
752fcf3ce44SJohn Forte if (dtype == DTYPE_ESI) {
753fcf3ce44SJohn Forte /* could be removing a photon */
754fcf3ce44SJohn Forte if (todo == REMOVE_DEVICE) {
755fcf3ce44SJohn Forte /*
756fcf3ce44SJohn Forte * Need the select ID (tid) for the IB.
757fcf3ce44SJohn Forte */
758fcf3ce44SJohn Forte if ((err = g_get_wwn(ses_path, port_wwn,
759fcf3ce44SJohn Forte node_wwn, &al_pa,
760fcf3ce44SJohn Forte verbose_flag)) != 0) {
761fcf3ce44SJohn Forte goto done;
762fcf3ce44SJohn Forte }
763fcf3ce44SJohn Forte (void) sprintf(node_wwn_s,
764fcf3ce44SJohn Forte "%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x%1.2x",
765fcf3ce44SJohn Forte node_wwn[0], node_wwn[1], node_wwn[2],
766fcf3ce44SJohn Forte node_wwn[3], node_wwn[4], node_wwn[5],
767fcf3ce44SJohn Forte node_wwn[6], node_wwn[7]);
768fcf3ce44SJohn Forte tid = g_sf_alpa_to_switch[al_pa];
769fcf3ce44SJohn Forte *dev_path = '\0';
770fcf3ce44SJohn Forte /*
771fcf3ce44SJohn Forte * Check if any disk in this photon
772fcf3ce44SJohn Forte * is reserved by another host
773fcf3ce44SJohn Forte */
774fcf3ce44SJohn Forte if (!force_flag) {
775fcf3ce44SJohn Forte for (
776fcf3ce44SJohn Forte i = 0;
777fcf3ce44SJohn Forte i < l_state.total_num_drv/2;
778fcf3ce44SJohn Forte i++) {
779fcf3ce44SJohn Forte if ((l_state.drv_front[i].g_disk_state.d_state_flags[PORT_A] &
780fcf3ce44SJohn Forte L_RESERVED) ||
781fcf3ce44SJohn Forte (l_state.drv_front[i].g_disk_state.d_state_flags[PORT_B] &
782fcf3ce44SJohn Forte L_RESERVED) ||
783fcf3ce44SJohn Forte (l_state.drv_rear[i].g_disk_state.d_state_flags[PORT_A] &
784fcf3ce44SJohn Forte L_RESERVED) ||
785fcf3ce44SJohn Forte (l_state.drv_rear[i].g_disk_state.d_state_flags[PORT_B] &
786fcf3ce44SJohn Forte L_RESERVED)) {
787fcf3ce44SJohn Forte reserve_flag = 1;
788fcf3ce44SJohn Forte }
789fcf3ce44SJohn Forte }
790fcf3ce44SJohn Forte }
791fcf3ce44SJohn Forte goto loop;
792fcf3ce44SJohn Forte }
793fcf3ce44SJohn Forte (void) fprintf(stderr,
794fcf3ce44SJohn Forte MSGSTR(5512,
795fcf3ce44SJohn Forte "Error: %s already exists!!\n"),
796fcf3ce44SJohn Forte argv[path_index]);
797fcf3ce44SJohn Forte goto done;
798fcf3ce44SJohn Forte }
799fcf3ce44SJohn Forte getinfo:
800fcf3ce44SJohn Forte if (!path_struct->slot_valid) {
801fcf3ce44SJohn Forte /* We are passing the disks path */
802fcf3ce44SJohn Forte if ((err = l_get_slot(path_struct, &l_state,
803fcf3ce44SJohn Forte verbose_flag)) != 0) {
804fcf3ce44SJohn Forte goto done;
805fcf3ce44SJohn Forte }
806fcf3ce44SJohn Forte }
807fcf3ce44SJohn Forte
808fcf3ce44SJohn Forte slot = path_struct->slot;
809fcf3ce44SJohn Forte if (path_struct->f_flag) {
810fcf3ce44SJohn Forte tid = l_state.drv_front[slot].ib_status.sel_id;
811fcf3ce44SJohn Forte code = l_state.drv_front[slot].ib_status.code;
812fcf3ce44SJohn Forte (void) strcpy(node_wwn_s,
813fcf3ce44SJohn Forte l_state.drv_front[slot].g_disk_state.node_wwn_s);
814fcf3ce44SJohn Forte } else {
815fcf3ce44SJohn Forte tid = l_state.drv_rear[slot].ib_status.sel_id;
816fcf3ce44SJohn Forte code = l_state.drv_rear[slot].ib_status.code;
817fcf3ce44SJohn Forte (void) strcpy(node_wwn_s,
818fcf3ce44SJohn Forte l_state.drv_rear[slot].g_disk_state.node_wwn_s);
819fcf3ce44SJohn Forte }
820fcf3ce44SJohn Forte
821fcf3ce44SJohn Forte if (found_nullwwn) {
822fcf3ce44SJohn Forte goto loop;
823fcf3ce44SJohn Forte }
824fcf3ce44SJohn Forte
825fcf3ce44SJohn Forte l_make_node(ses_path, tid, dev_path, &map, 0);
826fcf3ce44SJohn Forte
827fcf3ce44SJohn Forte if ((todo == INSERT_DEVICE) &&
828fcf3ce44SJohn Forte (g_device_in_map(&map, tid) ||
829fcf3ce44SJohn Forte (code != S_NOT_INSTALLED))) {
830fcf3ce44SJohn Forte (void) fprintf(stderr,
831fcf3ce44SJohn Forte MSGSTR(5513, "\nNotice: %s may "
832fcf3ce44SJohn Forte "already be present.\n"),
833fcf3ce44SJohn Forte argv[path_index]);
834fcf3ce44SJohn Forte if (path_struct->f_flag) {
835fcf3ce44SJohn Forte if ((l_state.drv_front[slot].l_state_flag
836fcf3ce44SJohn Forte != L_NO_PATH_FOUND) &&
837fcf3ce44SJohn Forte (!l_state.drv_front[slot].ib_status.dev_off))
838fcf3ce44SJohn Forte continue;
839fcf3ce44SJohn Forte } else {
840fcf3ce44SJohn Forte if ((l_state.drv_rear[slot].l_state_flag
841fcf3ce44SJohn Forte != L_NO_PATH_FOUND) &&
842fcf3ce44SJohn Forte (!l_state.drv_rear[slot].ib_status.dev_off))
843fcf3ce44SJohn Forte continue;
844fcf3ce44SJohn Forte }
845fcf3ce44SJohn Forte }
846fcf3ce44SJohn Forte
847fcf3ce44SJohn Forte /* Check if disk is reserved */
848fcf3ce44SJohn Forte if ((todo == REMOVE_DEVICE) && (!force_flag)) {
849fcf3ce44SJohn Forte if (path_struct->f_flag) {
850fcf3ce44SJohn Forte if ((l_state.drv_front[slot].g_disk_state.d_state_flags[PORT_A] &
851fcf3ce44SJohn Forte L_RESERVED) ||
852fcf3ce44SJohn Forte (l_state.drv_front[slot].g_disk_state.d_state_flags[PORT_B] &
853fcf3ce44SJohn Forte L_RESERVED)) {
854fcf3ce44SJohn Forte reserve_flag = 1;
855fcf3ce44SJohn Forte }
856fcf3ce44SJohn Forte } else {
857fcf3ce44SJohn Forte if ((l_state.drv_rear[slot].g_disk_state.d_state_flags[PORT_A] &
858fcf3ce44SJohn Forte L_RESERVED) ||
859fcf3ce44SJohn Forte (l_state.drv_rear[slot].g_disk_state.d_state_flags[PORT_B] &
860fcf3ce44SJohn Forte L_RESERVED)) {
861fcf3ce44SJohn Forte reserve_flag = 1;
862fcf3ce44SJohn Forte }
863fcf3ce44SJohn Forte }
864fcf3ce44SJohn Forte }
865fcf3ce44SJohn Forte
866fcf3ce44SJohn Forte loop:
867fcf3ce44SJohn Forte if ((disk_list = (Hotplug_Devlist *)
868fcf3ce44SJohn Forte calloc(1, sizeof (Hotplug_Devlist))) == NULL) {
869fcf3ce44SJohn Forte (void) print_errString(L_MALLOC_FAILED, NULL);
870fcf3ce44SJohn Forte goto done;
871fcf3ce44SJohn Forte }
872fcf3ce44SJohn Forte
873fcf3ce44SJohn Forte /*
874fcf3ce44SJohn Forte * dev_path is NULL when removing a whole encloser. We
875fcf3ce44SJohn Forte * don't want to call g_get_multipath while removing whole
876fcf3ce44SJohn Forte * enclosure. Its being taken care later in the code path
877fcf3ce44SJohn Forte */
878fcf3ce44SJohn Forte
879fcf3ce44SJohn Forte if ((todo != INSERT_DEVICE) && (dtype != DTYPE_ESI)) {
880fcf3ce44SJohn Forte if ((err = g_get_multipath(dev_path,
881fcf3ce44SJohn Forte &(disk_list->dlhead),
882fcf3ce44SJohn Forte wwn_list, verbose_flag)) != 0) {
883fcf3ce44SJohn Forte if (disk_list->dlhead != NULL) {
884fcf3ce44SJohn Forte (void) g_free_multipath(
885fcf3ce44SJohn Forte disk_list->dlhead);
886fcf3ce44SJohn Forte }
887fcf3ce44SJohn Forte goto done;
888fcf3ce44SJohn Forte }
889fcf3ce44SJohn Forte }
890fcf3ce44SJohn Forte disk_list->dev_type = dtype;
891fcf3ce44SJohn Forte disk_list->dev_location = dev_location;
892fcf3ce44SJohn Forte (void) strcpy(disk_list->dev_name,
893fcf3ce44SJohn Forte argv[path_index]);
894fcf3ce44SJohn Forte disk_list->tid = tid;
895fcf3ce44SJohn Forte (void) strcpy(disk_list->node_wwn_s, node_wwn_s);
896fcf3ce44SJohn Forte if (dev_location == SENA) {
897fcf3ce44SJohn Forte if ((err = l_get_allses(ses_path, box_list,
898fcf3ce44SJohn Forte &(disk_list->seslist), 0)) != 0) {
899fcf3ce44SJohn Forte if (disk_list->seslist != NULL) {
900fcf3ce44SJohn Forte (void) g_free_multipath(disk_list->seslist);
901fcf3ce44SJohn Forte }
902fcf3ce44SJohn Forte goto done;
903fcf3ce44SJohn Forte }
904fcf3ce44SJohn Forte (void) strcpy(disk_list->box_name,
905fcf3ce44SJohn Forte (char *)l_state.ib_tbl.enclosure_name);
906fcf3ce44SJohn Forte disk_list->slot = slot;
907fcf3ce44SJohn Forte disk_list->f_flag = path_struct->f_flag;
908fcf3ce44SJohn Forte }
909fcf3ce44SJohn Forte if (todo == REMOVE_DEVICE && !force_flag && !reserve_flag) {
910fcf3ce44SJohn Forte if ((err = h_chk_dev_busy(disk_list, wwn_list,
911fcf3ce44SJohn Forte &busy_flag, force_flag, verbose_flag)) != 0) {
912fcf3ce44SJohn Forte goto done;
913fcf3ce44SJohn Forte }
914fcf3ce44SJohn Forte }
915fcf3ce44SJohn Forte
916fcf3ce44SJohn Forte if (reserve_flag || busy_flag) {
917fcf3ce44SJohn Forte if (reserve_flag)
918fcf3ce44SJohn Forte disk_list->reserve_flag = 1;
919fcf3ce44SJohn Forte if (busy_flag)
920fcf3ce44SJohn Forte disk_list->busy_flag = 1;
921fcf3ce44SJohn Forte
922fcf3ce44SJohn Forte if (bsyRsrv_dskLst_head == NULL) {
923fcf3ce44SJohn Forte bsyRsrv_dskLst_head =
924fcf3ce44SJohn Forte bsyRsrv_dskLst_tail = disk_list;
925fcf3ce44SJohn Forte } else {
926fcf3ce44SJohn Forte disk_list->prev = bsyRsrv_dskLst_tail;
927fcf3ce44SJohn Forte bsyRsrv_dskLst_tail->next = disk_list;
928fcf3ce44SJohn Forte bsyRsrv_dskLst_tail = disk_list;
929fcf3ce44SJohn Forte }
930fcf3ce44SJohn Forte reserve_flag = 0;
931fcf3ce44SJohn Forte busy_flag = 0;
932fcf3ce44SJohn Forte
933fcf3ce44SJohn Forte } else if (disk_list_head == NULL) {
934fcf3ce44SJohn Forte disk_list_head = disk_list_tail = disk_list;
935fcf3ce44SJohn Forte } else {
936fcf3ce44SJohn Forte disk_list->prev = disk_list_tail;
937fcf3ce44SJohn Forte disk_list_tail->next = disk_list;
938fcf3ce44SJohn Forte disk_list_tail = disk_list;
939fcf3ce44SJohn Forte }
940fcf3ce44SJohn Forte }
941fcf3ce44SJohn Forte
942fcf3ce44SJohn Forte if (bsyRsrv_dskLst_head != NULL) {
943fcf3ce44SJohn Forte if ((err = h_print_list(bsyRsrv_dskLst_head,
944fcf3ce44SJohn Forte &action, enc_type)) != 0) {
945fcf3ce44SJohn Forte goto done;
946fcf3ce44SJohn Forte }
947fcf3ce44SJohn Forte if (action == SKIP) {
948fcf3ce44SJohn Forte (void) h_free_hotplug_dlist(&bsyRsrv_dskLst_head);
949fcf3ce44SJohn Forte } else if (action == QUIT) {
950fcf3ce44SJohn Forte goto done;
951fcf3ce44SJohn Forte }
952fcf3ce44SJohn Forte }
953fcf3ce44SJohn Forte if (disk_list_head != NULL) {
954fcf3ce44SJohn Forte if ((h_print_list_warn(disk_list_head, todo, enc_type)) != 0) {
955fcf3ce44SJohn Forte goto done;
956fcf3ce44SJohn Forte }
957fcf3ce44SJohn Forte if ((err = h_pre_hotplug(&disk_list_head, wwn_list, todo, verbose_flag,
958fcf3ce44SJohn Forte force_flag)) != 0) {
959fcf3ce44SJohn Forte goto done;
960fcf3ce44SJohn Forte }
961fcf3ce44SJohn Forte if (disk_list_head != NULL) {
962fcf3ce44SJohn Forte if (todo == REMOVE_DEVICE) {
963fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5514,
964fcf3ce44SJohn Forte "\nHit <Return> after "
965fcf3ce44SJohn Forte "removing the device(s)."));
966fcf3ce44SJohn Forte } else {
967fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5515,
968fcf3ce44SJohn Forte "\nHit <Return> after "
969fcf3ce44SJohn Forte "inserting the device(s)."));
970fcf3ce44SJohn Forte }
971fcf3ce44SJohn Forte (void) getchar();
972fcf3ce44SJohn Forte (void) fprintf(stdout, "\n");
973fcf3ce44SJohn Forte if ((err = h_post_hotplug(disk_list_head, wwn_list,
974fcf3ce44SJohn Forte todo, verbose_flag, force_flag,
975fcf3ce44SJohn Forte enc_type)) != 0) {
976fcf3ce44SJohn Forte goto done;
977fcf3ce44SJohn Forte }
978fcf3ce44SJohn Forte }
979fcf3ce44SJohn Forte }
980fcf3ce44SJohn Forte done:
981fcf3ce44SJohn Forte (void) l_free_box_list(&box_list);
982fcf3ce44SJohn Forte (void) g_free_wwn_list(&wwn_list);
983fcf3ce44SJohn Forte if (err && err != -1) {
984fcf3ce44SJohn Forte return (err);
985fcf3ce44SJohn Forte }
986fcf3ce44SJohn Forte free((void *)map.dev_addr);
987fcf3ce44SJohn Forte return (0);
988fcf3ce44SJohn Forte }
989fcf3ce44SJohn Forte
990fcf3ce44SJohn Forte
991fcf3ce44SJohn Forte
992fcf3ce44SJohn Forte
993fcf3ce44SJohn Forte /*
994fcf3ce44SJohn Forte * Internal routine to clean up ../'s in paths.
995fcf3ce44SJohn Forte * returns 0 if no "../" are left.
996fcf3ce44SJohn Forte *
997fcf3ce44SJohn Forte * Wouldn't it be nice if there was a standard system library
998fcf3ce44SJohn Forte * routine to do this...?
999fcf3ce44SJohn Forte */
1000fcf3ce44SJohn Forte static int
cleanup_dotdot_path(char * path)1001fcf3ce44SJohn Forte cleanup_dotdot_path(char *path)
1002fcf3ce44SJohn Forte {
1003fcf3ce44SJohn Forte char holder[MAXPATHLEN];
1004fcf3ce44SJohn Forte char *dotdot;
1005fcf3ce44SJohn Forte char *previous_slash;
1006fcf3ce44SJohn Forte
1007fcf3ce44SJohn Forte /* Find the first "/../" in the string */
1008fcf3ce44SJohn Forte dotdot = strstr(path, "/../");
1009fcf3ce44SJohn Forte if (dotdot == NULL) {
1010fcf3ce44SJohn Forte return (0);
1011fcf3ce44SJohn Forte }
1012fcf3ce44SJohn Forte
1013fcf3ce44SJohn Forte
1014fcf3ce44SJohn Forte /*
1015fcf3ce44SJohn Forte * If the [0] character is '/' and "../" immediatly
1016fcf3ce44SJohn Forte * follows it, then we can strip the ../
1017fcf3ce44SJohn Forte *
1018fcf3ce44SJohn Forte * /../../foo/bar == /foo/bar
1019fcf3ce44SJohn Forte *
1020fcf3ce44SJohn Forte */
1021fcf3ce44SJohn Forte if (dotdot == path) {
1022fcf3ce44SJohn Forte strcpy(holder, &path[3]); /* strip "/.." */
1023fcf3ce44SJohn Forte strcpy(path, holder);
1024fcf3ce44SJohn Forte return (1);
1025fcf3ce44SJohn Forte }
1026fcf3ce44SJohn Forte
1027fcf3ce44SJohn Forte /*
1028fcf3ce44SJohn Forte * Now look for the LAST "/" before the "/../"
1029fcf3ce44SJohn Forte * as this is the parent dir we can get rid of.
1030fcf3ce44SJohn Forte * We do this by temporarily truncating the string
1031fcf3ce44SJohn Forte * at the '/' just before "../" using the dotdot pointer.
1032fcf3ce44SJohn Forte */
1033fcf3ce44SJohn Forte *dotdot = '\0';
1034fcf3ce44SJohn Forte previous_slash = strrchr(path, '/');
1035fcf3ce44SJohn Forte if (previous_slash == NULL) {
1036fcf3ce44SJohn Forte /*
1037fcf3ce44SJohn Forte * hmm, somethings wrong. path looks something
1038fcf3ce44SJohn Forte * like "foo/../bar/" so we can't really deal with it.
1039fcf3ce44SJohn Forte */
1040fcf3ce44SJohn Forte return (0);
1041fcf3ce44SJohn Forte }
1042fcf3ce44SJohn Forte /*
1043fcf3ce44SJohn Forte * Now truncate the path just after the previous '/'
1044fcf3ce44SJohn Forte * and slam everything after the "../" back on
1045fcf3ce44SJohn Forte */
1046fcf3ce44SJohn Forte *(previous_slash+1) = '\0';
1047fcf3ce44SJohn Forte (void) strcat(path, dotdot+4);
1048fcf3ce44SJohn Forte return (1); /* We may have more "../"s */
1049fcf3ce44SJohn Forte }
1050fcf3ce44SJohn Forte
1051fcf3ce44SJohn Forte
1052fcf3ce44SJohn Forte /*
1053fcf3ce44SJohn Forte * Follow symbolic links from the logical device name to
1054fcf3ce44SJohn Forte * the /devfs physical device name. To be complete, we
1055fcf3ce44SJohn Forte * handle the case of multiple links. This function
1056fcf3ce44SJohn Forte * either returns NULL (no links, or some other error),
1057fcf3ce44SJohn Forte * or the physical device name, alloc'ed on the heap.
1058fcf3ce44SJohn Forte *
1059fcf3ce44SJohn Forte * For S10 the physical path may be non-existent.
1060fcf3ce44SJohn Forte *
1061fcf3ce44SJohn Forte * NOTE: If the path is relative, it will be forced into
1062fcf3ce44SJohn Forte * an absolute path by pre-pending the pwd to it.
1063fcf3ce44SJohn Forte */
1064fcf3ce44SJohn Forte char *
h_get_physical_name_from_link(char * path)1065fcf3ce44SJohn Forte h_get_physical_name_from_link(char *path)
1066fcf3ce44SJohn Forte {
1067fcf3ce44SJohn Forte struct stat stbuf;
1068fcf3ce44SJohn Forte char source[MAXPATHLEN];
1069fcf3ce44SJohn Forte char scratch[MAXPATHLEN];
1070fcf3ce44SJohn Forte char pwd[MAXPATHLEN];
1071fcf3ce44SJohn Forte char *tmp;
1072fcf3ce44SJohn Forte int cnt;
1073fcf3ce44SJohn Forte
1074fcf3ce44SJohn Forte /* return NULL if path is NULL */
1075fcf3ce44SJohn Forte if (path == NULL) {
1076fcf3ce44SJohn Forte return (NULL);
1077fcf3ce44SJohn Forte }
1078fcf3ce44SJohn Forte
1079fcf3ce44SJohn Forte strcpy(source, path);
1080fcf3ce44SJohn Forte for (;;) {
1081fcf3ce44SJohn Forte
1082fcf3ce44SJohn Forte /*
1083fcf3ce44SJohn Forte * First make sure the path is absolute. If not, make it.
1084fcf3ce44SJohn Forte * If it's already an absolute path, we have no need
1085fcf3ce44SJohn Forte * to determine the cwd, so the program should still
1086fcf3ce44SJohn Forte * function within security-by-obscurity directories.
1087fcf3ce44SJohn Forte */
1088fcf3ce44SJohn Forte if (source[0] != '/') {
1089fcf3ce44SJohn Forte tmp = getcwd(pwd, MAXPATHLEN);
1090fcf3ce44SJohn Forte if (tmp == NULL) {
1091fcf3ce44SJohn Forte O_DPRINTF("getcwd() failed - %s\n",
1092fcf3ce44SJohn Forte strerror(errno));
1093fcf3ce44SJohn Forte return (NULL);
1094fcf3ce44SJohn Forte }
1095fcf3ce44SJohn Forte /*
1096fcf3ce44SJohn Forte * Handle special case of "./foo/bar"
1097fcf3ce44SJohn Forte */
1098fcf3ce44SJohn Forte if (source[0] == '.' && source[1] == '/') {
1099fcf3ce44SJohn Forte strcpy(scratch, source+2);
1100fcf3ce44SJohn Forte } else { /* no "./" so just take everything */
1101fcf3ce44SJohn Forte strcpy(scratch, source);
1102fcf3ce44SJohn Forte }
1103fcf3ce44SJohn Forte strcpy(source, pwd);
1104fcf3ce44SJohn Forte (void) strcat(source, "/");
1105fcf3ce44SJohn Forte (void) strcat(source, scratch);
1106fcf3ce44SJohn Forte }
1107fcf3ce44SJohn Forte
1108fcf3ce44SJohn Forte /*
1109fcf3ce44SJohn Forte * Clean up any "../"s that are in the path
1110fcf3ce44SJohn Forte */
1111fcf3ce44SJohn Forte while (cleanup_dotdot_path(source));
1112fcf3ce44SJohn Forte
1113fcf3ce44SJohn Forte /*
1114fcf3ce44SJohn Forte * source is now an absolute path to the link we're
1115fcf3ce44SJohn Forte * concerned with
1116fcf3ce44SJohn Forte *
1117fcf3ce44SJohn Forte * S10: Do NOT ignore dangling links, pointing to devfs nodes.
1118fcf3ce44SJohn Forte */
1119fcf3ce44SJohn Forte if (strstr(source, "/devices")) {
1120fcf3ce44SJohn Forte return (g_alloc_string(source));
1121fcf3ce44SJohn Forte }
1122fcf3ce44SJohn Forte
1123fcf3ce44SJohn Forte if (lstat(source, &stbuf) == -1) {
1124fcf3ce44SJohn Forte O_DPRINTF("lstat() failed for - %s\n",
1125fcf3ce44SJohn Forte source, strerror(errno));
1126fcf3ce44SJohn Forte return (NULL);
1127fcf3ce44SJohn Forte }
1128fcf3ce44SJohn Forte /*
1129fcf3ce44SJohn Forte * If the file is not a link, we're done one
1130fcf3ce44SJohn Forte * way or the other. If there were links,
1131fcf3ce44SJohn Forte * return the full pathname of the resulting
1132fcf3ce44SJohn Forte * file.
1133fcf3ce44SJohn Forte *
1134fcf3ce44SJohn Forte * Note: All of our temp's are on the stack,
1135fcf3ce44SJohn Forte * so we have to copy the final result to the heap.
1136fcf3ce44SJohn Forte */
1137fcf3ce44SJohn Forte if (!S_ISLNK(stbuf.st_mode)) {
1138fcf3ce44SJohn Forte return (g_alloc_string(source));
1139fcf3ce44SJohn Forte }
1140fcf3ce44SJohn Forte cnt = readlink(source, scratch, sizeof (scratch));
1141fcf3ce44SJohn Forte if (cnt < 0) {
1142fcf3ce44SJohn Forte O_DPRINTF("readlink() failed - %s\n",
1143fcf3ce44SJohn Forte strerror(errno));
1144fcf3ce44SJohn Forte return (NULL);
1145fcf3ce44SJohn Forte }
1146fcf3ce44SJohn Forte /*
1147fcf3ce44SJohn Forte * scratch is on the heap, and for some reason readlink
1148fcf3ce44SJohn Forte * doesn't always terminate things properly so we have
1149fcf3ce44SJohn Forte * to make certain we're properly terminated
1150fcf3ce44SJohn Forte */
1151fcf3ce44SJohn Forte scratch[cnt] = '\0';
1152fcf3ce44SJohn Forte
1153fcf3ce44SJohn Forte /*
1154fcf3ce44SJohn Forte * Now check to see if the link is relative. If so,
1155fcf3ce44SJohn Forte * then we have to append it to the directory
1156fcf3ce44SJohn Forte * which the source was in. (This is non trivial)
1157fcf3ce44SJohn Forte */
1158fcf3ce44SJohn Forte if (scratch[0] != '/') {
1159fcf3ce44SJohn Forte tmp = strrchr(source, '/');
1160fcf3ce44SJohn Forte if (tmp == NULL) { /* Whoa! Something's hosed! */
1161fcf3ce44SJohn Forte O_DPRINTF("Internal error... corrupt path.\n");
1162fcf3ce44SJohn Forte return (NULL);
1163fcf3ce44SJohn Forte }
1164fcf3ce44SJohn Forte /* Now strip off just the directory path */
1165fcf3ce44SJohn Forte *(tmp+1) = '\0'; /* Keeping the last '/' */
1166fcf3ce44SJohn Forte /* and append the new link */
1167fcf3ce44SJohn Forte (void) strcat(source, scratch);
1168fcf3ce44SJohn Forte /*
1169fcf3ce44SJohn Forte * Note: At this point, source should have "../"s
1170fcf3ce44SJohn Forte * but we'll clean it up in the next pass through
1171fcf3ce44SJohn Forte * the loop.
1172fcf3ce44SJohn Forte */
1173fcf3ce44SJohn Forte } else {
1174fcf3ce44SJohn Forte /* It's an absolute link so no worries */
1175fcf3ce44SJohn Forte strcpy(source, scratch);
1176fcf3ce44SJohn Forte }
1177fcf3ce44SJohn Forte }
1178fcf3ce44SJohn Forte /* Never reach here */
1179fcf3ce44SJohn Forte }
1180fcf3ce44SJohn Forte
1181fcf3ce44SJohn Forte /*
1182fcf3ce44SJohn Forte * Function for getting physical pathnames
1183fcf3ce44SJohn Forte *
1184fcf3ce44SJohn Forte * For S10 the physical path may not exist at the time devctl calls
1185fcf3ce44SJohn Forte * are made. So we should not return error if stat fails on /devices path.
1186fcf3ce44SJohn Forte *
1187fcf3ce44SJohn Forte * This function can handle 2 different inputs.
1188fcf3ce44SJohn Forte *
1189fcf3ce44SJohn Forte * 1) Inputs of the form /dev/rdsk/cNtNdNsN
1190fcf3ce44SJohn Forte * These are identified by being a link
1191fcf3ce44SJohn Forte * The physical path they are linked to is returned.
1192fcf3ce44SJohn Forte *
1193fcf3ce44SJohn Forte * 2) Inputs of the form /devices/...
1194fcf3ce44SJohn Forte * These are actual physical names.
1195fcf3ce44SJohn Forte * They are not converted.
1196fcf3ce44SJohn Forte */
1197fcf3ce44SJohn Forte char *
h_get_physical_name(char * path)1198fcf3ce44SJohn Forte h_get_physical_name(char *path)
1199fcf3ce44SJohn Forte {
1200fcf3ce44SJohn Forte struct stat stbuf;
1201fcf3ce44SJohn Forte char s[MAXPATHLEN];
1202fcf3ce44SJohn Forte char savedir[MAXPATHLEN];
1203fcf3ce44SJohn Forte char *result = NULL;
1204fcf3ce44SJohn Forte int status = 0;
1205fcf3ce44SJohn Forte
1206fcf3ce44SJohn Forte /* return invalid path if path NULL */
1207fcf3ce44SJohn Forte if (path == NULL) {
1208fcf3ce44SJohn Forte return (NULL);
1209fcf3ce44SJohn Forte }
1210fcf3ce44SJohn Forte
1211fcf3ce44SJohn Forte (void) strcpy(s, path);
1212fcf3ce44SJohn Forte
1213fcf3ce44SJohn Forte status = lstat(s, &stbuf);
1214fcf3ce44SJohn Forte
1215fcf3ce44SJohn Forte /*
1216fcf3ce44SJohn Forte * S10: If string is devfs node we allow failed lstat.
1217fcf3ce44SJohn Forte */
1218fcf3ce44SJohn Forte if ((status == -1) || !S_ISLNK(stbuf.st_mode)) {
1219fcf3ce44SJohn Forte /* Make sure a full path as that is required. */
1220fcf3ce44SJohn Forte if (strstr(s, "/devices")) {
1221fcf3ce44SJohn Forte result = g_alloc_string(s);
1222fcf3ce44SJohn Forte } else {
1223fcf3ce44SJohn Forte if (getcwd(savedir,
1224fcf3ce44SJohn Forte sizeof (savedir)) == NULL) {
1225fcf3ce44SJohn Forte return (NULL);
1226fcf3ce44SJohn Forte }
1227fcf3ce44SJohn Forte /*
1228fcf3ce44SJohn Forte * Check for this format:
1229fcf3ce44SJohn Forte * ./ssd@0,1:g,raw
1230fcf3ce44SJohn Forte */
1231fcf3ce44SJohn Forte if (s[0] == '.') {
1232fcf3ce44SJohn Forte (void) strcat(savedir, &s[1]);
1233fcf3ce44SJohn Forte } else {
1234fcf3ce44SJohn Forte (void) strcat(savedir, "/");
1235fcf3ce44SJohn Forte (void) strcat(savedir, s);
1236fcf3ce44SJohn Forte }
1237fcf3ce44SJohn Forte if ((status != -1) || strstr(s, "/devices")) {
1238fcf3ce44SJohn Forte result = g_alloc_string(savedir);
1239fcf3ce44SJohn Forte }
1240fcf3ce44SJohn Forte }
1241fcf3ce44SJohn Forte } else {
1242fcf3ce44SJohn Forte /*
1243fcf3ce44SJohn Forte * Entry is linked file
1244fcf3ce44SJohn Forte * so follow link to physical name
1245fcf3ce44SJohn Forte */
1246fcf3ce44SJohn Forte result = h_get_physical_name_from_link(path);
1247fcf3ce44SJohn Forte }
1248fcf3ce44SJohn Forte
1249fcf3ce44SJohn Forte exit:
1250fcf3ce44SJohn Forte return (result);
1251fcf3ce44SJohn Forte }
1252fcf3ce44SJohn Forte
1253fcf3ce44SJohn Forte
1254fcf3ce44SJohn Forte /*
1255fcf3ce44SJohn Forte * handle expert-mode hotplug commands
1256fcf3ce44SJohn Forte *
1257fcf3ce44SJohn Forte * return 0 iff all is okay
1258fcf3ce44SJohn Forte */
1259fcf3ce44SJohn Forte int
hotplug_e(int todo,char ** argv,int verbose_flag,int force_flag)1260fcf3ce44SJohn Forte hotplug_e(int todo, char **argv, int verbose_flag, int force_flag)
1261fcf3ce44SJohn Forte {
1262fcf3ce44SJohn Forte char *path_phys = NULL;
1263fcf3ce44SJohn Forte char bus_path[MAXPATHLEN];
1264fcf3ce44SJohn Forte char *ptr;
1265*e9175934SKlaus Ziegler int exit_code = 1;
1266fcf3ce44SJohn Forte devctl_hdl_t dcp;
1267fcf3ce44SJohn Forte uint_t devstate;
1268fcf3ce44SJohn Forte int i = 0, pathcnt = 1;
1269fcf3ce44SJohn Forte mp_pathlist_t pathlist;
1270fcf3ce44SJohn Forte int p_pw = 0, p_on = 0, p_st = 0;
1271fcf3ce44SJohn Forte
1272fcf3ce44SJohn Forte
1273fcf3ce44SJohn Forte switch (todo) {
1274fcf3ce44SJohn Forte case DEV_ONLINE:
1275fcf3ce44SJohn Forte case DEV_OFFLINE:
1276fcf3ce44SJohn Forte case DEV_GETSTATE:
1277fcf3ce44SJohn Forte case DEV_RESET:
1278fcf3ce44SJohn Forte /* get physical name */
1279fcf3ce44SJohn Forte if ((path_phys = h_get_physical_name(argv[0])) == NULL) {
1280fcf3ce44SJohn Forte
1281fcf3ce44SJohn Forte (void) fprintf(stderr,
1282fcf3ce44SJohn Forte MSGSTR(112, "Error: Invalid pathname (%s)"),
1283fcf3ce44SJohn Forte argv[0]);
1284fcf3ce44SJohn Forte (void) fprintf(stderr, "\n");
1285fcf3ce44SJohn Forte return (1);
1286fcf3ce44SJohn Forte }
1287fcf3ce44SJohn Forte
1288fcf3ce44SJohn Forte if (verbose_flag) {
1289fcf3ce44SJohn Forte (void) fprintf(stdout,
1290fcf3ce44SJohn Forte MSGSTR(5516,
1291fcf3ce44SJohn Forte "phys path = \"%s\"\n"),
1292fcf3ce44SJohn Forte path_phys);
1293fcf3ce44SJohn Forte }
1294fcf3ce44SJohn Forte
1295fcf3ce44SJohn Forte /* acquire rights to hack on device */
1296fcf3ce44SJohn Forte if ((dcp = devctl_device_acquire(path_phys,
1297fcf3ce44SJohn Forte force_flag ? 0 : DC_EXCL)) == NULL) {
1298fcf3ce44SJohn Forte
1299fcf3ce44SJohn Forte (void) fprintf(stderr, MSGSTR(5517,
1300fcf3ce44SJohn Forte "Error: can't acquire \"%s\": %s\n"),
1301fcf3ce44SJohn Forte path_phys, strerror(errno));
1302fcf3ce44SJohn Forte return (1);
1303fcf3ce44SJohn Forte }
1304fcf3ce44SJohn Forte
1305fcf3ce44SJohn Forte switch (todo) {
1306fcf3ce44SJohn Forte case DEV_ONLINE:
1307fcf3ce44SJohn Forte exit_code = devctl_device_online(dcp);
1308fcf3ce44SJohn Forte break;
1309fcf3ce44SJohn Forte case DEV_OFFLINE:
1310fcf3ce44SJohn Forte exit_code = devctl_device_offline(dcp);
1311fcf3ce44SJohn Forte break;
1312fcf3ce44SJohn Forte case DEV_GETSTATE:
1313fcf3ce44SJohn Forte if ((exit_code = devctl_device_getstate(dcp,
1314fcf3ce44SJohn Forte &devstate)) == 0) {
1315fcf3ce44SJohn Forte print_dev_state(argv[0], devstate);
1316fcf3ce44SJohn Forte }
1317fcf3ce44SJohn Forte break;
1318fcf3ce44SJohn Forte case DEV_RESET:
1319fcf3ce44SJohn Forte exit_code = devctl_device_reset(dcp);
1320fcf3ce44SJohn Forte break;
1321fcf3ce44SJohn Forte }
1322fcf3ce44SJohn Forte
1323fcf3ce44SJohn Forte if (exit_code != 0) {
1324fcf3ce44SJohn Forte perror(MSGSTR(5518, "devctl"));
1325fcf3ce44SJohn Forte }
1326fcf3ce44SJohn Forte
1327fcf3ce44SJohn Forte /* all done now -- release device */
1328fcf3ce44SJohn Forte devctl_release(dcp);
1329fcf3ce44SJohn Forte break;
1330fcf3ce44SJohn Forte
1331fcf3ce44SJohn Forte /* for hotplugging bus operations */
1332fcf3ce44SJohn Forte case BUS_QUIESCE:
1333fcf3ce44SJohn Forte case BUS_UNQUIESCE:
1334fcf3ce44SJohn Forte case BUS_GETSTATE:
1335fcf3ce44SJohn Forte case BUS_RESET:
1336fcf3ce44SJohn Forte case BUS_RESETALL:
1337fcf3ce44SJohn Forte /* get physical name */
1338fcf3ce44SJohn Forte if ((path_phys = h_get_physical_name(argv[0])) ==
1339fcf3ce44SJohn Forte NULL) {
1340fcf3ce44SJohn Forte (void) fprintf(stderr,
1341fcf3ce44SJohn Forte MSGSTR(112, "Error: Invalid pathname (%s)"),
1342fcf3ce44SJohn Forte argv[0]);
1343fcf3ce44SJohn Forte (void) fprintf(stderr, "\n");
1344fcf3ce44SJohn Forte return (1);
1345fcf3ce44SJohn Forte }
1346fcf3ce44SJohn Forte if (verbose_flag) {
1347fcf3ce44SJohn Forte printf(MSGSTR(5519, "phys path = \"%s\"\n"), path_phys);
1348fcf3ce44SJohn Forte }
1349fcf3ce44SJohn Forte
1350fcf3ce44SJohn Forte /* acquire rights to hack on device */
1351fcf3ce44SJohn Forte /* delete leaf part from path_phys. */
1352fcf3ce44SJohn Forte if (strstr(path_phys, SCSI_VHCI) != NULL) {
1353fcf3ce44SJohn Forte /* obtain phci */
1354fcf3ce44SJohn Forte (void) strcpy(bus_path, path_phys);
1355fcf3ce44SJohn Forte if (g_get_pathlist(bus_path, &pathlist)) {
1356fcf3ce44SJohn Forte (void) fprintf(stderr,
1357fcf3ce44SJohn Forte MSGSTR(112, "Error: Invalid pathname (%s)"),
1358fcf3ce44SJohn Forte path_phys);
1359fcf3ce44SJohn Forte (void) fprintf(stderr, "\n");
1360fcf3ce44SJohn Forte return (1);
1361fcf3ce44SJohn Forte }
1362fcf3ce44SJohn Forte pathcnt = pathlist.path_count;
1363fcf3ce44SJohn Forte p_pw = p_on = p_st = 0;
1364fcf3ce44SJohn Forte for (i = 0; i < pathcnt; i++) {
1365fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state <
1366fcf3ce44SJohn Forte MAXPATHSTATE) {
1367fcf3ce44SJohn Forte if (strstr(pathlist.path_info[i].
1368fcf3ce44SJohn Forte path_addr,
1369fcf3ce44SJohn Forte argv[0]) != NULL) {
1370fcf3ce44SJohn Forte p_pw = i;
1371fcf3ce44SJohn Forte break;
1372fcf3ce44SJohn Forte }
1373fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state ==
1374fcf3ce44SJohn Forte MDI_PATHINFO_STATE_ONLINE) {
1375fcf3ce44SJohn Forte p_on = i;
1376fcf3ce44SJohn Forte }
1377fcf3ce44SJohn Forte if (pathlist.path_info[i].path_state ==
1378fcf3ce44SJohn Forte MDI_PATHINFO_STATE_STANDBY) {
1379fcf3ce44SJohn Forte p_st = i;
1380fcf3ce44SJohn Forte }
1381fcf3ce44SJohn Forte }
1382fcf3ce44SJohn Forte }
1383fcf3ce44SJohn Forte if (strstr(pathlist.path_info[p_pw].path_addr,
1384fcf3ce44SJohn Forte argv[0]) != NULL) {
1385fcf3ce44SJohn Forte /* matching input pwwn */
1386fcf3ce44SJohn Forte (void) strcpy(bus_path,
1387fcf3ce44SJohn Forte pathlist.path_info[p_pw].path_hba);
1388fcf3ce44SJohn Forte } else if (pathlist.path_info[p_on].path_state ==
1389fcf3ce44SJohn Forte MDI_PATHINFO_STATE_ONLINE) {
1390fcf3ce44SJohn Forte /* on_line path */
1391fcf3ce44SJohn Forte (void) strcpy(bus_path,
1392fcf3ce44SJohn Forte pathlist.path_info[p_on].path_hba);
1393fcf3ce44SJohn Forte } else {
1394fcf3ce44SJohn Forte /* standby or path0 */
1395fcf3ce44SJohn Forte (void) strcpy(bus_path,
1396fcf3ce44SJohn Forte pathlist.path_info[p_st].path_hba);
1397fcf3ce44SJohn Forte }
1398fcf3ce44SJohn Forte free(pathlist.path_info);
1399fcf3ce44SJohn Forte } else {
1400fcf3ce44SJohn Forte
1401fcf3ce44SJohn Forte (void) strcpy(bus_path, path_phys);
1402fcf3ce44SJohn Forte ptr = strrchr(bus_path, '/');
1403fcf3ce44SJohn Forte if (ptr) {
1404fcf3ce44SJohn Forte *ptr = '\0';
1405fcf3ce44SJohn Forte } else {
1406fcf3ce44SJohn Forte (void) fprintf(stderr,
1407fcf3ce44SJohn Forte MSGSTR(112, "Error: Invalid pathname (%s)"),
1408fcf3ce44SJohn Forte path_phys);
1409fcf3ce44SJohn Forte (void) fprintf(stderr, "\n");
1410fcf3ce44SJohn Forte return (1);
1411fcf3ce44SJohn Forte }
1412fcf3ce44SJohn Forte }
1413fcf3ce44SJohn Forte
1414fcf3ce44SJohn Forte if ((dcp = devctl_bus_acquire(bus_path,
1415fcf3ce44SJohn Forte force_flag ? 0 : DC_EXCL)) == NULL) {
1416fcf3ce44SJohn Forte (void) fprintf(stderr,
1417fcf3ce44SJohn Forte MSGSTR(5521,
1418fcf3ce44SJohn Forte " Error: can't acquire bus node from"
1419fcf3ce44SJohn Forte " the path \"%s\": %s\n"),
1420fcf3ce44SJohn Forte bus_path, strerror(errno));
1421fcf3ce44SJohn Forte return (1);
1422fcf3ce44SJohn Forte }
1423fcf3ce44SJohn Forte
1424fcf3ce44SJohn Forte switch (todo) {
1425fcf3ce44SJohn Forte case BUS_QUIESCE:
1426fcf3ce44SJohn Forte exit_code = devctl_bus_quiesce(dcp);
1427fcf3ce44SJohn Forte break;
1428fcf3ce44SJohn Forte case BUS_UNQUIESCE:
1429fcf3ce44SJohn Forte exit_code = devctl_bus_unquiesce(dcp);
1430fcf3ce44SJohn Forte break;
1431fcf3ce44SJohn Forte case BUS_GETSTATE:
1432fcf3ce44SJohn Forte if ((exit_code = devctl_bus_getstate(dcp,
1433fcf3ce44SJohn Forte &devstate)) == 0) {
1434fcf3ce44SJohn Forte print_bus_state(argv[0], devstate);
1435fcf3ce44SJohn Forte }
1436fcf3ce44SJohn Forte break;
1437fcf3ce44SJohn Forte case BUS_RESET:
1438fcf3ce44SJohn Forte exit_code = devctl_bus_reset(dcp);
1439fcf3ce44SJohn Forte break;
1440fcf3ce44SJohn Forte case BUS_RESETALL:
1441fcf3ce44SJohn Forte exit_code = devctl_bus_resetall(dcp);
1442fcf3ce44SJohn Forte break;
1443fcf3ce44SJohn Forte }
1444fcf3ce44SJohn Forte
1445fcf3ce44SJohn Forte if (exit_code != 0) {
1446fcf3ce44SJohn Forte perror(MSGSTR(5522, "devctl"));
1447fcf3ce44SJohn Forte }
1448fcf3ce44SJohn Forte
1449fcf3ce44SJohn Forte /* all done now -- release device */
1450fcf3ce44SJohn Forte devctl_release(dcp);
1451fcf3ce44SJohn Forte break;
1452fcf3ce44SJohn Forte }
1453fcf3ce44SJohn Forte
1454fcf3ce44SJohn Forte return (exit_code);
1455fcf3ce44SJohn Forte }
1456fcf3ce44SJohn Forte
1457fcf3ce44SJohn Forte
1458fcf3ce44SJohn Forte
1459fcf3ce44SJohn Forte /*
1460fcf3ce44SJohn Forte * Prepares an individual FC_AL device
1461fcf3ce44SJohn Forte * to be removed from the specified
1462fcf3ce44SJohn Forte * slot.
1463fcf3ce44SJohn Forte *
1464fcf3ce44SJohn Forte * RETURNS:
1465fcf3ce44SJohn Forte * 0 if OK
1466fcf3ce44SJohn Forte * non-zero otherwise.
1467fcf3ce44SJohn Forte */
1468fcf3ce44SJohn Forte static int
h_pre_remove_dev(Hotplug_Devlist * hotplug_disk,WWN_list * wwn_list,int verbose_flag,int force_flag)1469fcf3ce44SJohn Forte h_pre_remove_dev(Hotplug_Devlist *hotplug_disk, WWN_list *wwn_list,
1470fcf3ce44SJohn Forte int verbose_flag, int force_flag)
1471fcf3ce44SJohn Forte {
1472fcf3ce44SJohn Forte char *dev_path, device_name[MAXNAMELEN];
1473fcf3ce44SJohn Forte int err;
1474fcf3ce44SJohn Forte
1475fcf3ce44SJohn Forte /* Initialize pointers */
1476fcf3ce44SJohn Forte dev_path = NULL;
1477fcf3ce44SJohn Forte
1478fcf3ce44SJohn Forte if (hotplug_disk->dlhead != NULL) {
1479fcf3ce44SJohn Forte dev_path = hotplug_disk->dlhead->dev_path;
1480fcf3ce44SJohn Forte (void) strcpy(device_name, (hotplug_disk->dlhead)->logical_path);
1481fcf3ce44SJohn Forte }
1482fcf3ce44SJohn Forte (void) fprintf(stdout,
1483fcf3ce44SJohn Forte MSGSTR(157,
1484fcf3ce44SJohn Forte "stopping: %s...."), device_name);
1485fcf3ce44SJohn Forte if (!(strstr(dev_path, SLSH_DRV_NAME_ST))) {
1486fcf3ce44SJohn Forte if ((err = g_dev_stop(dev_path, wwn_list, verbose_flag)) != 0)
1487fcf3ce44SJohn Forte return (err);
1488fcf3ce44SJohn Forte }
1489fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(156, "Done\n"));
1490fcf3ce44SJohn Forte
1491fcf3ce44SJohn Forte (void) fprintf(stdout,
1492fcf3ce44SJohn Forte MSGSTR(158, "offlining: %s...."), device_name);
1493fcf3ce44SJohn Forte if ((err = g_offline_drive(hotplug_disk->dlhead,
1494fcf3ce44SJohn Forte force_flag)) != 0) {
1495fcf3ce44SJohn Forte (void) fprintf(stdout,
1496fcf3ce44SJohn Forte MSGSTR(160,
1497fcf3ce44SJohn Forte "\nonlining: %s\n"), device_name);
1498fcf3ce44SJohn Forte
1499fcf3ce44SJohn Forte (void) g_online_drive(hotplug_disk->dlhead, force_flag);
1500fcf3ce44SJohn Forte (void) fprintf(stdout,
1501fcf3ce44SJohn Forte MSGSTR(159, "starting: %s...."),
1502fcf3ce44SJohn Forte device_name);
1503fcf3ce44SJohn Forte if ((err = g_dev_start(dev_path, 0)) != 0) {
1504fcf3ce44SJohn Forte return (err);
1505fcf3ce44SJohn Forte }
1506fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(156, "Done\n"));
1507fcf3ce44SJohn Forte return (err);
1508fcf3ce44SJohn Forte }
1509fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(156, "Done\n"));
1510fcf3ce44SJohn Forte return (0);
1511fcf3ce44SJohn Forte }
1512fcf3ce44SJohn Forte
1513fcf3ce44SJohn Forte
1514fcf3ce44SJohn Forte
1515fcf3ce44SJohn Forte /*
1516fcf3ce44SJohn Forte * Prepares a SENA enclosure or SENA FC_AL device
1517fcf3ce44SJohn Forte * to be inserted/removed from a specified slot.
1518fcf3ce44SJohn Forte *
1519fcf3ce44SJohn Forte * RETURNS:
1520fcf3ce44SJohn Forte * 0 if OK
1521fcf3ce44SJohn Forte * non-zero otherwise.
1522fcf3ce44SJohn Forte */
1523fcf3ce44SJohn Forte static int
h_pre_hotplug_sena(Hotplug_Devlist * hotplug_dev,WWN_list * wwn_list,int todo,int verbose_flag,int force_flag)1524fcf3ce44SJohn Forte h_pre_hotplug_sena(Hotplug_Devlist *hotplug_dev,
1525fcf3ce44SJohn Forte WWN_list *wwn_list, int todo,
1526fcf3ce44SJohn Forte int verbose_flag, int force_flag)
1527fcf3ce44SJohn Forte {
1528fcf3ce44SJohn Forte int slot, f_r, i, found_null_wwn = 0, err;
1529fcf3ce44SJohn Forte char *ses_path, *dev_path, code;
1530fcf3ce44SJohn Forte char node_wwn_s[WWN_SIZE], device_name[MAXNAMELEN];
1531fcf3ce44SJohn Forte struct l_state_struct l_state;
1532fcf3ce44SJohn Forte struct dlist *dl;
1533fcf3ce44SJohn Forte
1534fcf3ce44SJohn Forte
1535fcf3ce44SJohn Forte if (hotplug_dev->dev_type == DTYPE_ESI) {
1536fcf3ce44SJohn Forte /* entire photon is being removed */
1537fcf3ce44SJohn Forte if ((err = l_offline_photon(hotplug_dev, wwn_list,
1538fcf3ce44SJohn Forte force_flag, verbose_flag)) != 0) {
1539fcf3ce44SJohn Forte return (err);
1540fcf3ce44SJohn Forte }
1541fcf3ce44SJohn Forte return (0);
1542fcf3ce44SJohn Forte }
1543fcf3ce44SJohn Forte
1544fcf3ce44SJohn Forte /* if device is an individual sena disk */
1545fcf3ce44SJohn Forte dl = hotplug_dev->seslist;
1546fcf3ce44SJohn Forte while (dl) {
1547fcf3ce44SJohn Forte ses_path = dl->dev_path;
1548fcf3ce44SJohn Forte if ((err = l_get_status(ses_path, &l_state,
1549fcf3ce44SJohn Forte verbose_flag)) == 0)
1550fcf3ce44SJohn Forte break;
1551fcf3ce44SJohn Forte dl = dl->next;
1552fcf3ce44SJohn Forte }
1553fcf3ce44SJohn Forte if (dl == NULL) {
1554fcf3ce44SJohn Forte return (L_GET_STATUS_FAILED);
1555fcf3ce44SJohn Forte }
1556fcf3ce44SJohn Forte
1557fcf3ce44SJohn Forte f_r = hotplug_dev->f_flag;
1558fcf3ce44SJohn Forte slot = hotplug_dev->slot;
1559fcf3ce44SJohn Forte (void) l_get_drive_name(device_name, slot, f_r, hotplug_dev->box_name);
1560fcf3ce44SJohn Forte
1561fcf3ce44SJohn Forte /* check if disk has null wwn */
1562fcf3ce44SJohn Forte if (f_r) {
1563fcf3ce44SJohn Forte (void) strncpy(node_wwn_s,
1564fcf3ce44SJohn Forte l_state.drv_front[slot].g_disk_state.node_wwn_s, WWN_SIZE);
1565fcf3ce44SJohn Forte } else {
1566fcf3ce44SJohn Forte (void) strncpy(node_wwn_s,
1567fcf3ce44SJohn Forte l_state.drv_rear[slot].g_disk_state.node_wwn_s, WWN_SIZE);
1568fcf3ce44SJohn Forte }
1569fcf3ce44SJohn Forte for (i = 0; i < WWN_SIZE; i++) {
1570fcf3ce44SJohn Forte if (node_wwn_s[i] != '0')
1571fcf3ce44SJohn Forte break;
1572fcf3ce44SJohn Forte found_null_wwn = 1;
1573fcf3ce44SJohn Forte }
1574fcf3ce44SJohn Forte
1575fcf3ce44SJohn Forte switch (todo) {
1576fcf3ce44SJohn Forte case INSERT_DEVICE:
1577fcf3ce44SJohn Forte if (hotplug_dev->f_flag) {
1578fcf3ce44SJohn Forte code =
1579fcf3ce44SJohn Forte l_state.drv_front[slot].ib_status.code;
1580fcf3ce44SJohn Forte } else {
1581fcf3ce44SJohn Forte code =
1582fcf3ce44SJohn Forte l_state.drv_rear[slot].ib_status.code;
1583fcf3ce44SJohn Forte }
1584fcf3ce44SJohn Forte if (code & S_NOT_INSTALLED) {
1585fcf3ce44SJohn Forte /*
1586fcf3ce44SJohn Forte * At this point we know that the drive is not
1587fcf3ce44SJohn Forte * there. Turn on the RQST INSERT bit to make
1588fcf3ce44SJohn Forte * the LED blink
1589fcf3ce44SJohn Forte */
1590fcf3ce44SJohn Forte if ((err = l_encl_status_page_funcs
1591fcf3ce44SJohn Forte (SET_RQST_INSRT, 0, todo,
1592fcf3ce44SJohn Forte ses_path, &l_state, f_r, slot,
1593fcf3ce44SJohn Forte verbose_flag)) != 0) {
1594fcf3ce44SJohn Forte (void) print_errString(err,
1595fcf3ce44SJohn Forte device_name);
1596fcf3ce44SJohn Forte (void) fprintf(stderr,
1597fcf3ce44SJohn Forte MSGSTR(5530,
1598fcf3ce44SJohn Forte " %s: could not turn "
1599fcf3ce44SJohn Forte "on LED\n"),
1600fcf3ce44SJohn Forte device_name);
1601fcf3ce44SJohn Forte }
1602fcf3ce44SJohn Forte } else {
1603fcf3ce44SJohn Forte /*
1604fcf3ce44SJohn Forte * Drive is there so start it.
1605fcf3ce44SJohn Forte */
1606fcf3ce44SJohn Forte if ((err = l_encl_status_page_funcs
1607fcf3ce44SJohn Forte (SET_DRV_ON, 0, todo,
1608fcf3ce44SJohn Forte ses_path, &l_state, f_r, slot,
1609fcf3ce44SJohn Forte verbose_flag)) != 0) {
1610fcf3ce44SJohn Forte (void) print_errString(err,
1611fcf3ce44SJohn Forte device_name);
1612fcf3ce44SJohn Forte (void) fprintf(stderr,
1613fcf3ce44SJohn Forte MSGSTR(5531,
1614fcf3ce44SJohn Forte " could not enable"
1615fcf3ce44SJohn Forte " %s\n"),
1616fcf3ce44SJohn Forte device_name);
1617fcf3ce44SJohn Forte }
1618fcf3ce44SJohn Forte }
1619fcf3ce44SJohn Forte break;
1620fcf3ce44SJohn Forte
1621fcf3ce44SJohn Forte case REMOVE_DEVICE:
1622fcf3ce44SJohn Forte /*
1623fcf3ce44SJohn Forte * if disk has null wwn, then
1624fcf3ce44SJohn Forte * there is no need to check the
1625fcf3ce44SJohn Forte * disk/loop status.
1626fcf3ce44SJohn Forte */
1627fcf3ce44SJohn Forte if (found_null_wwn == 1) {
1628fcf3ce44SJohn Forte if (getenv("_LUX_W_DEBUG") != NULL) {
1629fcf3ce44SJohn Forte (void) fprintf(stdout,
1630fcf3ce44SJohn Forte "Device %s has "
1631fcf3ce44SJohn Forte "null WWN.\n",
1632fcf3ce44SJohn Forte device_name);
1633fcf3ce44SJohn Forte }
1634fcf3ce44SJohn Forte goto rmv;
1635fcf3ce44SJohn Forte }
1636fcf3ce44SJohn Forte if (hotplug_dev->f_flag) {
1637fcf3ce44SJohn Forte if (
1638fcf3ce44SJohn Forte l_state.drv_front[slot].ib_status.code
1639fcf3ce44SJohn Forte == S_NOT_INSTALLED) {
1640fcf3ce44SJohn Forte (void) fprintf(stderr,
1641fcf3ce44SJohn Forte MSGSTR(86,
1642fcf3ce44SJohn Forte " Notice: %s may already"
1643fcf3ce44SJohn Forte " be removed.\n"),
1644fcf3ce44SJohn Forte device_name);
1645fcf3ce44SJohn Forte return (0);
1646fcf3ce44SJohn Forte }
1647fcf3ce44SJohn Forte } else if (
1648fcf3ce44SJohn Forte l_state.drv_rear[slot].ib_status.code
1649fcf3ce44SJohn Forte == S_NOT_INSTALLED) {
1650fcf3ce44SJohn Forte (void) fprintf(stderr,
1651fcf3ce44SJohn Forte MSGSTR(86,
1652fcf3ce44SJohn Forte " Notice: %s may already"
1653fcf3ce44SJohn Forte " be removed.\n"),
1654fcf3ce44SJohn Forte device_name);
1655fcf3ce44SJohn Forte return (0);
1656fcf3ce44SJohn Forte }
1657fcf3ce44SJohn Forte
1658fcf3ce44SJohn Forte rmv:
1659fcf3ce44SJohn Forte if (hotplug_dev->dlhead == NULL) {
1660fcf3ce44SJohn Forte dev_path = NULL;
1661fcf3ce44SJohn Forte } else {
1662fcf3ce44SJohn Forte dev_path = hotplug_dev->dlhead->dev_path;
1663fcf3ce44SJohn Forte }
1664fcf3ce44SJohn Forte
1665fcf3ce44SJohn Forte (void) fprintf(stdout,
1666fcf3ce44SJohn Forte MSGSTR(157,
1667fcf3ce44SJohn Forte "stopping: %s...."), device_name);
1668fcf3ce44SJohn Forte if ((err = g_dev_stop(dev_path, wwn_list, 0)) != 0) {
1669fcf3ce44SJohn Forte return (err);
1670fcf3ce44SJohn Forte }
1671fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(156, "Done\n"));
1672fcf3ce44SJohn Forte
1673fcf3ce44SJohn Forte (void) fprintf(stdout,
1674fcf3ce44SJohn Forte MSGSTR(158, "offlining: %s...."),
1675fcf3ce44SJohn Forte device_name);
1676fcf3ce44SJohn Forte if ((err = g_offline_drive(hotplug_dev->dlhead,
1677fcf3ce44SJohn Forte force_flag)) != 0) {
1678fcf3ce44SJohn Forte (void) fprintf(stdout,
1679fcf3ce44SJohn Forte MSGSTR(160,
1680fcf3ce44SJohn Forte "\nonlining: %s\n"), device_name);
1681fcf3ce44SJohn Forte (void) g_online_drive(hotplug_dev->dlhead, force_flag);
1682fcf3ce44SJohn Forte
1683fcf3ce44SJohn Forte (void) fprintf(stdout,
1684fcf3ce44SJohn Forte MSGSTR(159, "starting: %s...."),
1685fcf3ce44SJohn Forte device_name);
1686fcf3ce44SJohn Forte (void) g_dev_start(dev_path, 0);
1687fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(156, "Done\n"));
1688fcf3ce44SJohn Forte return (err);
1689fcf3ce44SJohn Forte }
1690fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(156, "Done\n"));
1691fcf3ce44SJohn Forte
1692fcf3ce44SJohn Forte /*
1693fcf3ce44SJohn Forte * Take the drive off the loop
1694fcf3ce44SJohn Forte * and blink the LED.
1695fcf3ce44SJohn Forte */
1696fcf3ce44SJohn Forte if (hotplug_dev->dev_location == SENA) {
1697fcf3ce44SJohn Forte if ((err = l_encl_status_page_funcs(SET_RQST_RMV, 0,
1698fcf3ce44SJohn Forte todo, ses_path, &l_state, f_r,
1699fcf3ce44SJohn Forte slot, verbose_flag)) != 0) {
1700fcf3ce44SJohn Forte (void) print_errString(err, device_name);
1701fcf3ce44SJohn Forte (void) fprintf(stderr,
1702fcf3ce44SJohn Forte MSGSTR(5539,
1703fcf3ce44SJohn Forte " %s: could not blink"
1704fcf3ce44SJohn Forte " the yellow LED\n"),
1705fcf3ce44SJohn Forte device_name);
1706fcf3ce44SJohn Forte }
1707fcf3ce44SJohn Forte }
1708fcf3ce44SJohn Forte break;
1709fcf3ce44SJohn Forte }
1710fcf3ce44SJohn Forte return (0);
1711fcf3ce44SJohn Forte }
1712fcf3ce44SJohn Forte
1713fcf3ce44SJohn Forte
1714fcf3ce44SJohn Forte
1715fcf3ce44SJohn Forte /*
1716fcf3ce44SJohn Forte * Performs the post removal operations for
1717fcf3ce44SJohn Forte * a SENA enclosure or a SENA FC_AL disk.
1718fcf3ce44SJohn Forte *
1719fcf3ce44SJohn Forte * RETURNS:
1720fcf3ce44SJohn Forte * 0 if OK
1721fcf3ce44SJohn Forte * non-zero otherwise
1722fcf3ce44SJohn Forte */
1723fcf3ce44SJohn Forte static int
h_post_hotplug_sena(Hotplug_Devlist * hotplug_dev,WWN_list * wwn_list,int todo,int verbose_flag,int force_flag,int enc_type)1724fcf3ce44SJohn Forte h_post_hotplug_sena(Hotplug_Devlist *hotplug_dev,
1725fcf3ce44SJohn Forte WWN_list *wwn_list, int todo,
1726fcf3ce44SJohn Forte int verbose_flag, int force_flag, int enc_type)
1727fcf3ce44SJohn Forte {
1728*e9175934SKlaus Ziegler char *ses_path = NULL, *dev_path = NULL, device_name[MAXNAMELEN];
1729fcf3ce44SJohn Forte int tid, slot, f_r, al_pa, timeout = 0;
1730fcf3ce44SJohn Forte uchar_t port_wwn[WWN_SIZE], node_wwn[WWN_SIZE];
1731fcf3ce44SJohn Forte char code;
1732fcf3ce44SJohn Forte int wait_spinup_flag = 0, wait_map_flag = 0;
1733fcf3ce44SJohn Forte int wait_node_flag = 0, err = 0, nArg;
1734fcf3ce44SJohn Forte gfc_map_t map;
1735fcf3ce44SJohn Forte WWN_list *newWwn_list = NULL;
1736fcf3ce44SJohn Forte struct dlist *dl, *dl1;
1737fcf3ce44SJohn Forte struct l_state_struct l_state;
1738fcf3ce44SJohn Forte
1739fcf3ce44SJohn Forte
1740fcf3ce44SJohn Forte dl = hotplug_dev->seslist;
1741fcf3ce44SJohn Forte slot = hotplug_dev->slot;
1742fcf3ce44SJohn Forte f_r = hotplug_dev->f_flag;
1743fcf3ce44SJohn Forte tid = hotplug_dev->tid;
1744fcf3ce44SJohn Forte
1745fcf3ce44SJohn Forte if (hotplug_dev->dev_type == DTYPE_ESI) {
1746fcf3ce44SJohn Forte /*
1747fcf3ce44SJohn Forte * See if photon has really been removed. If not,
1748fcf3ce44SJohn Forte * try onlining the devices if applicable
1749fcf3ce44SJohn Forte */
1750fcf3ce44SJohn Forte H_DPRINTF(" post_hotplug_sena: Seeing if enclosure "
1751fcf3ce44SJohn Forte "has really been removed:\n"
1752fcf3ce44SJohn Forte " tid=0x%x, ses_path %s\n",
1753fcf3ce44SJohn Forte tid, dl->dev_path);
1754fcf3ce44SJohn Forte
1755fcf3ce44SJohn Forte while (dl) {
1756fcf3ce44SJohn Forte ses_path = dl->dev_path;
1757fcf3ce44SJohn Forte if ((err = g_get_dev_map(ses_path, &map, 0)) == 0) {
1758fcf3ce44SJohn Forte if ((map.hba_addr.port_topology ==
1759fcf3ce44SJohn Forte FC_TOP_PUBLIC_LOOP) ||
1760fcf3ce44SJohn Forte (map.hba_addr.port_topology ==
1761fcf3ce44SJohn Forte FC_TOP_FABRIC)) {
1762fcf3ce44SJohn Forte /* public or fabric loop device */
1763fcf3ce44SJohn Forte free((void *)map.dev_addr);
1764fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5540,
1765fcf3ce44SJohn Forte "This operation is not "
1766fcf3ce44SJohn Forte "supported in this topology.\n"));
1767fcf3ce44SJohn Forte return (0);
1768fcf3ce44SJohn Forte }
1769fcf3ce44SJohn Forte if ((err = g_get_wwn(ses_path, port_wwn,
1770fcf3ce44SJohn Forte node_wwn, &al_pa, verbose_flag)) == 0) {
1771fcf3ce44SJohn Forte tid = g_sf_alpa_to_switch[al_pa];
1772fcf3ce44SJohn Forte if (g_device_in_map(&map, tid)) {
1773fcf3ce44SJohn Forte free((void *)map.dev_addr);
1774fcf3ce44SJohn Forte break;
1775fcf3ce44SJohn Forte }
1776fcf3ce44SJohn Forte }
1777fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
1778fcf3ce44SJohn Forte }
1779fcf3ce44SJohn Forte
1780fcf3ce44SJohn Forte dl = dl->next;
1781fcf3ce44SJohn Forte }
1782fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
1783fcf3ce44SJohn Forte if (dl) {
1784fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5640,
1785fcf3ce44SJohn Forte "Photon \"%s\" not removed."
1786fcf3ce44SJohn Forte " Onlining Drives in enclosure.\n"),
1787fcf3ce44SJohn Forte hotplug_dev->box_name);
1788fcf3ce44SJohn Forte for (dl = hotplug_dev->dlhead; dl; ) {
1789fcf3ce44SJohn Forte (void) g_online_drive(dl->multipath,
1790fcf3ce44SJohn Forte force_flag);
1791fcf3ce44SJohn Forte (void) g_free_multipath(dl->multipath);
1792fcf3ce44SJohn Forte dl1 = dl;
1793fcf3ce44SJohn Forte dl = dl->next;
1794fcf3ce44SJohn Forte (void) free(dl1);
1795fcf3ce44SJohn Forte }
1796fcf3ce44SJohn Forte hotplug_dev->dlhead = NULL;
1797fcf3ce44SJohn Forte return (0);
1798fcf3ce44SJohn Forte }
1799fcf3ce44SJohn Forte /*
1800fcf3ce44SJohn Forte * Remove logical nodes for this
1801fcf3ce44SJohn Forte * photon, this includes ses and
1802fcf3ce44SJohn Forte * /dev/dsk entries.
1803fcf3ce44SJohn Forte * In Solaris7, disks with -C option
1804fcf3ce44SJohn Forte * removes the /dev/dsk entries.
1805fcf3ce44SJohn Forte * The -C option is available
1806fcf3ce44SJohn Forte * only for Solaris7. From Solaris8
1807fcf3ce44SJohn Forte * or higher releases, the "disks"
1808fcf3ce44SJohn Forte * program will be replaced by the
1809fcf3ce44SJohn Forte * devfsadm program.
1810fcf3ce44SJohn Forte */
1811fcf3ce44SJohn Forte /* pass "disks -C" as cmdStrg. */
1812fcf3ce44SJohn Forte nArg = 2;
1813fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[0], nArg) != 0) {
1814fcf3ce44SJohn Forte for (dl = hotplug_dev->dlhead;
1815fcf3ce44SJohn Forte dl != NULL; dl = dl->next) {
1816fcf3ce44SJohn Forte if ((err = h_remove_nodes(dl->multipath))
1817fcf3ce44SJohn Forte != 0) {
1818fcf3ce44SJohn Forte return (err);
1819fcf3ce44SJohn Forte }
1820fcf3ce44SJohn Forte }
1821fcf3ce44SJohn Forte } else {
1822fcf3ce44SJohn Forte (void) fprintf(stdout,
1823fcf3ce44SJohn Forte MSGSTR(5541,
1824fcf3ce44SJohn Forte " Logical Nodes being removed"
1825fcf3ce44SJohn Forte " under /dev/dsk/ and /dev/rdsk:\n"));
1826fcf3ce44SJohn Forte for (dl = hotplug_dev->dlhead;
1827fcf3ce44SJohn Forte dl != NULL; dl = dl->next) {
1828fcf3ce44SJohn Forte (void) h_print_logical_nodes(dl->multipath);
1829fcf3ce44SJohn Forte }
1830fcf3ce44SJohn Forte }
1831fcf3ce44SJohn Forte
1832fcf3ce44SJohn Forte for (dl = hotplug_dev->dlhead; dl != NULL; ) {
1833fcf3ce44SJohn Forte (void) g_free_multipath(dl->multipath);
1834fcf3ce44SJohn Forte dl1 = dl;
1835fcf3ce44SJohn Forte dl = dl->next;
1836fcf3ce44SJohn Forte (void) free(dl1);
1837fcf3ce44SJohn Forte }
1838fcf3ce44SJohn Forte hotplug_dev->dlhead = NULL;
1839fcf3ce44SJohn Forte if ((err = h_remove_ses_nodes(hotplug_dev->seslist)) != 0) {
1840fcf3ce44SJohn Forte return (err);
1841fcf3ce44SJohn Forte }
1842fcf3ce44SJohn Forte return (0);
1843fcf3ce44SJohn Forte }
1844fcf3ce44SJohn Forte
1845fcf3ce44SJohn Forte /* post hotplug operations for a SENA disk. */
1846fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) {
1847fcf3ce44SJohn Forte (void) sprintf(device_name, MSGSTR(5664,
1848fcf3ce44SJohn Forte " Drive in Box Name \"%s\" slot %d"),
1849fcf3ce44SJohn Forte hotplug_dev->box_name,
1850fcf3ce44SJohn Forte f_r ? slot : slot + (MAX_DRIVES_DAK/2));
1851fcf3ce44SJohn Forte } else {
1852fcf3ce44SJohn Forte if (tid & 0x10) {
1853fcf3ce44SJohn Forte (void) sprintf(device_name, MSGSTR(5542,
1854fcf3ce44SJohn Forte " Drive in Box Name \"%s\" rear slot %d"),
1855fcf3ce44SJohn Forte hotplug_dev->box_name, slot);
1856fcf3ce44SJohn Forte } else {
1857fcf3ce44SJohn Forte (void) sprintf(device_name, MSGSTR(5543,
1858fcf3ce44SJohn Forte " Drive in Box Name \"%s\" front slot %d"),
1859fcf3ce44SJohn Forte hotplug_dev->box_name, slot);
1860fcf3ce44SJohn Forte }
1861fcf3ce44SJohn Forte }
1862fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", device_name);
1863fcf3ce44SJohn Forte
1864fcf3ce44SJohn Forte dl = hotplug_dev->seslist;
1865fcf3ce44SJohn Forte while (dl) {
1866fcf3ce44SJohn Forte ses_path = dl->dev_path;
1867fcf3ce44SJohn Forte if ((err = l_get_status(ses_path, &l_state,
1868fcf3ce44SJohn Forte verbose_flag)) == 0)
1869fcf3ce44SJohn Forte break;
1870fcf3ce44SJohn Forte dl = dl->next;
1871fcf3ce44SJohn Forte }
1872fcf3ce44SJohn Forte if (dl == NULL) {
1873fcf3ce44SJohn Forte print_errString(err, ses_path);
1874fcf3ce44SJohn Forte return (L_GET_STATUS_FAILED);
1875fcf3ce44SJohn Forte }
1876fcf3ce44SJohn Forte
1877fcf3ce44SJohn Forte code = 0;
1878fcf3ce44SJohn Forte while (((err = l_encl_status_page_funcs(OVERALL_STATUS,
1879fcf3ce44SJohn Forte &code, todo, ses_path, &l_state, f_r, slot,
1880fcf3ce44SJohn Forte verbose_flag)) != 0) || (code != 0)) {
1881fcf3ce44SJohn Forte if (err) {
1882fcf3ce44SJohn Forte (void) print_errString(err, ses_path);
1883fcf3ce44SJohn Forte } else if (todo == REMOVE_DEVICE) {
1884fcf3ce44SJohn Forte if (code == S_OK) {
1885fcf3ce44SJohn Forte (void) fprintf(stderr,
1886fcf3ce44SJohn Forte MSGSTR(5544,
1887fcf3ce44SJohn Forte "\n Warning: Device has not been"
1888fcf3ce44SJohn Forte " removed from the enclosure\n"
1889fcf3ce44SJohn Forte " and is still on the loop."));
1890fcf3ce44SJohn Forte return (0);
1891fcf3ce44SJohn Forte } else {
1892fcf3ce44SJohn Forte (void) fprintf(stderr,
1893fcf3ce44SJohn Forte MSGSTR(5545,
1894fcf3ce44SJohn Forte " Notice: Device has not been"
1895fcf3ce44SJohn Forte " removed from the enclosure.\n"
1896fcf3ce44SJohn Forte " It has been removed from the"
1897fcf3ce44SJohn Forte " loop and is ready to be\n"
1898fcf3ce44SJohn Forte " removed"
1899fcf3ce44SJohn Forte " from the enclosure, and"
1900fcf3ce44SJohn Forte " the LED is blinking.\n\n"));
1901fcf3ce44SJohn Forte }
1902fcf3ce44SJohn Forte goto loop2;
1903fcf3ce44SJohn Forte } else if ((todo == INSERT_DEVICE) &&
1904fcf3ce44SJohn Forte ((code != S_NOT_AVAILABLE) ||
1905fcf3ce44SJohn Forte (timeout >
1906fcf3ce44SJohn Forte PHOTON_SPINUP_TIMEOUT) ||
1907fcf3ce44SJohn Forte err)) {
1908fcf3ce44SJohn Forte (void) fprintf(stderr,
1909fcf3ce44SJohn Forte MSGSTR(5546,
1910fcf3ce44SJohn Forte "\n Warning: Disk status is"
1911fcf3ce44SJohn Forte " Not OK!\n\n"));
1912fcf3ce44SJohn Forte return (0);
1913fcf3ce44SJohn Forte }
1914fcf3ce44SJohn Forte (void) sleep(PHOTON_SPINUP_DELAY);
1915fcf3ce44SJohn Forte if (wait_spinup_flag++ == 0) {
1916fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5547,
1917fcf3ce44SJohn Forte " Waiting for the disk to spin up:"));
1918fcf3ce44SJohn Forte } else {
1919fcf3ce44SJohn Forte (void) fprintf(stdout, ".");
1920fcf3ce44SJohn Forte }
1921fcf3ce44SJohn Forte timeout++;
1922fcf3ce44SJohn Forte }
1923fcf3ce44SJohn Forte if (wait_spinup_flag) {
1924fcf3ce44SJohn Forte (void) fprintf(stdout, "\n");
1925fcf3ce44SJohn Forte }
1926fcf3ce44SJohn Forte loop2:
1927fcf3ce44SJohn Forte switch (todo) {
1928fcf3ce44SJohn Forte case INSERT_DEVICE:
1929fcf3ce44SJohn Forte /* check loop map that drive is present */
1930fcf3ce44SJohn Forte for (;;) {
1931fcf3ce44SJohn Forte dl = hotplug_dev->seslist;
1932fcf3ce44SJohn Forte map.dev_addr = (gfc_port_dev_info_t *)NULL;
1933fcf3ce44SJohn Forte while (dl) {
1934fcf3ce44SJohn Forte ses_path = dl->dev_path;
1935fcf3ce44SJohn Forte if ((err = g_get_dev_map(ses_path,
1936fcf3ce44SJohn Forte &map, verbose_flag)) != 0) {
1937fcf3ce44SJohn Forte (void) fprintf(stderr,
1938fcf3ce44SJohn Forte MSGSTR(5548,
1939fcf3ce44SJohn Forte " Error: Could not get"
1940fcf3ce44SJohn Forte " map for %s.\n"),
1941fcf3ce44SJohn Forte ses_path);
1942fcf3ce44SJohn Forte return (err);
1943fcf3ce44SJohn Forte }
1944fcf3ce44SJohn Forte if (g_device_in_map(&map, tid)) {
1945fcf3ce44SJohn Forte goto loop3;
1946fcf3ce44SJohn Forte }
1947fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
1948fcf3ce44SJohn Forte dl = dl->next;
1949fcf3ce44SJohn Forte }
1950fcf3ce44SJohn Forte if (timeout > PHOTON_SPINUP_TIMEOUT) {
1951fcf3ce44SJohn Forte (void) fprintf(stderr,
1952fcf3ce44SJohn Forte MSGSTR(5549,
1953fcf3ce44SJohn Forte " Warning: Device not in"
1954fcf3ce44SJohn Forte " loop map.\n"));
1955fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
1956fcf3ce44SJohn Forte return (0);
1957fcf3ce44SJohn Forte }
1958fcf3ce44SJohn Forte if (wait_map_flag++ == 0) {
1959fcf3ce44SJohn Forte (void) fprintf(stdout,
1960fcf3ce44SJohn Forte MSGSTR(5550,
1961fcf3ce44SJohn Forte " Waiting for the device "
1962fcf3ce44SJohn Forte "to appear in the loop map:"));
1963fcf3ce44SJohn Forte } else {
1964fcf3ce44SJohn Forte (void) fprintf(stdout, ".");
1965fcf3ce44SJohn Forte }
1966fcf3ce44SJohn Forte timeout++;
1967fcf3ce44SJohn Forte (void) sleep(PHOTON_SPINUP_DELAY);
1968fcf3ce44SJohn Forte }
1969fcf3ce44SJohn Forte loop3:
1970fcf3ce44SJohn Forte if (wait_map_flag) {
1971fcf3ce44SJohn Forte (void) fprintf(stdout, "\n");
1972fcf3ce44SJohn Forte }
1973fcf3ce44SJohn Forte
1974fcf3ce44SJohn Forte /*
1975fcf3ce44SJohn Forte * Run drvconfig and disks to create
1976fcf3ce44SJohn Forte * logical nodes
1977fcf3ce44SJohn Forte */
1978fcf3ce44SJohn Forte for (;;) {
1979fcf3ce44SJohn Forte /* pass "disks" as cmdStrg */
1980fcf3ce44SJohn Forte nArg = 3;
1981fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[2], nArg) != 0) {
1982fcf3ce44SJohn Forte (void) fprintf(stderr,
1983fcf3ce44SJohn Forte MSGSTR(5551,
1984fcf3ce44SJohn Forte " Could not "
1985fcf3ce44SJohn Forte "run drvconfig.\n"));
1986fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
1987fcf3ce44SJohn Forte return (L_DRVCONFIG_ERROR);
1988fcf3ce44SJohn Forte }
1989fcf3ce44SJohn Forte
1990fcf3ce44SJohn Forte if (l_device_present(ses_path, tid, &map,
1991fcf3ce44SJohn Forte verbose_flag, &dev_path) == 1)
1992fcf3ce44SJohn Forte break;
1993fcf3ce44SJohn Forte if (timeout > PHOTON_SPINUP_TIMEOUT) {
1994fcf3ce44SJohn Forte (void) fprintf(stderr,
1995fcf3ce44SJohn Forte MSGSTR(5552,
1996fcf3ce44SJohn Forte " Warning: Could not find "
1997fcf3ce44SJohn Forte "any node for inserted "
1998fcf3ce44SJohn Forte "device\n"));
1999fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
2000fcf3ce44SJohn Forte return (0);
2001fcf3ce44SJohn Forte }
2002fcf3ce44SJohn Forte if (wait_node_flag++ == 0) {
2003fcf3ce44SJohn Forte (void) fprintf(stdout,
2004fcf3ce44SJohn Forte MSGSTR(5553,
2005fcf3ce44SJohn Forte " Waiting for the logical "
2006fcf3ce44SJohn Forte "node to be created:"));
2007fcf3ce44SJohn Forte } else {
2008fcf3ce44SJohn Forte (void) fprintf(stdout, ".");
2009fcf3ce44SJohn Forte }
2010fcf3ce44SJohn Forte timeout++;
2011fcf3ce44SJohn Forte (void) sleep(PHOTON_SPINUP_DELAY);
2012fcf3ce44SJohn Forte }
2013fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
2014fcf3ce44SJohn Forte if (wait_node_flag) {
2015fcf3ce44SJohn Forte (void) fprintf(stdout, "\n");
2016fcf3ce44SJohn Forte }
2017fcf3ce44SJohn Forte /*
2018fcf3ce44SJohn Forte * In Solaris7, disks with -C
2019fcf3ce44SJohn Forte * option creates the new links
2020fcf3ce44SJohn Forte * and removes any stale links.
2021fcf3ce44SJohn Forte * In pre-Solaris7 releases, just
2022fcf3ce44SJohn Forte * disks should do it all.
2023fcf3ce44SJohn Forte */
2024fcf3ce44SJohn Forte /* pass "disks -C" as cmdStrg */
2025fcf3ce44SJohn Forte nArg = 2;
2026fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[0], nArg) != 0) {
2027fcf3ce44SJohn Forte return (L_DISKS_ERROR);
2028fcf3ce44SJohn Forte }
2029fcf3ce44SJohn Forte /*
2030fcf3ce44SJohn Forte * Get a new wwn list here in order to
2031fcf3ce44SJohn Forte * get the multiple paths to a newly added
2032fcf3ce44SJohn Forte * device.
2033fcf3ce44SJohn Forte */
2034fcf3ce44SJohn Forte if ((err = g_get_wwn_list(&newWwn_list,
2035fcf3ce44SJohn Forte verbose_flag)) != 0) {
2036fcf3ce44SJohn Forte return (err);
2037fcf3ce44SJohn Forte }
2038fcf3ce44SJohn Forte if ((err = g_get_multipath(dev_path, &dl,
2039fcf3ce44SJohn Forte newWwn_list, 0)) != 0) {
2040fcf3ce44SJohn Forte return (err);
2041fcf3ce44SJohn Forte }
2042fcf3ce44SJohn Forte if ((err = h_display_logical_nodes(dl)) != 0) {
2043fcf3ce44SJohn Forte return (err);
2044fcf3ce44SJohn Forte }
2045fcf3ce44SJohn Forte break;
2046fcf3ce44SJohn Forte
2047fcf3ce44SJohn Forte case REMOVE_DEVICE:
2048fcf3ce44SJohn Forte /*
2049fcf3ce44SJohn Forte * TBD
2050fcf3ce44SJohn Forte * Need to check all loops.
2051fcf3ce44SJohn Forte */
2052fcf3ce44SJohn Forte /* check whether device is still in loop map */
2053fcf3ce44SJohn Forte if ((err = g_get_dev_map(ses_path, &map,
2054fcf3ce44SJohn Forte verbose_flag)) != 0) {
2055fcf3ce44SJohn Forte return (err);
2056fcf3ce44SJohn Forte }
2057fcf3ce44SJohn Forte
2058fcf3ce44SJohn Forte if ((map.hba_addr.port_topology ==
2059fcf3ce44SJohn Forte FC_TOP_PUBLIC_LOOP) ||
2060fcf3ce44SJohn Forte (map.hba_addr.port_topology ==
2061fcf3ce44SJohn Forte FC_TOP_FABRIC)) {
2062fcf3ce44SJohn Forte /* public or fabric loop device */
2063fcf3ce44SJohn Forte free((void *)map.dev_addr);
2064fcf3ce44SJohn Forte (void) fprintf(stderr, MSGSTR(5540,
2065fcf3ce44SJohn Forte "This operation is not "
2066fcf3ce44SJohn Forte "supported in this topology.\n"));
2067fcf3ce44SJohn Forte /*
2068fcf3ce44SJohn Forte * calling routine expects a 0 return code
2069fcf3ce44SJohn Forte * or a pre-defined luxadm error code.
2070fcf3ce44SJohn Forte * Here we do not have a pre-defined error
2071fcf3ce44SJohn Forte * code, a 0 is returned.
2072fcf3ce44SJohn Forte */
2073fcf3ce44SJohn Forte return (0);
2074fcf3ce44SJohn Forte }
2075fcf3ce44SJohn Forte
2076fcf3ce44SJohn Forte if (g_device_in_map(&map, tid)) {
2077fcf3ce44SJohn Forte (void) fprintf(stderr, MSGSTR(5554,
2078fcf3ce44SJohn Forte " Warning: Device still in the loop map.\n"));
2079fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
2080fcf3ce44SJohn Forte return (0);
2081fcf3ce44SJohn Forte }
2082fcf3ce44SJohn Forte FREE_DEV_ADDR(map.dev_addr);
2083fcf3ce44SJohn Forte /*
2084fcf3ce44SJohn Forte * In Solaris7, "disks -C" program
2085fcf3ce44SJohn Forte * removes the /dev/{r}dsk entries.
2086fcf3ce44SJohn Forte * The -C option is available only
2087fcf3ce44SJohn Forte * for Solaris7. From Solaris8 or
2088fcf3ce44SJohn Forte * higher releases, the "disks" program
2089fcf3ce44SJohn Forte * will be replaced by devfsadm.
2090fcf3ce44SJohn Forte */
2091fcf3ce44SJohn Forte /* pass "disks -C" as cmdStrg */
2092fcf3ce44SJohn Forte nArg = 2;
2093fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[0], nArg) != 0) {
2094fcf3ce44SJohn Forte return (L_DISKS_ERROR);
2095fcf3ce44SJohn Forte }
2096fcf3ce44SJohn Forte (void) fprintf(stdout,
2097fcf3ce44SJohn Forte MSGSTR(5555,
2098fcf3ce44SJohn Forte " Logical Nodes being removed"
2099fcf3ce44SJohn Forte " under /dev/dsk/ and /dev/rdsk:\n"));
2100fcf3ce44SJohn Forte (void) h_print_logical_nodes(
2101fcf3ce44SJohn Forte hotplug_dev->dlhead);
2102fcf3ce44SJohn Forte break;
2103fcf3ce44SJohn Forte }
2104fcf3ce44SJohn Forte return (0);
2105fcf3ce44SJohn Forte }
2106fcf3ce44SJohn Forte
2107fcf3ce44SJohn Forte
2108fcf3ce44SJohn Forte
2109fcf3ce44SJohn Forte
2110fcf3ce44SJohn Forte /*
2111fcf3ce44SJohn Forte * Creates new ses entries under /dev/es
2112fcf3ce44SJohn Forte * directory for the newly added
2113fcf3ce44SJohn Forte * enclosures.
2114fcf3ce44SJohn Forte *
2115fcf3ce44SJohn Forte * RETURNS:
2116fcf3ce44SJohn Forte * 0 if OK
2117fcf3ce44SJohn Forte * non-zero otherwise
2118fcf3ce44SJohn Forte */
2119fcf3ce44SJohn Forte static int
h_post_insert_encl(timestruc_t ses_lastmtim)2120fcf3ce44SJohn Forte h_post_insert_encl(timestruc_t ses_lastmtim)
2121fcf3ce44SJohn Forte {
2122fcf3ce44SJohn Forte struct stat ses_stat;
2123fcf3ce44SJohn Forte char lname[MAXPATHLEN];
2124fcf3ce44SJohn Forte int err, found_newlink = 0;
2125fcf3ce44SJohn Forte DIR *dir;
2126fcf3ce44SJohn Forte struct dirent *dirent;
2127fcf3ce44SJohn Forte Box_list *bl1, *box_list = NULL;
2128fcf3ce44SJohn Forte
2129fcf3ce44SJohn Forte
2130fcf3ce44SJohn Forte if ((dir = opendir(SES_DIR)) == NULL) {
2131fcf3ce44SJohn Forte return (L_OPEN_ES_DIR_FAILED);
2132fcf3ce44SJohn Forte }
2133fcf3ce44SJohn Forte if ((err = l_get_box_list(&box_list, 0)) != 0) {
2134fcf3ce44SJohn Forte closedir(dir);
2135fcf3ce44SJohn Forte return (err);
2136fcf3ce44SJohn Forte }
2137fcf3ce44SJohn Forte
2138fcf3ce44SJohn Forte /*
2139fcf3ce44SJohn Forte * The mod time of /dev/es was newer than the mod time prior to
2140fcf3ce44SJohn Forte * insert so dir entry is checked at this time.
2141fcf3ce44SJohn Forte */
2142fcf3ce44SJohn Forte while ((dirent = readdir(dir)) != (struct dirent *)NULL) {
2143fcf3ce44SJohn Forte if (strcmp(dirent->d_name, ".") == 0 ||
2144fcf3ce44SJohn Forte strcmp(dirent->d_name, "..") == 0)
2145fcf3ce44SJohn Forte continue;
2146fcf3ce44SJohn Forte
2147fcf3ce44SJohn Forte (void) sprintf(lname, SES_DIR"/%s", dirent->d_name);
2148fcf3ce44SJohn Forte if (lstat(lname, &ses_stat) < 0) {
2149fcf3ce44SJohn Forte (void) print_errString(L_LSTAT_ES_DIR_ERROR,
2150fcf3ce44SJohn Forte lname);
2151fcf3ce44SJohn Forte continue;
2152fcf3ce44SJohn Forte }
2153fcf3ce44SJohn Forte
2154fcf3ce44SJohn Forte for (bl1 = box_list; bl1; bl1 = bl1->box_next) {
2155fcf3ce44SJohn Forte if (strstr(lname, bl1->b_physical_path))
2156fcf3ce44SJohn Forte break;
2157fcf3ce44SJohn Forte }
2158fcf3ce44SJohn Forte
2159fcf3ce44SJohn Forte if (box_list && bl1)
2160fcf3ce44SJohn Forte continue;
2161fcf3ce44SJohn Forte
2162fcf3ce44SJohn Forte if (NEWER(ses_stat.st_ctim, ses_lastmtim)) {
2163fcf3ce44SJohn Forte /* New enclosure was detected. */
2164fcf3ce44SJohn Forte found_newlink++;
2165fcf3ce44SJohn Forte if (found_newlink == 1) {
2166fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5556,
2167fcf3ce44SJohn Forte " New Logical Nodes under /dev/es:\n"));
2168fcf3ce44SJohn Forte }
2169fcf3ce44SJohn Forte (void) fprintf(stdout, "\t%s\n",
2170fcf3ce44SJohn Forte dirent->d_name);
2171fcf3ce44SJohn Forte }
2172fcf3ce44SJohn Forte }
2173fcf3ce44SJohn Forte if (!found_newlink) {
2174fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5662,
2175fcf3ce44SJohn Forte " No new enclosure(s) were added!!\n\n"));
2176fcf3ce44SJohn Forte }
2177fcf3ce44SJohn Forte
2178fcf3ce44SJohn Forte closedir(dir);
2179fcf3ce44SJohn Forte
2180fcf3ce44SJohn Forte (void) l_free_box_list(&box_list);
2181fcf3ce44SJohn Forte return (0);
2182fcf3ce44SJohn Forte }
2183fcf3ce44SJohn Forte
2184fcf3ce44SJohn Forte
2185fcf3ce44SJohn Forte
2186fcf3ce44SJohn Forte /*
2187fcf3ce44SJohn Forte * performs the post removal of individual
2188fcf3ce44SJohn Forte * FC_AL disks.
2189fcf3ce44SJohn Forte *
2190fcf3ce44SJohn Forte * RETURNS:
2191fcf3ce44SJohn Forte * 0 if OK
2192fcf3ce44SJohn Forte * non-zero otherwise
2193fcf3ce44SJohn Forte */
2194fcf3ce44SJohn Forte static int
h_post_remove_dev(Hotplug_Devlist * hotplug_disk,int todo,int verbose_flag)2195fcf3ce44SJohn Forte h_post_remove_dev(Hotplug_Devlist *hotplug_disk,
2196525fef19SToomas Soome int todo, int verbose_flag)
2197fcf3ce44SJohn Forte {
2198525fef19SToomas Soome char device_name[MAXNAMELEN], *dev_path = NULL;
2199525fef19SToomas Soome int tid, err;
2200525fef19SToomas Soome gfc_map_t map;
2201525fef19SToomas Soome int nArg;
2202fcf3ce44SJohn Forte
2203fcf3ce44SJohn Forte
2204fcf3ce44SJohn Forte tid = hotplug_disk->tid;
2205fcf3ce44SJohn Forte (void) sprintf(device_name,
2206fcf3ce44SJohn Forte MSGSTR(5557,
2207fcf3ce44SJohn Forte "\n Device: %s"),
2208fcf3ce44SJohn Forte (hotplug_disk->dlhead)->logical_path);
2209fcf3ce44SJohn Forte
2210fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n", device_name);
2211fcf3ce44SJohn Forte
2212fcf3ce44SJohn Forte dev_path = (hotplug_disk->dlhead)->dev_path;
2213fcf3ce44SJohn Forte
2214fcf3ce44SJohn Forte /*
2215fcf3ce44SJohn Forte * On qlc, after a forcelip on a FC combo box, it sometimes takes 17
2216fcf3ce44SJohn Forte * seconds for the loop to come back online. During this 17 seconds,
2217fcf3ce44SJohn Forte * g_get_dev_map * will return L_NO_DEVICES_FOUND. This delay
2218fcf3ce44SJohn Forte * has been added to assure that the L_NO_DEVICES_FOUND returned from
2219fcf3ce44SJohn Forte * g_get_dev_map is not the result of the 17 second delay on FC combo.
2220fcf3ce44SJohn Forte * This only affects qlc.
2221fcf3ce44SJohn Forte */
2222fcf3ce44SJohn Forte if ((err = g_get_dev_map(dev_path, &map, verbose_flag)) != 0) {
2223fcf3ce44SJohn Forte if ((err == L_NO_DEVICES_FOUND) &&
2224fcf3ce44SJohn Forte (strstr(dev_path, "SUNW,qlc@") != NULL)) {
2225fcf3ce44SJohn Forte sleep(QLC_LIP_DELAY);
2226fcf3ce44SJohn Forte if ((err = g_get_dev_map(dev_path, &map, verbose_flag))
2227fcf3ce44SJohn Forte != 0) {
2228fcf3ce44SJohn Forte if (err != L_NO_DEVICES_FOUND)
2229fcf3ce44SJohn Forte return (err);
2230fcf3ce44SJohn Forte }
2231fcf3ce44SJohn Forte } else if (err != L_NO_DEVICES_FOUND)
2232fcf3ce44SJohn Forte return (err);
2233fcf3ce44SJohn Forte }
2234fcf3ce44SJohn Forte
2235fcf3ce44SJohn Forte /*
2236fcf3ce44SJohn Forte * if g_get_dev_map returns L_NO_DEVICES_FOUND, then there are not
2237fcf3ce44SJohn Forte * devices attached to the HBA and there is no sense in calling
2238fcf3ce44SJohn Forte * g_device_in_map().
2239fcf3ce44SJohn Forte */
2240fcf3ce44SJohn Forte if (err != L_NO_DEVICES_FOUND) {
2241fcf3ce44SJohn Forte if ((map.hba_addr.port_topology == FC_TOP_PUBLIC_LOOP) ||
2242fcf3ce44SJohn Forte (map.hba_addr.port_topology == FC_TOP_FABRIC)) {
2243fcf3ce44SJohn Forte /* public or fabric loop device */
2244fcf3ce44SJohn Forte free((void *)map.dev_addr);
2245fcf3ce44SJohn Forte (void) fprintf(stderr, MSGSTR(5540,
2246fcf3ce44SJohn Forte "This operation is not "
2247fcf3ce44SJohn Forte "supported in this topology.\n"));
2248fcf3ce44SJohn Forte return (0);
2249fcf3ce44SJohn Forte }
2250fcf3ce44SJohn Forte
2251fcf3ce44SJohn Forte if (g_device_in_map(&map, tid) != 0) {
2252fcf3ce44SJohn Forte (void) fprintf(stderr,
2253fcf3ce44SJohn Forte MSGSTR(5558,
2254fcf3ce44SJohn Forte " Warning: Device has"
2255fcf3ce44SJohn Forte " not been removed from\n"
2256fcf3ce44SJohn Forte " the slot and is still"
2257fcf3ce44SJohn Forte " in the loop map.\n\n"));
2258fcf3ce44SJohn Forte free((void *)map.dev_addr);
2259fcf3ce44SJohn Forte return (0);
2260fcf3ce44SJohn Forte }
2261fcf3ce44SJohn Forte free((void *)map.dev_addr);
2262fcf3ce44SJohn Forte }
2263fcf3ce44SJohn Forte /*
2264fcf3ce44SJohn Forte * In Solaris7, "disks -C" program
2265fcf3ce44SJohn Forte * removes the /dev/{r}dsk entries.
2266fcf3ce44SJohn Forte * The -C option is available only
2267fcf3ce44SJohn Forte * for Solaris7. From Solaris8 or
2268fcf3ce44SJohn Forte * higher releases, the "disks" program
2269fcf3ce44SJohn Forte * will be replaced by devfsadm.
2270fcf3ce44SJohn Forte */
2271fcf3ce44SJohn Forte /* pass "disks -C" as cmdStrg. */
2272fcf3ce44SJohn Forte nArg = 2;
2273fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[0], nArg) != 0) {
2274fcf3ce44SJohn Forte return (L_DISKS_ERROR);
2275fcf3ce44SJohn Forte }
2276fcf3ce44SJohn Forte /* pass "tapes -C as cmdStrg. */
2277fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[5], nArg) != 0) {
2278fcf3ce44SJohn Forte return (L_TAPES_ERROR);
2279fcf3ce44SJohn Forte }
2280fcf3ce44SJohn Forte (void) h_print_logical_nodes(hotplug_disk->dlhead);
2281fcf3ce44SJohn Forte
2282fcf3ce44SJohn Forte return (0);
2283fcf3ce44SJohn Forte }
2284fcf3ce44SJohn Forte
2285fcf3ce44SJohn Forte
2286fcf3ce44SJohn Forte
2287fcf3ce44SJohn Forte /*
2288fcf3ce44SJohn Forte * Gets the last modification time for
2289fcf3ce44SJohn Forte * /dev/es/ and /dev/rdsk directories
2290fcf3ce44SJohn Forte * and passes these values to the caller.
2291fcf3ce44SJohn Forte *
2292fcf3ce44SJohn Forte * RETURNS:
2293fcf3ce44SJohn Forte * 0 if OK
2294fcf3ce44SJohn Forte * non-zero in case of error
2295fcf3ce44SJohn Forte */
2296fcf3ce44SJohn Forte static int
h_pre_insert_encl_dev(timestruc_t * ses_time,timestruc_t * dsk_time,timestruc_t * rmt_time)2297fcf3ce44SJohn Forte h_pre_insert_encl_dev(timestruc_t *ses_time, timestruc_t *dsk_time,
2298fcf3ce44SJohn Forte timestruc_t *rmt_time)
2299fcf3ce44SJohn Forte {
2300fcf3ce44SJohn Forte struct stat ses_stat, dsk_stat, rmt_stat;
2301fcf3ce44SJohn Forte
2302fcf3ce44SJohn Forte if (stat(SES_DIR, &ses_stat) < 0) {
2303fcf3ce44SJohn Forte /*
2304fcf3ce44SJohn Forte * Even if there exists no /dev/es don't fail it.
2305fcf3ce44SJohn Forte * The host doesn't have to have any enclosure device
2306fcf3ce44SJohn Forte * configured.
2307fcf3ce44SJohn Forte */
2308fcf3ce44SJohn Forte if (errno == ENOENT) {
2309fcf3ce44SJohn Forte ses_time = (timestruc_t *)NULL;
2310fcf3ce44SJohn Forte } else {
2311fcf3ce44SJohn Forte return (L_LSTAT_ES_DIR_ERROR);
2312fcf3ce44SJohn Forte }
2313fcf3ce44SJohn Forte } else {
2314fcf3ce44SJohn Forte *ses_time = ses_stat.st_mtim;
2315fcf3ce44SJohn Forte }
2316fcf3ce44SJohn Forte
2317fcf3ce44SJohn Forte if (stat(DEV_DSK_DIR, &dsk_stat) < 0) {
2318fcf3ce44SJohn Forte return (L_STAT_DEV_DIR_ERROR);
2319fcf3ce44SJohn Forte } else {
2320fcf3ce44SJohn Forte *dsk_time = dsk_stat.st_mtim;
2321fcf3ce44SJohn Forte }
2322fcf3ce44SJohn Forte if (stat(DEV_TAPE_DIR, &rmt_stat) < 0) {
2323fcf3ce44SJohn Forte /*
2324fcf3ce44SJohn Forte * Even if there exists no /dev/rmt don't fail it.
2325fcf3ce44SJohn Forte * The host doesn't have to have any tape device
2326fcf3ce44SJohn Forte * configured.
2327fcf3ce44SJohn Forte */
2328fcf3ce44SJohn Forte if (errno == ENOENT) {
2329fcf3ce44SJohn Forte rmt_time = (timestruc_t *)NULL;
2330fcf3ce44SJohn Forte } else {
2331fcf3ce44SJohn Forte return (L_STAT_RMT_DIR_ERROR);
2332fcf3ce44SJohn Forte }
2333fcf3ce44SJohn Forte } else {
2334fcf3ce44SJohn Forte *rmt_time = rmt_stat.st_mtim;
2335fcf3ce44SJohn Forte }
2336fcf3ce44SJohn Forte
2337fcf3ce44SJohn Forte return (0);
2338fcf3ce44SJohn Forte }
2339fcf3ce44SJohn Forte
2340fcf3ce44SJohn Forte
2341fcf3ce44SJohn Forte
2342fcf3ce44SJohn Forte /*
2343fcf3ce44SJohn Forte * Waits for loop intialization to complete
2344fcf3ce44SJohn Forte * and runs drvconfig, disks and devlinks to create device nodes
2345fcf3ce44SJohn Forte * for devices that are being added and prints the newly created
2346fcf3ce44SJohn Forte * /dev/rdsk entries.
2347fcf3ce44SJohn Forte *
2348fcf3ce44SJohn Forte * RETURNS:
2349fcf3ce44SJohn Forte * 0 if OK
2350fcf3ce44SJohn Forte * non-zero in case of error
2351fcf3ce44SJohn Forte */
2352fcf3ce44SJohn Forte
2353fcf3ce44SJohn Forte static int
h_post_insert_dev(timestruc_t dsk_lastmtim,timestruc_t rmt_lastmtim)2354fcf3ce44SJohn Forte h_post_insert_dev(timestruc_t dsk_lastmtim, timestruc_t rmt_lastmtim)
2355fcf3ce44SJohn Forte {
2356fcf3ce44SJohn Forte int found_newlink = 0, nArg;
2357fcf3ce44SJohn Forte
2358fcf3ce44SJohn Forte (void) fprintf(stdout,
2359fcf3ce44SJohn Forte MSGSTR(5560,
2360fcf3ce44SJohn Forte "\nWaiting for Loop Initialization to complete...\n"));
2361fcf3ce44SJohn Forte
2362fcf3ce44SJohn Forte /*
2363fcf3ce44SJohn Forte * We sleep here to let the system create nodes. Not sleeping
2364fcf3ce44SJohn Forte * could cause the drvconfig below to run too soon.
2365fcf3ce44SJohn Forte */
2366fcf3ce44SJohn Forte
2367fcf3ce44SJohn Forte (void) sleep(NODE_CREATION_TIME);
2368fcf3ce44SJohn Forte
2369fcf3ce44SJohn Forte /*
2370fcf3ce44SJohn Forte * Run drvconfig and disks to create
2371fcf3ce44SJohn Forte * logical nodes
2372fcf3ce44SJohn Forte */
2373fcf3ce44SJohn Forte /* pass "drvconfig" as cmdStrg */
2374fcf3ce44SJohn Forte nArg = 1;
2375fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[3], nArg) != 0) {
2376fcf3ce44SJohn Forte return (L_DRVCONFIG_ERROR);
2377fcf3ce44SJohn Forte }
2378fcf3ce44SJohn Forte
2379fcf3ce44SJohn Forte /*
2380fcf3ce44SJohn Forte * In 2.7, disks with the -C
2381fcf3ce44SJohn Forte * option should be used to
2382fcf3ce44SJohn Forte * create new links and remove
2383fcf3ce44SJohn Forte * any stale links.
2384fcf3ce44SJohn Forte * In pre-2.7 releases, just
2385fcf3ce44SJohn Forte * disks should do it all.
2386fcf3ce44SJohn Forte */
2387fcf3ce44SJohn Forte
2388fcf3ce44SJohn Forte /* pass "disks -C" as cmdStrg */
2389fcf3ce44SJohn Forte nArg = 2;
2390fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[0], nArg) != 0) {
2391fcf3ce44SJohn Forte return (L_DISKS_ERROR);
2392fcf3ce44SJohn Forte }
2393fcf3ce44SJohn Forte /* pass "tapes -C as cmdStrg */
2394fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[5], nArg) != 0) {
2395fcf3ce44SJohn Forte return (L_TAPES_ERROR);
2396fcf3ce44SJohn Forte }
2397fcf3ce44SJohn Forte
2398fcf3ce44SJohn Forte /* pass "devlinks" as cmdStrg */
2399fcf3ce44SJohn Forte nArg = 1;
2400fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[4], nArg) != 0) {
2401fcf3ce44SJohn Forte return (L_DEVLINKS_ERROR);
2402fcf3ce44SJohn Forte }
2403fcf3ce44SJohn Forte
2404fcf3ce44SJohn Forte /* check /dev/dsk and /dev/rmt for new links */
2405fcf3ce44SJohn Forte found_newlink = h_find_new_device_link(DEV_DSK_DIR, dsk_lastmtim) +
2406fcf3ce44SJohn Forte h_find_new_device_link(DEV_TAPE_DIR, rmt_lastmtim);
2407fcf3ce44SJohn Forte
2408fcf3ce44SJohn Forte if (!found_newlink) {
2409fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5562,
2410fcf3ce44SJohn Forte " No new device(s) were added!!\n\n"));
2411fcf3ce44SJohn Forte }
2412fcf3ce44SJohn Forte
2413fcf3ce44SJohn Forte return (0);
2414fcf3ce44SJohn Forte }
2415fcf3ce44SJohn Forte
2416fcf3ce44SJohn Forte
2417fcf3ce44SJohn Forte
2418fcf3ce44SJohn Forte /*
2419fcf3ce44SJohn Forte * Performs the pre hotplug operations on SENA enclosure(s),
2420fcf3ce44SJohn Forte * SENA disk(s) and individual fcal disk(s).
2421fcf3ce44SJohn Forte * If the device is failed to remove, then it removes the device from the
2422fcf3ce44SJohn Forte * hotplug list and continues with the next device in the list.
2423fcf3ce44SJohn Forte *
2424fcf3ce44SJohn Forte * RETURNS:
2425fcf3ce44SJohn Forte * 0 if OK
2426fcf3ce44SJohn Forte * prints an error message to stderr and returns 0
2427fcf3ce44SJohn Forte */
2428fcf3ce44SJohn Forte static int
h_pre_hotplug(Hotplug_Devlist ** disk_list_head_ptr,WWN_list * wwn_list,int todo,int verbose_flag,int force_flag)2429fcf3ce44SJohn Forte h_pre_hotplug(Hotplug_Devlist **disk_list_head_ptr,
2430fcf3ce44SJohn Forte WWN_list *wwn_list, int todo,
2431fcf3ce44SJohn Forte int verbose_flag, int force_flag)
2432fcf3ce44SJohn Forte {
2433fcf3ce44SJohn Forte Hotplug_Devlist *list, *disk_list;
2434fcf3ce44SJohn Forte int err = 0;
2435fcf3ce44SJohn Forte
2436fcf3ce44SJohn Forte disk_list = *disk_list_head_ptr;
2437fcf3ce44SJohn Forte while (disk_list != NULL) {
2438fcf3ce44SJohn Forte if ((disk_list->dev_type == DTYPE_ESI) ||
2439fcf3ce44SJohn Forte (disk_list->dev_location == SENA)) {
2440fcf3ce44SJohn Forte if ((err = h_pre_hotplug_sena(disk_list, wwn_list,
2441fcf3ce44SJohn Forte todo, verbose_flag, force_flag)) != 0) {
2442fcf3ce44SJohn Forte (void) print_errString(err,
2443fcf3ce44SJohn Forte disk_list->dev_name);
2444fcf3ce44SJohn Forte goto delete;
2445fcf3ce44SJohn Forte }
2446fcf3ce44SJohn Forte } else if (disk_list->dev_location == NON_SENA) {
2447fcf3ce44SJohn Forte if ((err = h_pre_remove_dev(disk_list, wwn_list,
2448fcf3ce44SJohn Forte verbose_flag, force_flag)) != 0) {
2449fcf3ce44SJohn Forte (void) print_errString(err,
2450fcf3ce44SJohn Forte disk_list->dev_name);
2451fcf3ce44SJohn Forte goto delete;
2452fcf3ce44SJohn Forte }
2453fcf3ce44SJohn Forte }
2454fcf3ce44SJohn Forte disk_list = disk_list->next;
2455fcf3ce44SJohn Forte continue;
2456fcf3ce44SJohn Forte delete:
2457fcf3ce44SJohn Forte list = disk_list->prev;
2458fcf3ce44SJohn Forte if (list != NULL) {
2459fcf3ce44SJohn Forte list->next = disk_list->next;
2460fcf3ce44SJohn Forte if (list->next != NULL)
2461fcf3ce44SJohn Forte list->next->prev = list;
2462fcf3ce44SJohn Forte }
2463fcf3ce44SJohn Forte list = disk_list;
2464fcf3ce44SJohn Forte disk_list = disk_list->next;
2465fcf3ce44SJohn Forte if (list == *disk_list_head_ptr)
2466fcf3ce44SJohn Forte *disk_list_head_ptr = disk_list;
2467fcf3ce44SJohn Forte (void) g_free_multipath(list->seslist);
2468fcf3ce44SJohn Forte (void) g_free_multipath(list->dlhead);
2469fcf3ce44SJohn Forte (void) free(list);
2470fcf3ce44SJohn Forte }
2471fcf3ce44SJohn Forte return (0);
2472fcf3ce44SJohn Forte }
2473fcf3ce44SJohn Forte
2474fcf3ce44SJohn Forte
2475fcf3ce44SJohn Forte
2476fcf3ce44SJohn Forte /*
2477fcf3ce44SJohn Forte * Performs the post removal of a list of SENA enclosure(s),
2478fcf3ce44SJohn Forte * SENA disk(s) and individual fcal disk(s).
2479fcf3ce44SJohn Forte *
2480fcf3ce44SJohn Forte * RETURNS:
2481fcf3ce44SJohn Forte * 0 O.K.
2482fcf3ce44SJohn Forte * non-zero otherwise
2483fcf3ce44SJohn Forte */
2484fcf3ce44SJohn Forte static int
h_post_hotplug(Hotplug_Devlist * hotplug_dlist,WWN_list * wwn_list,int todo,int verbose_flag,int force_flag,int enc_type)2485fcf3ce44SJohn Forte h_post_hotplug(Hotplug_Devlist *hotplug_dlist,
2486fcf3ce44SJohn Forte WWN_list *wwn_list, int todo,
2487fcf3ce44SJohn Forte int verbose_flag, int force_flag, int enc_type)
2488fcf3ce44SJohn Forte {
2489fcf3ce44SJohn Forte Hotplug_Devlist *list;
2490fcf3ce44SJohn Forte int err;
2491fcf3ce44SJohn Forte
2492fcf3ce44SJohn Forte /* Do a lip on every loop so that we get the latest loop maps */
2493fcf3ce44SJohn Forte if (todo != INSERT_DEVICE) {
2494fcf3ce44SJohn Forte if ((err = g_forcelip_all(hotplug_dlist)) != 0) {
2495fcf3ce44SJohn Forte return (err);
2496fcf3ce44SJohn Forte }
2497fcf3ce44SJohn Forte }
2498fcf3ce44SJohn Forte
2499fcf3ce44SJohn Forte while (hotplug_dlist != NULL) {
2500fcf3ce44SJohn Forte if ((hotplug_dlist->dev_location == SENA) ||
2501fcf3ce44SJohn Forte (hotplug_dlist->dev_type == DTYPE_ESI)) {
2502fcf3ce44SJohn Forte if ((err = h_post_hotplug_sena(hotplug_dlist, wwn_list, todo,
2503fcf3ce44SJohn Forte verbose_flag, force_flag, enc_type)) != 0)
2504fcf3ce44SJohn Forte (void) print_errString(err, hotplug_dlist->dev_name);
2505fcf3ce44SJohn Forte } else if (hotplug_dlist->dev_location == NON_SENA) {
2506fcf3ce44SJohn Forte if ((err = h_post_remove_dev(hotplug_dlist,
2507fcf3ce44SJohn Forte todo, verbose_flag)) != 0)
2508fcf3ce44SJohn Forte (void) print_errString(err,
2509fcf3ce44SJohn Forte hotplug_dlist->dev_name);
2510fcf3ce44SJohn Forte }
2511fcf3ce44SJohn Forte list = hotplug_dlist;
2512fcf3ce44SJohn Forte hotplug_dlist = hotplug_dlist->next;
2513fcf3ce44SJohn Forte (void) g_free_multipath(list->seslist);
2514fcf3ce44SJohn Forte (void) g_free_multipath(list->dlhead);
2515fcf3ce44SJohn Forte (void) free(list);
2516fcf3ce44SJohn Forte }
2517fcf3ce44SJohn Forte return (0);
2518fcf3ce44SJohn Forte }
2519fcf3ce44SJohn Forte
2520fcf3ce44SJohn Forte
2521fcf3ce44SJohn Forte /*
2522fcf3ce44SJohn Forte * removes the device's logical paths.
2523fcf3ce44SJohn Forte *
2524fcf3ce44SJohn Forte * RETURNS:
2525fcf3ce44SJohn Forte * 0 if OK
2526fcf3ce44SJohn Forte * non-zero otherwise
2527fcf3ce44SJohn Forte */
2528fcf3ce44SJohn Forte static int
h_remove_nodes(struct dlist * dl)2529fcf3ce44SJohn Forte h_remove_nodes(struct dlist *dl)
2530fcf3ce44SJohn Forte {
2531fcf3ce44SJohn Forte char link[MAXPATHLEN], path[MAXPATHLEN];
2532fcf3ce44SJohn Forte char lname[MAXPATHLEN], *ptr;
2533fcf3ce44SJohn Forte DIR *dir;
2534fcf3ce44SJohn Forte struct dirent *dirent;
2535fcf3ce44SJohn Forte struct dlist *dlist;
2536fcf3ce44SJohn Forte
2537fcf3ce44SJohn Forte if ((dir = opendir(DEV_DSK_DIR)) == NULL) {
2538fcf3ce44SJohn Forte return (L_READ_DEV_DIR_ERROR);
2539fcf3ce44SJohn Forte }
2540fcf3ce44SJohn Forte if (dl == NULL) {
2541fcf3ce44SJohn Forte /* pass "disks" as cmdStrg */
2542fcf3ce44SJohn Forte if (h_execCmnd(cmdStrg[1], 1) != 0) {
2543fcf3ce44SJohn Forte return (L_DISKS_ERROR);
2544fcf3ce44SJohn Forte }
2545fcf3ce44SJohn Forte }
2546fcf3ce44SJohn Forte
2547fcf3ce44SJohn Forte (void) fprintf(stdout,
2548fcf3ce44SJohn Forte MSGSTR(5563,
2549fcf3ce44SJohn Forte " Removing Logical Nodes: \n"));
2550fcf3ce44SJohn Forte
2551fcf3ce44SJohn Forte while ((dirent = readdir(dir)) != (struct dirent *)NULL) {
2552fcf3ce44SJohn Forte if (strcmp(dirent->d_name, ".") == 0 ||
2553fcf3ce44SJohn Forte strcmp(dirent->d_name, "..") == 0) {
2554fcf3ce44SJohn Forte continue;
2555fcf3ce44SJohn Forte }
2556fcf3ce44SJohn Forte (void) sprintf(lname, DEV_DSK_DIR"/%s", dirent->d_name);
2557fcf3ce44SJohn Forte if (readlink((const char *)lname, (char *)link,
2558fcf3ce44SJohn Forte (size_t)MAXPATHLEN) <= 0) {
2559fcf3ce44SJohn Forte (void) fprintf(stderr,
2560fcf3ce44SJohn Forte MSGSTR(5564,
2561fcf3ce44SJohn Forte " Error: Could not read %s\n"),
2562fcf3ce44SJohn Forte lname);
2563fcf3ce44SJohn Forte continue;
2564fcf3ce44SJohn Forte }
2565fcf3ce44SJohn Forte for (dlist = dl; dlist != NULL; dlist = dlist->next) {
2566fcf3ce44SJohn Forte (void) strcpy(path, dlist->dev_path);
2567fcf3ce44SJohn Forte ptr = strrchr(path, ':');
2568fcf3ce44SJohn Forte if (ptr)
2569fcf3ce44SJohn Forte *ptr = '\0';
2570fcf3ce44SJohn Forte if (strstr(link, path)) {
2571fcf3ce44SJohn Forte (void) unlink(lname);
2572fcf3ce44SJohn Forte (void) sprintf(lname, "/dev/rdsk/%s",
2573fcf3ce44SJohn Forte dirent->d_name);
2574fcf3ce44SJohn Forte (void) fprintf(stdout,
2575fcf3ce44SJohn Forte MSGSTR(5565,
2576fcf3ce44SJohn Forte "\tRemoving %s\n"),
2577fcf3ce44SJohn Forte dirent->d_name);
2578fcf3ce44SJohn Forte (void) unlink(lname);
2579fcf3ce44SJohn Forte }
2580fcf3ce44SJohn Forte }
2581fcf3ce44SJohn Forte }
2582fcf3ce44SJohn Forte closedir(dir);
2583fcf3ce44SJohn Forte return (0);
2584fcf3ce44SJohn Forte }
2585fcf3ce44SJohn Forte
2586fcf3ce44SJohn Forte
2587fcf3ce44SJohn Forte
2588fcf3ce44SJohn Forte /*
2589fcf3ce44SJohn Forte * removes the SENA's ses paths.
2590fcf3ce44SJohn Forte *
2591fcf3ce44SJohn Forte * RETURNS:
2592fcf3ce44SJohn Forte * 0 if OK
2593fcf3ce44SJohn Forte * non-zero otherwise
2594fcf3ce44SJohn Forte */
2595fcf3ce44SJohn Forte static int
h_remove_ses_nodes(struct dlist * dlist)2596fcf3ce44SJohn Forte h_remove_ses_nodes(struct dlist *dlist)
2597fcf3ce44SJohn Forte {
2598fcf3ce44SJohn Forte char link[MAXPATHLEN], lname[MAXPATHLEN];
2599fcf3ce44SJohn Forte DIR *dir;
2600fcf3ce44SJohn Forte struct dirent *dirent;
2601fcf3ce44SJohn Forte struct dlist *dl;
2602fcf3ce44SJohn Forte
2603fcf3ce44SJohn Forte
2604fcf3ce44SJohn Forte if ((dir = opendir(SES_DIR)) == NULL) {
2605fcf3ce44SJohn Forte return (L_READ_DEV_DIR_ERROR);
2606fcf3ce44SJohn Forte }
2607fcf3ce44SJohn Forte
2608fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5566, " Removing Ses Nodes:\n"));
2609fcf3ce44SJohn Forte
2610fcf3ce44SJohn Forte /*
2611fcf3ce44SJohn Forte * Remove the ses entries
2612fcf3ce44SJohn Forte * of the form ses<#>
2613fcf3ce44SJohn Forte * from the /dev/es directory.
2614fcf3ce44SJohn Forte */
2615fcf3ce44SJohn Forte
2616fcf3ce44SJohn Forte while ((dirent = readdir(dir)) != (struct dirent *)NULL) {
2617fcf3ce44SJohn Forte if (strcmp(dirent->d_name, ".") == 0 ||
2618fcf3ce44SJohn Forte strcmp(dirent->d_name, "..") == 0)
2619fcf3ce44SJohn Forte continue;
2620fcf3ce44SJohn Forte
2621fcf3ce44SJohn Forte (void) sprintf(lname, SES_DIR"/%s", dirent->d_name);
2622fcf3ce44SJohn Forte if (readlink((const char *)lname, (char *)link,
2623fcf3ce44SJohn Forte (size_t)MAXPATHLEN) <= 0) {
2624fcf3ce44SJohn Forte (void) fprintf(stderr,
2625fcf3ce44SJohn Forte MSGSTR(5564,
2626fcf3ce44SJohn Forte " Error: Could not read %s\n"),
2627fcf3ce44SJohn Forte lname);
2628fcf3ce44SJohn Forte continue;
2629fcf3ce44SJohn Forte }
2630fcf3ce44SJohn Forte for (dl = dlist; dl != NULL; dl = dl->next) {
2631fcf3ce44SJohn Forte if (strstr(link, dl->dev_path)) {
2632fcf3ce44SJohn Forte (void) fprintf(stdout,
2633fcf3ce44SJohn Forte MSGSTR(5568,
2634fcf3ce44SJohn Forte "\tRemoving %s\n"),
2635fcf3ce44SJohn Forte lname);
2636fcf3ce44SJohn Forte (void) unlink(lname);
2637fcf3ce44SJohn Forte }
2638fcf3ce44SJohn Forte }
2639fcf3ce44SJohn Forte }
2640fcf3ce44SJohn Forte closedir(dir);
2641fcf3ce44SJohn Forte (void) g_free_multipath(dlist);
2642fcf3ce44SJohn Forte return (0);
2643fcf3ce44SJohn Forte }
2644fcf3ce44SJohn Forte
2645fcf3ce44SJohn Forte
2646fcf3ce44SJohn Forte /*
2647fcf3ce44SJohn Forte * prints the device's logical
2648fcf3ce44SJohn Forte * paths for disks to stdout.
2649fcf3ce44SJohn Forte *
2650fcf3ce44SJohn Forte * RETURNS:
2651fcf3ce44SJohn Forte * 0 if OK
2652fcf3ce44SJohn Forte * non-zero otherwise
2653fcf3ce44SJohn Forte */
2654fcf3ce44SJohn Forte static void
h_print_logical_nodes(struct dlist * disk_list)2655fcf3ce44SJohn Forte h_print_logical_nodes(struct dlist *disk_list)
2656fcf3ce44SJohn Forte {
2657fcf3ce44SJohn Forte char *lpath, *ptr, *buf_ptr, buf[MAXNAMELEN], dev[MAXNAMELEN];
2658fcf3ce44SJohn Forte struct dlist *dlist;
2659fcf3ce44SJohn Forte int i, found_dev = 0;
2660fcf3ce44SJohn Forte char *tape_entries[] = { "", "b", "bn", "c", "cb", "cbn", "cn",
2661fcf3ce44SJohn Forte "h", "hb", "hbn", "hn", "l", "lb",
2662fcf3ce44SJohn Forte "lbn", "ln", "m", "mb", "mbn", "mn",
2663fcf3ce44SJohn Forte "n", "u", "ub", "ubn", "un", NULL};
2664fcf3ce44SJohn Forte
2665fcf3ce44SJohn Forte for (dlist = disk_list; dlist != NULL; dlist = dlist->next) {
2666fcf3ce44SJohn Forte lpath = dlist->logical_path;
2667fcf3ce44SJohn Forte if ((ptr = strrchr(lpath, 'c')) == NULL)
2668fcf3ce44SJohn Forte continue;
2669fcf3ce44SJohn Forte (void) strcpy(buf, ptr);
2670fcf3ce44SJohn Forte if ((ptr = strrchr(buf, 's')) == NULL)
2671fcf3ce44SJohn Forte continue;
2672525fef19SToomas Soome *(++ptr) = '\0';
2673fcf3ce44SJohn Forte found_dev++;
2674fcf3ce44SJohn Forte if (found_dev == 1)
2675fcf3ce44SJohn Forte (void) fprintf(stdout,
2676fcf3ce44SJohn Forte MSGSTR(5559, " Logical Nodes being "
2677fcf3ce44SJohn Forte "removed under /dev/dsk/ and "
2678fcf3ce44SJohn Forte "/dev/rdsk:\n"));
2679fcf3ce44SJohn Forte for (i = 0; i <= 7; i++) {
2680fcf3ce44SJohn Forte (void) sprintf(dev, "%s%d", buf, i);
2681fcf3ce44SJohn Forte (void) fprintf(stdout, "\t%s\n", dev);
2682fcf3ce44SJohn Forte }
2683fcf3ce44SJohn Forte }
2684fcf3ce44SJohn Forte found_dev = 0;
2685fcf3ce44SJohn Forte for (dlist = disk_list; dlist != NULL; dlist = dlist->next) {
2686fcf3ce44SJohn Forte lpath = dlist->logical_path;
2687fcf3ce44SJohn Forte if (strstr(lpath, DEV_TAPE_DIR)) {
2688fcf3ce44SJohn Forte if ((ptr = strrchr(lpath, '/')) == NULL)
2689fcf3ce44SJohn Forte continue;
2690fcf3ce44SJohn Forte found_dev++;
2691fcf3ce44SJohn Forte if (found_dev == 1)
2692fcf3ce44SJohn Forte (void) fprintf(stdout, "Logical Nodes being "
2693fcf3ce44SJohn Forte "removed under /dev/rmt:\n");
2694fcf3ce44SJohn Forte ptr++;
2695fcf3ce44SJohn Forte buf_ptr = ptr;
2696fcf3ce44SJohn Forte while (*ptr >= '0' && *ptr <= '9')
2697fcf3ce44SJohn Forte ptr++;
2698525fef19SToomas Soome *ptr = '\0';
2699fcf3ce44SJohn Forte for (i = 0, ptr = tape_entries[0];
2700fcf3ce44SJohn Forte ptr != NULL;
2701fcf3ce44SJohn Forte i++, ptr = tape_entries[i]) {
2702fcf3ce44SJohn Forte (void) sprintf(dev, "%s%s", buf_ptr, ptr);
2703fcf3ce44SJohn Forte (void) fprintf(stdout, "\t%s\n", dev);
2704fcf3ce44SJohn Forte }
2705fcf3ce44SJohn Forte }
2706fcf3ce44SJohn Forte }
2707fcf3ce44SJohn Forte }
2708fcf3ce44SJohn Forte
2709fcf3ce44SJohn Forte /*
2710fcf3ce44SJohn Forte * displays logical paths to a
2711fcf3ce44SJohn Forte * device to stdout.
2712fcf3ce44SJohn Forte *
2713fcf3ce44SJohn Forte * RETURNS:
2714fcf3ce44SJohn Forte * 0 if OK
2715fcf3ce44SJohn Forte * non-zero otherwise
2716fcf3ce44SJohn Forte */
2717fcf3ce44SJohn Forte static int
h_display_logical_nodes(struct dlist * dlist)2718fcf3ce44SJohn Forte h_display_logical_nodes(struct dlist *dlist)
2719fcf3ce44SJohn Forte {
2720fcf3ce44SJohn Forte char link[MAXPATHLEN], path[MAXPATHLEN];
2721fcf3ce44SJohn Forte char lname[MAXPATHLEN], *d1;
2722fcf3ce44SJohn Forte DIR *dir;
2723fcf3ce44SJohn Forte struct dirent *dirent;
2724fcf3ce44SJohn Forte struct dlist *dl;
2725fcf3ce44SJohn Forte
2726fcf3ce44SJohn Forte
2727fcf3ce44SJohn Forte if ((dir = opendir(DEV_DSK_DIR)) == NULL) {
2728fcf3ce44SJohn Forte return (L_READ_DEV_DIR_ERROR);
2729fcf3ce44SJohn Forte }
2730fcf3ce44SJohn Forte (void) fprintf(stdout,
2731fcf3ce44SJohn Forte MSGSTR(5569,
2732fcf3ce44SJohn Forte " Logical Nodes under /dev/dsk and /dev/rdsk :\n"));
2733fcf3ce44SJohn Forte
2734fcf3ce44SJohn Forte while ((dirent = readdir(dir)) != (struct dirent *)NULL) {
2735fcf3ce44SJohn Forte if (strcmp(dirent->d_name, ".") == 0 ||
2736fcf3ce44SJohn Forte strcmp(dirent->d_name, "..") == 0) {
2737fcf3ce44SJohn Forte continue;
2738fcf3ce44SJohn Forte }
2739fcf3ce44SJohn Forte (void) sprintf(lname, DEV_DSK_DIR"/%s", dirent->d_name);
2740fcf3ce44SJohn Forte if (readlink((const char *)lname, (char *)link,
2741fcf3ce44SJohn Forte (size_t)MAXPATHLEN) <= 0) {
2742fcf3ce44SJohn Forte (void) print_errString(L_SYMLINK_ERROR, lname);
2743fcf3ce44SJohn Forte continue;
2744fcf3ce44SJohn Forte }
2745fcf3ce44SJohn Forte for (dl = dlist; dl; dl = dl->next) {
2746fcf3ce44SJohn Forte (void) strcpy(path, dl->dev_path);
2747fcf3ce44SJohn Forte d1 = strrchr(path, ':');
2748fcf3ce44SJohn Forte if (d1)
2749fcf3ce44SJohn Forte *d1 = '\0';
2750fcf3ce44SJohn Forte if (strstr(link, path)) {
2751fcf3ce44SJohn Forte (void) fprintf(stdout,
2752fcf3ce44SJohn Forte "\t%s\n",
2753fcf3ce44SJohn Forte dirent->d_name);
2754fcf3ce44SJohn Forte }
2755fcf3ce44SJohn Forte }
2756fcf3ce44SJohn Forte }
2757fcf3ce44SJohn Forte
2758fcf3ce44SJohn Forte closedir(dir);
2759fcf3ce44SJohn Forte return (0);
2760fcf3ce44SJohn Forte }
2761fcf3ce44SJohn Forte
2762fcf3ce44SJohn Forte
2763fcf3ce44SJohn Forte
2764fcf3ce44SJohn Forte /*
2765fcf3ce44SJohn Forte * prints a list of devices which
2766fcf3ce44SJohn Forte * will be inserted or removed
2767fcf3ce44SJohn Forte * to the stdout and asks for
2768fcf3ce44SJohn Forte * the user's confirmation.
2769fcf3ce44SJohn Forte *
2770fcf3ce44SJohn Forte * RETURNS:
2771fcf3ce44SJohn Forte * 0 if OK
2772fcf3ce44SJohn Forte * non-zero otherwise
2773fcf3ce44SJohn Forte */
2774fcf3ce44SJohn Forte static int
h_print_list_warn(Hotplug_Devlist * disk_list_head,int todo,int enc_type)2775fcf3ce44SJohn Forte h_print_list_warn(Hotplug_Devlist *disk_list_head, int todo, int enc_type)
2776fcf3ce44SJohn Forte {
2777fcf3ce44SJohn Forte int i;
2778fcf3ce44SJohn Forte char choice[2];
2779fcf3ce44SJohn Forte struct dlist *dl_ses, *dl_multi;
2780fcf3ce44SJohn Forte Hotplug_Devlist *disk_list = disk_list_head;
2781fcf3ce44SJohn Forte
2782fcf3ce44SJohn Forte (void) fprintf(stdout,
2783fcf3ce44SJohn Forte MSGSTR(5570, "The list of devices which will be "));
2784fcf3ce44SJohn Forte switch (todo) {
2785fcf3ce44SJohn Forte case INSERT_DEVICE:
2786fcf3ce44SJohn Forte (void) fprintf(stdout,
2787fcf3ce44SJohn Forte MSGSTR(5571, "inserted is:\n"));
2788fcf3ce44SJohn Forte break;
2789fcf3ce44SJohn Forte case REMOVE_DEVICE:
2790fcf3ce44SJohn Forte (void) fprintf(stdout,
2791fcf3ce44SJohn Forte MSGSTR(5572, "removed is:\n"));
2792fcf3ce44SJohn Forte break;
2793fcf3ce44SJohn Forte }
2794fcf3ce44SJohn Forte
2795fcf3ce44SJohn Forte for (i = 1; disk_list; i++, disk_list = disk_list->next) {
2796fcf3ce44SJohn Forte if ((disk_list->dev_type == DTYPE_DIRECT) &&
2797fcf3ce44SJohn Forte (disk_list->dev_location == SENA)) {
2798525fef19SToomas Soome if (disk_list->f_flag != 0) {
2799fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) {
2800fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5665,
2801fcf3ce44SJohn Forte " %d: Box Name: \"%s\" slot %d\n"),
2802fcf3ce44SJohn Forte i, disk_list->box_name, disk_list->slot);
2803fcf3ce44SJohn Forte } else {
2804fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(137,
2805fcf3ce44SJohn Forte " %d: Box Name: \"%s\" front slot %d\n"),
2806fcf3ce44SJohn Forte i, disk_list->box_name, disk_list->slot);
2807fcf3ce44SJohn Forte }
2808fcf3ce44SJohn Forte } else {
2809fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) {
2810fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5665,
2811fcf3ce44SJohn Forte " %d: Box Name: \"%s\" slot %d\n"),
2812fcf3ce44SJohn Forte i, disk_list->box_name,
2813fcf3ce44SJohn Forte disk_list->slot + (MAX_DRIVES_DAK/2));
2814fcf3ce44SJohn Forte } else {
2815fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(136,
2816fcf3ce44SJohn Forte " %d: Box Name: \"%s\" rear slot %d\n"),
2817fcf3ce44SJohn Forte i, disk_list->box_name, disk_list->slot);
2818fcf3ce44SJohn Forte }
2819fcf3ce44SJohn Forte }
2820fcf3ce44SJohn Forte } else if (((disk_list->dev_type == DTYPE_DIRECT) ||
2821fcf3ce44SJohn Forte (disk_list->dev_type == DTYPE_SEQUENTIAL)) &&
2822fcf3ce44SJohn Forte (disk_list->dev_location == NON_SENA)) {
2823fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5573,
2824fcf3ce44SJohn Forte " %d: Device name: %s\n"),
2825fcf3ce44SJohn Forte i, disk_list->dev_name);
2826fcf3ce44SJohn Forte } else if (disk_list->dev_type == DTYPE_ESI) {
2827fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5574,
2828fcf3ce44SJohn Forte " %d: Box name: %s\n"),
2829fcf3ce44SJohn Forte i, disk_list->box_name);
2830fcf3ce44SJohn Forte }
2831fcf3ce44SJohn Forte if (getenv("_LUX_H_DEBUG") != NULL) {
2832fcf3ce44SJohn Forte if (disk_list->dev_location == SENA) {
2833fcf3ce44SJohn Forte (void) fprintf(stdout,
2834fcf3ce44SJohn Forte " Select ID:\t0x%x\n",
2835fcf3ce44SJohn Forte disk_list->tid);
2836fcf3ce44SJohn Forte if (disk_list->dev_type != DTYPE_ESI) {
2837fcf3ce44SJohn Forte if (enc_type == DAK_ENC_TYPE) {
2838fcf3ce44SJohn Forte (void) fprintf(stdout,
2839fcf3ce44SJohn Forte " Location: \tSlot %d \n",
2840fcf3ce44SJohn Forte disk_list->f_flag
2841fcf3ce44SJohn Forte ? disk_list->slot
2842fcf3ce44SJohn Forte : disk_list->slot
2843fcf3ce44SJohn Forte +MAX_DRIVES_DAK/2);
2844fcf3ce44SJohn Forte } else {
2845fcf3ce44SJohn Forte (void) fprintf(stdout,
2846fcf3ce44SJohn Forte " Location: \tSlot %d %s \n",
2847fcf3ce44SJohn Forte disk_list->slot, disk_list->f_flag
2848fcf3ce44SJohn Forte ? "front" : "rear");
2849fcf3ce44SJohn Forte }
2850fcf3ce44SJohn Forte }
2851fcf3ce44SJohn Forte }
2852fcf3ce44SJohn Forte }
2853fcf3ce44SJohn Forte if (todo == REMOVE_DEVICE) {
2854fcf3ce44SJohn Forte (void) fprintf(stdout, " ");
2855fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(90, "Node WWN:"));
2856fcf3ce44SJohn Forte (void) fprintf(stdout, " %s\n",
2857fcf3ce44SJohn Forte disk_list->node_wwn_s);
2858fcf3ce44SJohn Forte
2859fcf3ce44SJohn Forte (void) fprintf(stdout, " ");
2860fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(35, "Device Type:"));
2861fcf3ce44SJohn Forte if (disk_list->dev_type == DTYPE_ESI) {
2862fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5581,
2863fcf3ce44SJohn Forte " SENA (%s)\n"),
2864fcf3ce44SJohn Forte dtype[disk_list->dev_type]);
2865fcf3ce44SJohn Forte } else {
2866fcf3ce44SJohn Forte (void) fprintf(stdout, "%s\n",
2867fcf3ce44SJohn Forte dtype[disk_list->dev_type]);
2868fcf3ce44SJohn Forte }
2869fcf3ce44SJohn Forte
2870fcf3ce44SJohn Forte if (disk_list->dev_type == DTYPE_ESI) {
2871fcf3ce44SJohn Forte dl_ses = disk_list->seslist;
2872fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5575,
2873fcf3ce44SJohn Forte " SES Paths:\n"));
2874fcf3ce44SJohn Forte while (dl_ses) {
2875fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5576,
2876fcf3ce44SJohn Forte " %s\n"), dl_ses->dev_path);
2877fcf3ce44SJohn Forte dl_ses = dl_ses->next;
2878fcf3ce44SJohn Forte }
2879fcf3ce44SJohn Forte } else {
2880fcf3ce44SJohn Forte dl_multi = disk_list->dlhead;
2881fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5577,
2882fcf3ce44SJohn Forte " Device Paths:\n"));
2883fcf3ce44SJohn Forte while (dl_multi) {
2884fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5578,
2885fcf3ce44SJohn Forte " %s\n"),
2886fcf3ce44SJohn Forte dl_multi->logical_path);
2887fcf3ce44SJohn Forte dl_multi = dl_multi->next;
2888fcf3ce44SJohn Forte }
2889fcf3ce44SJohn Forte }
2890fcf3ce44SJohn Forte }
2891fcf3ce44SJohn Forte (void) fprintf(stdout, "\n");
2892fcf3ce44SJohn Forte }
2893fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5579,
2894fcf3ce44SJohn Forte "\nPlease verify the above list of devices"
2895fcf3ce44SJohn Forte " and\nthen enter 'c' or <CR> to Continue"
2896fcf3ce44SJohn Forte " or 'q' to Quit. [Default: c]: "));
2897fcf3ce44SJohn Forte
2898fcf3ce44SJohn Forte /* Get the user input and continue accordingly. */
2899fcf3ce44SJohn Forte for (;;) {
2900fcf3ce44SJohn Forte (void) gets(choice);
2901fcf3ce44SJohn Forte if (choice[0] == 'c' || choice[0] == 'C' ||
2902fcf3ce44SJohn Forte choice[0] == 'q' || choice[0] == 'Q' ||
2903fcf3ce44SJohn Forte choice[0] == '\0') {
2904fcf3ce44SJohn Forte break;
2905fcf3ce44SJohn Forte }
2906fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5580,
2907fcf3ce44SJohn Forte " Enter an appropriate option [c,<CR>,q]: "));
2908fcf3ce44SJohn Forte }
2909fcf3ce44SJohn Forte
2910fcf3ce44SJohn Forte if (choice[0] == 'q' || choice[0] == 'Q') {
2911fcf3ce44SJohn Forte return (-1);
2912fcf3ce44SJohn Forte }
2913fcf3ce44SJohn Forte return (0);
2914fcf3ce44SJohn Forte }
2915fcf3ce44SJohn Forte
2916fcf3ce44SJohn Forte
2917fcf3ce44SJohn Forte static int
h_find_new_device_link(char * device_dir,timestruc_t lastmtim)2918fcf3ce44SJohn Forte h_find_new_device_link(char *device_dir, timestruc_t lastmtim)
2919fcf3ce44SJohn Forte {
2920fcf3ce44SJohn Forte struct stat dsk_stat;
2921fcf3ce44SJohn Forte char lname[MAXPATHLEN], link[MAXPATHLEN];
2922fcf3ce44SJohn Forte char *link_ptr;
2923fcf3ce44SJohn Forte DIR *dir;
2924fcf3ce44SJohn Forte struct dirent *dirent;
2925fcf3ce44SJohn Forte int found_newlink = 0;
2926fcf3ce44SJohn Forte
2927fcf3ce44SJohn Forte
2928fcf3ce44SJohn Forte if ((dir = opendir(device_dir)) == NULL) {
2929fcf3ce44SJohn Forte if (errno == ENOENT) {
2930fcf3ce44SJohn Forte return (0);
2931fcf3ce44SJohn Forte } else {
2932fcf3ce44SJohn Forte return (L_READ_DEV_DIR_ERROR);
2933fcf3ce44SJohn Forte }
2934fcf3ce44SJohn Forte }
2935fcf3ce44SJohn Forte
2936fcf3ce44SJohn Forte while ((dirent = readdir(dir)) != (struct dirent *)NULL) {
2937fcf3ce44SJohn Forte if (strcmp(dirent->d_name, ".") == 0 ||
2938fcf3ce44SJohn Forte strcmp(dirent->d_name, "..") == 0) {
2939fcf3ce44SJohn Forte continue;
2940fcf3ce44SJohn Forte }
2941fcf3ce44SJohn Forte (void) sprintf(lname, "%s/%s", device_dir, dirent->d_name);
2942fcf3ce44SJohn Forte if (lstat(lname, &dsk_stat) < 0) {
2943fcf3ce44SJohn Forte (void) print_errString(L_LSTAT_ES_DIR_ERROR,
2944fcf3ce44SJohn Forte lname);
2945fcf3ce44SJohn Forte continue;
2946fcf3ce44SJohn Forte }
2947fcf3ce44SJohn Forte if (readlink((const char *)lname, (char *)link,
2948fcf3ce44SJohn Forte (size_t)MAXPATHLEN) <= 0) {
2949fcf3ce44SJohn Forte (void) print_errString(L_SYMLINK_ERROR, lname);
2950fcf3ce44SJohn Forte continue;
2951fcf3ce44SJohn Forte }
2952fcf3ce44SJohn Forte
2953fcf3ce44SJohn Forte /*
2954fcf3ce44SJohn Forte * "link" can be a relative pathname. But, since
2955fcf3ce44SJohn Forte * g_get_path_type() only accepts absolute paths, we
2956fcf3ce44SJohn Forte * will skip to the part where "/devices/" begins and pass a
2957fcf3ce44SJohn Forte * pointer from there. Since "link" is got from readlink(),
2958fcf3ce44SJohn Forte * it is unlikely that it will not have /devices string, but
2959fcf3ce44SJohn Forte * we will check for it anyways.
2960fcf3ce44SJohn Forte */
2961fcf3ce44SJohn Forte if (!(link_ptr = strstr(link, "/devices/")))
2962fcf3ce44SJohn Forte continue;
2963fcf3ce44SJohn Forte if (!g_get_path_type(link_ptr)) {
2964fcf3ce44SJohn Forte continue;
2965fcf3ce44SJohn Forte }
2966fcf3ce44SJohn Forte if (NEWER(dsk_stat.st_ctim, lastmtim)) {
2967fcf3ce44SJohn Forte found_newlink++;
2968fcf3ce44SJohn Forte if (found_newlink == 1) {
2969fcf3ce44SJohn Forte if (! (strcmp(device_dir, DEV_DSK_DIR))) {
2970fcf3ce44SJohn Forte (void) fprintf(stdout, MSGSTR(5561,
2971fcf3ce44SJohn Forte " New Logical Nodes under "
2972fcf3ce44SJohn Forte "/dev/dsk and /dev/rdsk :\n"));
2973fcf3ce44SJohn Forte } else { /* device_dir is /dev/rmt */
2974fcf3ce44SJohn Forte (void) fprintf(stdout, "New Logical "
2975fcf3ce44SJohn Forte "Node under /dev/rmt:\n");
2976fcf3ce44SJohn Forte }
2977fcf3ce44SJohn Forte }
2978fcf3ce44SJohn Forte (void) fprintf(stdout, "\t%s\n", dirent->d_name);
2979fcf3ce44SJohn Forte }
2980fcf3ce44SJohn Forte }
2981fcf3ce44SJohn Forte closedir(dir);
2982fcf3ce44SJohn Forte return (found_newlink);
2983fcf3ce44SJohn Forte }
2984fcf3ce44SJohn Forte
2985fcf3ce44SJohn Forte
2986fcf3ce44SJohn Forte /*
2987fcf3ce44SJohn Forte * prints the device state.
2988fcf3ce44SJohn Forte *
2989fcf3ce44SJohn Forte * RETURNS:
2990fcf3ce44SJohn Forte * None.
2991fcf3ce44SJohn Forte */
2992fcf3ce44SJohn Forte void
print_dev_state(char * devname,int state)2993fcf3ce44SJohn Forte print_dev_state(char *devname, int state)
2994fcf3ce44SJohn Forte {
2995fcf3ce44SJohn Forte (void) printf("\t%s: ", devname);
2996fcf3ce44SJohn Forte if (state & DEVICE_ONLINE) {
2997fcf3ce44SJohn Forte (void) printf(MSGSTR(3000, "Online"));
2998fcf3ce44SJohn Forte if (state & DEVICE_BUSY) {
2999fcf3ce44SJohn Forte (void) printf(" ");
3000fcf3ce44SJohn Forte (void) printf(MSGSTR(37, "Busy"));
3001fcf3ce44SJohn Forte }
3002fcf3ce44SJohn Forte if (state & DEVICE_DOWN) {
3003fcf3ce44SJohn Forte (void) printf(" ");
3004fcf3ce44SJohn Forte (void) printf(MSGSTR(118, "Down"));
3005fcf3ce44SJohn Forte }
3006fcf3ce44SJohn Forte } else {
3007fcf3ce44SJohn Forte if (state & DEVICE_OFFLINE) {
3008fcf3ce44SJohn Forte (void) printf(MSGSTR(3001, "Offline"));
3009fcf3ce44SJohn Forte if (state & DEVICE_DOWN) {
3010fcf3ce44SJohn Forte (void) printf(" ");
3011fcf3ce44SJohn Forte (void) printf(MSGSTR(118, "Down"));
3012fcf3ce44SJohn Forte }
3013fcf3ce44SJohn Forte }
3014fcf3ce44SJohn Forte }
3015fcf3ce44SJohn Forte (void) printf("\n");
3016fcf3ce44SJohn Forte }
3017fcf3ce44SJohn Forte
3018fcf3ce44SJohn Forte
3019fcf3ce44SJohn Forte /*
3020fcf3ce44SJohn Forte * prints the bus state.
3021fcf3ce44SJohn Forte *
3022fcf3ce44SJohn Forte * RETURNS:
3023fcf3ce44SJohn Forte * None.
3024fcf3ce44SJohn Forte */
3025fcf3ce44SJohn Forte void
print_bus_state(char * devname,int state)3026fcf3ce44SJohn Forte print_bus_state(char *devname, int state)
3027fcf3ce44SJohn Forte {
3028fcf3ce44SJohn Forte (void) printf("\t%s: ", devname);
3029fcf3ce44SJohn Forte if (state == BUS_QUIESCED) {
3030fcf3ce44SJohn Forte (void) printf(MSGSTR(3002, "Quiesced"));
3031fcf3ce44SJohn Forte } else if (state == BUS_ACTIVE) {
3032fcf3ce44SJohn Forte (void) printf(MSGSTR(39, "Active"));
3033fcf3ce44SJohn Forte } else if (state == BUS_SHUTDOWN) {
3034fcf3ce44SJohn Forte (void) printf(MSGSTR(3003, "Shutdown"));
3035fcf3ce44SJohn Forte }
3036fcf3ce44SJohn Forte (void) printf("\n");
3037fcf3ce44SJohn Forte }
3038