~ubuntu-branches/ubuntu/intrepid/raidutils/intrepid

« back to all changes in this revision

Viewing changes to raideng/drv_busy.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Barak Pearlmutter
  • Date: 2004-05-18 11:33:42 UTC
  • Revision ID: james.westby@ubuntu.com-20040518113342-tyqavmso5q351xi2
Tags: upstream-0.0.4
ImportĀ upstreamĀ versionĀ 0.0.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 1996-2004, Adaptec Corporation
 
2
 * All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 *
 
7
 * - Redistributions of source code must retain the above copyright notice, this
 
8
 *   list of conditions and the following disclaimer.
 
9
 * - Redistributions in binary form must reproduce the above copyright notice,
 
10
 *   this list of conditions and the following disclaimer in the documentation
 
11
 *   and/or other materials provided with the distribution.
 
12
 * - Neither the name of the Adaptec Corporation nor the names of its
 
13
 *   contributors may be used to endorse or promote products derived from this
 
14
 *   software without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
17
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
19
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
20
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
21
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
22
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
23
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
24
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
25
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
26
 * POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/*
 
30
 * UNIX based drive busy checking routine.
 
31
 *
 
32
 *      1999/02/11 salyzyn@dpt.com
 
33
 *              Initial creation
 
34
 */
 
35
 
 
36
#include "stdio.h"
 
37
#include "drv_busy.hpp"
 
38
#include "string.h"
 
39
#include "stdlib.h"
 
40
 
 
41
#if (defined(_DPT_WIN_NT))
 
42
int DPTDriveBusy::drvBusy(int hba, int bus, int target, int lun)
 
43
{
 
44
        return (0);
 
45
}
 
46
#else // _DPT_WIN_NT
 
47
int DPTDriveBusy::newDeviceList (DPTDeviceList ** List, char * name)
 
48
{
 
49
        char              * Buffer;
 
50
        char              * Head = Buffer = Strdup(name);
 
51
        char              * Path;
 
52
        DPTDeviceList * Link = *List;
 
53
        DPTDeviceList * New = (DPTDeviceList *)NULL;
 
54
        DPTDeviceList * Next;
 
55
        int                             RetVal = 0;
 
56
        FILE              * fp;
 
57
        /* Parse out major, minor and links */
 
58
        static char     ls[] = "ls -ld %s 2>/dev/null | sed -n '"
 
59
          "s#.* \\([0-9][0-9]*\\),[  ]*\\([0-9][0-9]*\\).*#\\1 \\2#p\n"
 
60
          "s#^d.*#d#p\n"
 
61
          "s#^l.* \\([^         ]*/\\)[^/       ]*/[^/  ]*/[^/  ]*/[^/  ]* -> \\.\\./\\.\\./\\.\\./\\([^        ][^     ]*\\)$# \\1\\2#p\n"
 
62
          "s#^l.* \\([^         ]*/\\)[^/       ]*/[^/  ]*/[^/  ]* -> \\.\\./\\.\\./\\([^       ][^     ]*\\)$#l\\1\\2#p\n"
 
63
          "s#^l.* \\([^         ]*/\\)[^/       ]*/[^/  ]* -> \\.\\./\\([^      ][^     ]*\\)$#l\\1\\2#p\n"
 
64
          "s#^l.* \\([^         ]*/\\)[^/       ]* -> \\([^/    ][^     ]*\\)$#l\\1\\2#p\n"
 
65
          "s#^l.* -> \\([^      ][^     ]*\\)$#l\\1#p'";
 
66
        static char     eol[] = " \t\r\n";
 
67
 
 
68
        Link = *List;
 
69
        while (((Path = strtok (Head, eol)) != NULL) && (Path[0] != '\0')) {
 
70
                Head = (char *)NULL;
 
71
                if ((Next = (DPTDeviceList *)new char[sizeof(DPTDeviceList)
 
72
                  + strlen(Path)]) != (DPTDeviceList *)NULL) {
 
73
                        Next->Next = Link;
 
74
                        Next->Link = (DPTDeviceList *)NULL;
 
75
                        Next->Major = -1;
 
76
                        Next->Minor = -1;
 
77
                        (void)strcpy (Next->Name, Path);
 
78
                        if (New) {
 
79
                                New->Link = Next;
 
80
                        } else {
 
81
                                *List = Next;
 
82
                        }
 
83
                        New = Next;
 
84
                } else {
 
85
                        RetVal = -1;
 
86
                }
 
87
        }
 
88
        delete [] Buffer;
 
89
 
 
90
        /* Find any links, or device information, and extend them */
 
91
        if (New)        /* Any new entries to check? */
 
92
        for (Link = *List; Link != (DPTDeviceList *)NULL; Link = Link->Link) {
 
93
 
 
94
                Buffer = new char[sizeof(ls) + strlen(Link->Name) - 1];
 
95
                sprintf (Buffer, ls, Link->Name);
 
96
                fp = SafePopenRead (Buffer);
 
97
                delete [] Buffer;
 
98
 
 
99
                Buffer = new char[512];
 
100
                while (fgets(Buffer, 512, fp)) {
 
101
                        switch (Buffer[0]) {
 
102
                        case 'd':       /* Mark it as the mount point */
 
103
                                Link->Major = -2;
 
104
                                Link->Minor = -2;
 
105
                                break;
 
106
                        case 'l':       /* It's a link to a device */
 
107
                                if ((Next = (DPTDeviceList *)new char[sizeof(DPTDeviceList)
 
108
                              + strlen(Buffer + 1)]) != (DPTDeviceList *)NULL) {
 
109
                                        Next->Next = Link->Next;
 
110
                                        Next->Link = Link->Link;
 
111
                                        Next->Major = -1;
 
112
                                        Next->Minor = -1;
 
113
                                        (void)strcpy (Next->Name, strtok (Buffer + 1, eol));
 
114
                                        Link->Link = Next;
 
115
                                } else {
 
116
                                        RetVal = -1;
 
117
                                }
 
118
                                break;
 
119
                        default:        /* It's the mount device */
 
120
                                if ((Path = strtok(Buffer, eol)) != (char *)NULL) {
 
121
                                        Link->Major = atoi(Path);
 
122
                                        if ((Path = strtok ((char *)NULL, eol)) != (char *)NULL) {
 
123
                                                Link->Minor = atoi(Path);
 
124
                                        }
 
125
                                }
 
126
                                break;
 
127
                        }
 
128
                }
 
129
                delete [] Buffer;
 
130
                SafePclose (fp);
 
131
        }
 
132
        return (RetVal);
 
133
}
 
