source: trunk/athena/bin/attach/rvdutil.c @ 6257

Revision 6257, 6.1 KB checked in by probe, 32 years ago (diff)
Took out extraneous OLD_KERBEROS ifdef (not properly working)
Line 
1/*      Created by:     Robert French
2 *
3 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/attach/rvdutil.c,v $
4 *      $Author: probe $
5 *
6 *      Copyright (c) 1988 by the Massachusetts Institute of Technology.
7 */
8
9#ifndef lint
10static char rcsid_rvdutil_c[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/attach/rvdutil.c,v 1.5 1992-07-31 13:26:53 probe Exp $";
11#endif
12
13#include "attach.h"
14#ifdef RVD
15#include "rvdlib.h"
16#include <setjmp.h>
17#include <signal.h>
18
19int vdcntrl = -1;
20unsigned long rvderrno = 0;
21
22/*
23 * The RVD error list
24 */
25
26char *rvderlist[] = {
27/* 0 */ "No error",
28/* 1 */ "Non-existent drive",
29/* 2 */ "Bad password for mode",
30/* 3 */ "Already open in a different mode",
31/* 4 */ "Invalid Checksum",
32/* 5 */ "Index correction",
33/* 6 */ "Non-existant disk-pack",
34/* 7 */ "Drive already spun up",
35/* 8 */ "Bad mode",
36/* 9 */ "Unknown packet type",
37/* 10 */ "Non Active Host",
38/* 11 */ "Pack already spun up in EXCLUSIVE mode",
39/* 12 */ "Zero blocks requested",
40/* 13 */ "Too many blocks requested",
41/* 14 */ "Pack not physically mounted",
42/* 15 */ "Too many connections for server to support",
43/* 16 */ "Too many connections for this host",
44/* 17 */ "Server not currently active",
45/* 18 */ "Identical pack already spun up in this drive, in the requested mode",
46/* 19 */ "Physical device disused.",
47/* 20 */ "Temporarily bad mode",
48/* 21-30 */ "", "", "", "", "", "", "", "", "", "",
49/* 31-40 */ "", "", "", "", "", "", "", "", "", "",
50/* 41-51 */ "", "", "", "", "", "", "", "", "", "", "",
51/* 52 */ "Timeout",
52/* 53 */ "Invalid version",
53NULL
54};
55
56static jmp_buf rvd_timeout;
57
58static int rvd_timedout()
59{
60        longjmp(rvd_timeout,1);
61}
62
63/*
64 * Open the RVD control device
65 */
66
67rvd_open()
68{
69    if (vdcntrl >= 0)
70        return;
71    vdcntrl = open(VDCONTROL, O_RDONLY, 0);
72    if (vdcntrl < 0) {
73            fprintf(stderr, "Can't open RVD control device\n");
74            exit(ERR_FATAL);
75    }
76}
77
78/*
79 * Return an RVD error message
80 */
81
82char *rvd_error(n)
83    unsigned int n;
84{
85    return (rvderlist[n]);
86}
87
88/*
89 * Find a drive which already has the proper pack spunup on it, or the
90 * first available drive.  If the pack had already been spunup, spin it
91 * down and return that drive number.
92 */
93
94avail_drive(hostaddr, pack, drive)
95    struct in_addr hostaddr;
96    char *pack;
97    int *drive;
98{
99    int i;
100    struct vd_longstat lstats;
101    struct vd_longstat *stats = &lstats;
102    struct vd_long_dev *drives, *d;
103
104    rvd_open();
105   
106    if (ioctl(vdcntrl, VDIOCGETSTAT, &stats) < 0) {
107            fprintf(stderr, "Can't perform VDIOCGETSTAT for RVD\n");
108            exit(ERR_FATAL);
109    }
110
111    if (!(drives = (struct vd_long_dev *)malloc(lstats.num_drives*
112                                                sizeof(struct vd_long_dev)))) {
113            fprintf(stderr, "Can't malloc rvd information table.\n");
114            exit(ERR_FATAL);
115    }
116    if (ioctl(vdcntrl, VDIOCGETDRIVE, &drives) < 0) {
117            fprintf(stderr, "Can't perform VDIOCGETDRIVE for RVD\n");
118            exit(ERR_FATAL);
119    }
120    for (i=0, d=drives; i < lstats.num_drives; i++, d++) {
121        if (!strncmp(d->args.name, pack, VD_NAME_LEN) &&
122            d->vd_device.server.s_addr == hostaddr.s_addr) {
123            if (debug_flag)
124                printf("Found RVD spunup on drive %d!\n", i);
125            rvd_spindown(i);
126            *drive = i;
127            return (SUCCESS);
128        }
129    }
130    for (i=0, d=drives; i < lstats.num_drives; i++, d++) {
131        if (d->vd_device.state == OFF ||
132            d->vd_device.state == UNUSED) {
133            *drive = i;
134            return (SUCCESS);
135        }
136    }
137    return (FAILURE);
138}
139
140/*
141 * Spindown a drive
142 */
143
144rvd_spindown(drive)
145    int drive;
146{
147    rvd_open();
148
149    if (debug_flag)
150            printf("Spinning down drive %d\n", drive);
151   
152    if (setjmp(rvd_timeout)) {
153            if (debug_flag)
154                    printf("rvd_spindown: timed out");
155            return(FAILURE);
156    }
157    signal(SIGALRM, rvd_timedout);
158    alarm(RVD_ATTACH_TIMEOUT);
159
160    /* XXX Error status? */
161    if (ioctl(vdcntrl, VDIOCSPINDOWN, &drive)) {
162            if (debug_flag)
163                    perror("ioctl: spindown:");
164            return(FAILURE);
165    }
166   
167    alarm(0);
168    return(SUCCESS);
169}
170
171/*
172 * Spinup a drive
173 */
174
175rvd_spinup(server, pack, drive, mode, servername, pw)
176    struct in_addr server;
177    char *pack;
178    int drive;
179    char mode;
180    char *servername;
181    char *pw;
182{
183    struct vd_spinup vd_spinup;
184    struct spinargs sargs;
185    struct sockaddr_in sin;
186    u_short rvdmode;
187#ifdef KERBEROS
188    extern char *krb_realmofhost();
189#endif
190
191    if (debug_flag)
192        printf("Spinning up pack %s from %s on drive %d\n",
193               pack, servername, drive);
194   
195    rvd_open();
196   
197    if (setjmp(rvd_timeout)) {
198            if (debug_flag)
199                    printf("rvd_spinup: timed out");
200            alarm(0);
201            return(FAILURE);
202    }
203    signal(SIGALRM, rvd_timedout);
204    alarm(RVD_ATTACH_TIMEOUT);
205
206    errno = 0;
207
208    strncpy(sargs.name, pack, RVD_NAM);
209    if (pw)
210            strncpy(sargs.capab, pw, RVD_PW);
211    else
212            sargs.capab[0] = '\0';
213
214    if (mode == 'r')
215        rvdmode = RVDMRO;
216    else
217        rvdmode = RVDMEXC;
218   
219    /*
220     * First try a Kerberos authenticated spinup.  If
221     * it fails for any reason then try the regular spinup.
222     */
223#ifdef KERBEROS
224    while (1) {
225        int status;
226        KTEXT_ST authent;
227        struct vd_auth_spinup vd_auth_spinup;
228        register char *dot;
229        char *realm;
230
231        realm = krb_realmofhost(servername);
232        dot = index(servername, '.');
233        if (dot)
234            *dot = '\0';
235        status = krb_mk_req(&authent, "rvdsrv", servername, realm, NULL);
236        if (dot)
237            *dot = '.';
238        if (status != KSUCCESS)
239            break;
240        vd_auth_spinup.drive = drive;
241        vd_auth_spinup.uspin = &sargs;
242        vd_auth_spinup.mode = rvdmode;
243        sin.sin_family = AF_INET;
244        sin.sin_addr = server;
245        vd_auth_spinup.server = &sin;
246        vd_auth_spinup.errp = &rvderrno;
247        vd_auth_spinup.authent = &authent;
248
249        rvderrno = 0;
250        if (ioctl(vdcntrl, VDIOCAUTHSPINUP, &vd_auth_spinup) == 0) {
251            alarm(0);
252            return(SUCCESS);
253    }
254        if (debug_flag)
255            printf("Kerberos authenticated spinup failed\n");
256        break;
257    }
258#endif /* KERBEROS */
259
260    vd_spinup.drive = drive;
261    vd_spinup.mode = rvdmode;
262    sin.sin_family = AF_INET;
263    sin.sin_addr = server;
264    vd_spinup.server = &sin;
265    vd_spinup.uspin = &sargs;
266    vd_spinup.errp = &rvderrno;
267
268    errno = 0;
269    rvderrno = 0;
270    if (ioctl(vdcntrl, VDIOCSPINUP, &vd_spinup)) {
271            alarm(0);
272            return (FAILURE);
273    }
274    alarm(0);
275    if (errno || rvderrno)
276            return (FAILURE);
277    return (SUCCESS);
278}
279#endif
Note: See TracBrowser for help on using the repository browser.