134
 
 
135
void DPTDriveBusy::deleteDeviceList (DPTDeviceList * List)
 
136
{
 
137
        if (List != (DPTDeviceList *)NULL) {
 
138
                DPTDeviceList * Link;
 
139
                do {
 
140
                        if ((Link = List->Link) == (DPTDeviceList *)NULL) {
 
141
                                Link = List->Next;
 
142
                        }
 
143
                        delete [] ((char *) List);
 
144
                } while ((List = Link) != (DPTDeviceList *)NULL);
 
145
        }
 
146
}
 
147
 
 
148
static char *TargetStringDirs[] = {
 
149
        "",
 
150
        "/dev/dsk/",
 
151
        "/dev/rdsk/",
 
152
        "/dev/",
 
153
        "/dev/r",
 
154
        (char *)NULL
 
155
};
 
156
static char *TargetStringSuffixes[] = {
 
157
        "",
 
158
        "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
 
159
        "a", "b", "c", "d", "e", "f", "g", "h",
 
160
        (char *)NULL
 
161
};
 
162
 
 
163
static char *TargetPathDirs[] = {
 
164
        "",
 
165
        "/devices/",
 
166
        "/proc/",
 
167
        (char *)NULL
 
168
};
 
169
static char *TargetPathSuffixes[] = {
 
170
        "",
 
171
        ":a", ":b", ":c", ":d", ":e", ":f", ":g", ":h",
 
172
        (char *)NULL
 
173
};
 
174
 
 
175
int DPTDriveBusy::drvBusy(int hba, int bus, int target, int lun)
 
176
{       char          * Targets[2];
 
177
        char         ** Dirs[sizeof(Targets)/sizeof(Targets[0])];
 
178
        char         ** Suffixes[sizeof(Targets)/sizeof(Targets[0])];
 
179
        int                     SuffixIndex;
 
180
        DPTDeviceList * Mounts = (DPTDeviceList *)NULL;
 
181
        int             RetVal = -1;
 
182
 
 
183
        /* Initialize the local structures */
 
184
        Targets[0] = getTargetString(hba, bus, target, lun);
 
185
        Dirs[0] = TargetStringDirs;
 
186
        Suffixes[0] = TargetStringSuffixes;
 
187
        Targets[1] = getTargetPath(hba, bus, target, lun);
 
188
        Dirs[1] = TargetPathDirs;
 
189
        Suffixes[1] = TargetPathSuffixes;
 
190
 
 
191
        for (SuffixIndex = 0;;) {
 
192
                while (Targets[0] == (char *)NULL) {
 
193
                        int Index, NoneZero = 0;
 
194
 
 
195
                        for (Index = sizeof(Targets)/sizeof(Targets[0]); Index; --Index) {
 
196
                                if ((Targets[Index-2] = Targets[Index-1]) != (char *)NULL) {
 
197
                                        ++NoneZero;
 
198
                                }
 
199
                                Targets[Index-1] = (char *)NULL;
 
200
                                Dirs[Index-2] = Dirs[Index-1];
 
201
                                Suffixes[Index-2] = Suffixes[Index-1];
 
202
                        }
 
203
                        if (NoneZero == 0) {
 
204
                                break;
 
205
                        }
 
206
                }
 
207
                if (Targets[0] == (char *)NULL) {
 
208
                        break;
 
209
                }
 
210
 
 
211
                /* Check if the Dirs/Targets entry exists */
 
212
                {       char * name = new char[strlen(Dirs[0][0]) + strlen(Targets[0])
 
213
                          + strlen(Suffixes[0][SuffixIndex]) + 1];
 
214
 
 
215
                        if (name == (char *)NULL) {
 
216
                                RetVal = -2;
 
217
                                break;
 
218
                        }
 
219
                        (void)strcat(strcat(strcpy(name,
 
220
                          Dirs[0][0]), Targets[0]), Suffixes[0][SuffixIndex]);
 
221
                        switch(PathExists(name)) {
 
222
                case PathExists_Exists:
 
223
                    case PathExists_Read:
 
224
                    case PathExists_Open:
 
225
                                /* Check if the Dirs/Target entry is mounted */
 
226
                                if (Mounts == (DPTDeviceList *)NULL) {
 
227
                                        FILE * fp = SafePopenRead("mount | sed -n '"
 
228
                                          "s/^\\([^     ][^     ]*\\)[  ][      ]*on[   ][      ]*\\([^         ][^     ]*\\).*/\\1 \\2/p'");
 
229
                                        char * Buffer = new char[512];
 
230
 
 
231
                                        while (fgets (Buffer, 512, fp)) {
 
232
                                                if (newDeviceList (&Mounts, Buffer)) {
 
233
                                                        RetVal = -2;
 
234
                                                }
 
235
                                        }
 
236
                                        SafePclose(fp);
 
237
                                        if (RetVal == -1) {
 
238
                                                RetVal = 0;
 
239
                                        }
 
240
#                                       if (defined(DEBUG) && (DEBUG > 0))
 
241
                                                if (Mounts != (DPTDeviceList *)NULL) {
 
242
                                                    DPTDeviceList * List = Mounts;
 
243
                                                        DPTDeviceList * Link;
 
244
 
 
245
                                                    printf ("Mount list:\n");
 
246
                                                        do {
 
247
                                                                printf ("%s", List->Name);
 
248
                                                                if ((List->Major == -2)
 
249
                                                                 && (List->Minor == -2)) {
 
250
                                                                        printf ("/");
 
251
                                                                } else if ((List->Major != -1)
 
252
                                                                 || (List->Minor != -1)) {
 
253
                                                                        printf ("(%d,%d)",
 
254
                                                                          List->Major, List->Minor);
 
255
                                                                }
 
256
                                                                if ((Link = List->Link)
 
257
                                                                  == (DPTDeviceList *)NULL) {
 
258
                                                                        printf ("\n");
 
259
                                                                        Link = List->Next;
 
260
                                                                } else {
 
261
                                                                        printf (", ");
 
262
                                                                }
 
263
                                                        } while ((List = Link) != (DPTDeviceList *)NULL);
 
264
                                                }
 
265
#                                       endif
 
266
                                }
 
267
                                /* We have an initialized mount database, search! */
 
268
                                {
 
269
                                        DPTDeviceList * Link;
 
270
                                        DPTDeviceList * Names = (DPTDeviceList *)NULL;
 
271
 
 
272
                                        newDeviceList (&Names, name);
 
273
                                        for (Link = Mounts; Link != (DPTDeviceList *)NULL; ) {
 
274
                                                DPTDeviceList * Next;
 
275
                        DPTDeviceList *Name;
 
276
                                                for (Name = Names;
 
277
                                                  (Name = Name->Link) != (DPTDeviceList *)NULL; ) {
 
278
                                                        /* Same name, or same device */
 
279
                                                        if ((strcmp (Name->Name, Link->Name) == 0)
 
280
                                                         || ((Name->Major == Link->Major)
 
281
                                                          && (Name->Minor == Link->Minor))) {
 
282
                                                                break;
 
283
                                                        }
 
284
                                                }
 
285
                                                if (Name != (DPTDeviceList *)NULL) {
 
286
                                                        RetVal = 1;
 
287
                                                        break;
 
288
                                                }
 
289
                                                if ((Next = Link->Link) == (DPTDeviceList *)NULL) {
 
290
                                                        Next = Link->Next;
 
291
                                                }
 
292
                                                Link = Next;
 
293
                                        }
 
294
                                        deleteDeviceList (Names);
 
295
                                }
 
296
                                break;
 
297
                                
 
298
                    case PathExists_Busy:
 
299
                                RetVal = 1;     /* It's busy even before we hit the ground */
 
300
                        case PathExists_None:
 
301
                                break;
 
302
                        }
 
303
                        delete [] name;
 
304
                }
 
305
 
 
306
                if ((RetVal != -1) && (RetVal != 0)) {
 
307
                        break;
 
308
                }
 
309
                /* Try next */
 
310
                if (Suffixes[0][++SuffixIndex] == (char *)NULL) {
 
311
                        SuffixIndex = 0;
 
312
                        if ((++(Dirs[0]))[0] == (char *)NULL) {
 
313
                                delete [] Targets[0];
 
314
                                Targets[0] = (char *)NULL;
 
315
                        }
 
316
                }
 
317
        }
 
318
        /* Free up resources */
 
319
        {       int Index;
 
320
 
 
321
                for (Index = 0; Index < (sizeof(Targets)/sizeof(Targets[0])); ++Index) {
 
322
                        if (Targets[Index] != (char *)NULL) {
 
323
                                delete [] Targets[Index];
 
324
                        }
 
325
                }
 
326
        }
 
327
        deleteDeviceList (Mounts);
 
328
 
 
329
        return (RetVal);
 
330
}
 
331
#endif
 
332
 
 
333
/* `C' interface routine */
 
334
extern "C" {
 
335
    int drv_busy(int hba, int bus, int target, int lun)
 
336
        {
 
337
                if (hba == -1) {
 
338
                        DPTControllerMap::Reset();
 
339
                        return (0);
 
340
                }
 
341
                DPTDriveBusy * obj = new DPTDriveBusy();
 
342
                int                        retVal = obj->drvBusy(hba, bus, target, lun);
 
343
                delete obj;
 
344
                return (retVal);
 
345
        }
 
346
 
 
347
#if (defined(DEBUG))
 
348
        main (int argc, char ** argv)
 
349
        {
 
350
                int hba, bus, target, lun;
 
351
 
 
352
                hba = bus = target = lun = 0;
 
353
 
 
354
                if (argc > 1) {
 
355
                        hba = atoi(argv[1]);
 
356
                }
 
357
                if (argc > 2) {
 
358
                        bus = atoi(argv[2]);
 
359
                }
 
360
                if (argc > 3) {
 
361
                        target = atoi(argv[3]);
 
362
                }
 
363
                if (argc > 4) {
 
364
                        lun = atoi(argv[4]);
 
365
                }
 
366
                printf ("d%db%dt%dd%d: ", hba, bus, target, lun);
 
367
                switch (drv_busy (hba, bus, target, lun)) {
 
368
                case 0:
 
369
                        printf ("not busy\n");
 
370
                        break;
 
371
                case 1:
 
372
                        printf ("busy\n");
 
373
                        break;
 
374
                case -1:
 
375
                        printf ("not found\n");
 
376
                        break;
 
377
                case -2:
 
378
                        printf ("allocation error\n");
 
379
                        break;
 
380
                default:
 
381
                        printf ("Error\n");
 
382
                }
 
383
        }
 
384
#endif
 
385
}
 
386
 
 
387
#if (defined(DEBUG))
 
388
# if (DEBUG <= 1)
 
389
#  undef DEBUG
 
390
# endif
 
391
# include "ctlr_map.cpp"
 
392
#endif