0707070035050375121006660011710000040000010653710464714144700000700000003143README This is a simple extensible shell (scsish) for poking at scsi
devices, particularly the simpler kinds commonly called toasters.
it is supposed to be self-documenting in use; try the help command.
my use of the moran-dronek /dev/scsi library is still imperfect;
there is still some some debugging showing.
To compile, you first need mk. you then have to pick a system type
to set some flags; currently we support research and sgi.
yours may differ, particularly as no one else has our ansi C compiler for the sgi.
the only problem i would expect is the normal header file crap you get
mixing ansi and non-ansi files. i recommend setting NPROC=1 while debugging hdr files.
if you change (header) files, try putting them in the directory inc
(then others may benefit). To support a new system (say sgi-gcc), just create
a new file sgi-gcc.mk and so on. you may be missing some devices in
your /dev/scsi; the script scsi/gendev may help (but check the major/minor
numbers and permissions).
As for modifying/extending scsish, it has been designed to be not too hard.
Adding a new device means adding a new set of rules (like the other rules)
to mkfile and creating a new directory (say exabyte) and at least two files in it
(dev.c and fns.h). The wren directory is a small example you can clone.
Adding new functions to any device means updating a file list in mkfile,
updating dev.c and fns.h in the device directory. The argument syntax
scheme is arguably pokey, but liveable. at some future point we should probably
switch over to osterhout's tcl.
as always, i invite you send extensions/fixes etc back to
[email protected]
0707070035050375111006660011710000040000010653730457563432000000500000000565TODO | COPY drive NUMBER NUMBER drive NUMBER {/*:COPY sdrive sstart nblocks ddrive dstart:: */
s_copy($2, $3, $4, $5, $6);
}
| READ drive NUMBER {
struct scsi_ret output;
s_read($2, $3, 1, &output);
scsiodump(output.data, 1024);
}
| WRITE drive NUMBER { s_write($2, $3, 1); }
| WRITE drive NUMBER NUMBER { s_write($2, $3, $4); } /*:WRITE drive start n:: */
0707070035050406411006660011710000040000010511250474377127600001300000002245allocate.c #define _POSIX_SOURCE
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include "jukeface.h"
#include "jukebox.h"
allocate(Jukebox *j, char *vol_id, char *buf)
{
int drive, sh;
char nbuf[512];
if(j_rdshelves(j, buf)) /* read in shelf names */
return(-1);
if(j_shstatus(j, buf)) /* get the jukebox status */
return(-1);
sh = j_shelfof(j, vol_id);
if(sh >= 0){
sprintf(buf, "there is an existing '%s' on shelf %d", vol_id, sh);
return(-1);
}
sh = j_shelfof(j, UNALLOCATED);
if(sh < 0){
sprintf(buf, "no unallocated disks");
return(-1);
}
printf("using unallocated disk from shelf %d\n", sh);
drive = j->nluns-1;
if(j_sh_to_dr(sh, SIDEB, drive, buf) < 0)
return(-1);
sprintf(nbuf, "%sb", vol_id);
if(j_wvolid(drive, nbuf, buf))
return(-1);
j_wrshelf = 1;
j->names[sh] = strdup(vol_id);
j->shelves[sh] = 1;
if(j_dr_to_sh(drive, sh, SIDEB, buf) < 0)
return(-1);
if(j_sh_to_dr(sh, SIDEA, drive, buf) < 0)
return(-1);
sprintf(nbuf, "%sa", vol_id);
if(j_wvolid(drive, nbuf, buf))
return(-1);
if(j_dr_to_sh(drive, sh, SIDEA, buf) < 0)
return(-1);
return(0);
}
0707070035050550721006660011710000040000011772350474343203100000600000000761arg.h /*
* argument processing
*/
#define ARGBEGIN for((argv0? 0: (argv0=*argv)),argv++,argc--;\
argv[0] && argv[0][0]=='-' && argv[0][1];\
argc--, argv++) {\
char *_args, *_argt, _argc;\
_args = &argv[0][1];\
if(_args[0]=='-' && _args[1]==0){\
argc--; argv++; break;\
}\
while(*_args) switch(_argc=*_args++)
#define ARGEND }
#define ARGF() (_argt=_args, _args="",\
(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
#define ARGC() _argc
extern char *argv0;
0707070035050554471006660011710000040000010651520467171415300000400000000120c.c typedef int (*fn)(struct x *);
extern int fn1(struct x *);
extern fn *fp = fn1;
0707070035050421771006660011710000040000010011270477113511400000700000011124cold.c #define _POSIX_SOURCE
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "jukeface.h"
#include "jukebox.h"
#include "tcl.h"
#include "generic/fns.h"
static sort(char *buf);
j_cold(Jukebox *j, char *type, char *err)
{
int side;
int drive, sh, nsh;
int n;
char vol_id[512];
char *didit;
if(j_drstatus(j, err))
return(-1);
printf("drstatus done\n");
if(j_shstatus(j, err))
return(-1);
printf("shstatus done\n");
/* first clear out nonexistent labels */
n = 0;
didit = (char *)malloc(j->nshelves*sizeof(char));
for(sh = 0; sh < j->nshelves; sh++){
if(j->shelves[sh]){
n++;
j->names[sh] = "there";
} else
j->names[sh] = 0;
didit[sh] = 0;
}
printf("%d disks in shelves.\n", n);
/* second, clear the drives */
for(sh = 0; sh < j->nshelves; sh++)
if(j->shelves[sh] == 0)
break;
for(drive = 0; drive < j->nluns; drive++){
if(!j->luns[drive].occupied)
continue; /* no disk in drive */
printf("clearing drive %d:\n", drive);
if(j->luns[drive].shelf < 0){
if(j_dr_to_sh(drive, sh, SIDEA, err))
return(-1);
for(sh++; sh < j->nshelves; sh++)
if(j->shelves[sh] == 0)
break;
n++;
} else
if(j_dr_to_sh(drive, -1, SIDEA, err))
return(-1);
}
if(isdigit(*type)){ /* just do one shelf */
sh = atol(type);
printf("single shelf %d reload\n", sh);
if(j_rdshelves(j, err))
return(-1);
if(getvol(sh, drive, vol_id, &side)){
strcpy(err, vol_id);
return(-1);
}
printf("%s@%d -> %d\n", vol_id, sh, sh);
if(j_dr_to_sh(drive, -1, side, err) < 0)
return(-1);
j->names[sh] = strdup(vol_id);
j->shelves[sh] = 1;
j_wrshelf = 1;
return(0);
}
printf("reloading %d disks.\n", n);
side = SIDEA;
drive = j->nluns-1;
j_wrshelf = 1;
for(sh = 0; sh < j->nshelves; sh++){
if(didit[sh])
continue;
j->names[sh] = 0;
if(j->shelves[sh]){
printf("%d: ", sh); fflush(stdout);
if(getvol(sh, drive, vol_id, &side)){
strcpy(err, vol_id);
return(-1);
}
j->shelves[sh] = 0;
switch(*type)
{
case 'c':
for(nsh = 0; j->shelves[nsh]; nsh++)
;
break;
case 's':
case 'r':
while(j->shelves[nsh = nrand(j->nshelves)])
;
break;
case 'u':
default:
nsh = sh;
break;
}
printf("%s@%d -> %d\n", vol_id, sh, nsh);
if(j_dr_to_sh(drive, nsh, side, err) < 0)
return(-1);
j->names[nsh] = strdup(vol_id);
j->shelves[nsh] = 1;
didit[nsh] = 1;
sleep(5);
}
}
printf("process any new disks.\n");
if(j_warm(j, err))
return(-1);
/* if(type == 's')
return(sort(err));
*/
return(0);
}
getvol(int sh, int drive, char *vol_id, int *side)
{
int i;
char buf[512];
if(j_sh_to_dr(sh, SIDEA, drive, vol_id) < 0)
return(-1);
if((i = j_rvolid(drive, buf)) < 0)
goto softerr;
if(i == 0)
*side = SIDEA;
else {
*side = SIDEB;
if(j_dr_to_sh(drive, sh, SIDEA, vol_id) < 0)
return(-1);
if(j_sh_to_dr(sh, SIDEB, drive, vol_id) < 0)
return(-1);
if((i = j_rvolid(drive, buf)) < 0)
goto softerr;
}
if(i > 0)
strcpy(vol_id, UNALLOCATED);
else {
strcpy(vol_id, buf);
i = strlen(vol_id)-1;
if(i < 0){
sprintf(buf, "apparently good superblock but null vol_id");
goto softerr;
} else if(vol_id[i] == 'a')
vol_id[i] = 0;
else if(vol_id[i] == 'b'){
vol_id[i] = 0;
*side = !*side;
} else {
sprintf(buf, "vol_id '%s' must end in a or b", vol_id);
strcpy(vol_id, buf);
return(-1);
}
}
return(0);
softerr:
*side = SIDEA;
fprintf(stderr, "error in reading shelf %d: %s; proceeding\n", sh, buf);
sprintf(vol_id, "DISK_ERROR%d", sh);
j_reset();
return(0);
}
#ifdef CRAP
static int index[j->nshelves];
static
cmp(int *a, int *b)
{
char *sa = j->shelves[*a], *sb = j->shelves[*b];
if((sa == 0) && (sb == 0)) return(0);
if(sa == 0) return(-1);
if(sb == 0) return(1);
return(strcmp(sa, sb));
}
static char *disk[8];
static
sd(int a, int b, char *err)
{
disk[b] = j->shelves[a];
return(j->shelves_to_drive(a, SIDEB, b, err));
}
static
ds(int a, int b, char *err)
{
j->shelves[b] = disk[a];
return(j_drive_to_shelf(a, b, SIDEB, err));
}
static
sort(char *errbuf)
{
int i, j, org;
for(i = 0; i < j->nshelves; i++)
index[i] = i;
qsort(index, j->nshelves, sizeof index[0], cmp);
for(i = 0; i < j->nshelves; i++){
if(index[i] < 0) continue;
if(sd(org = i, NLUN-1, errbuf) < 0)
return(-1);
j = index[i];
index[i] = -1;
while(j != org){
if(sd(j, NLUN-2, errbuf) < 0)
return(-1);
if(ds(NLUN-2, i, errbuf) < 0)
return(-1);
i = j;
if(index[i] < 0)
break;
j = index[i];
index[i] = -1;
}
if(ds(NLUN-1, i, errbuf) < 0)
return(-1);
}
return(0);
}
#endif
0707070035050554431006660011710000040000010134650474362344500000500000106000core �������������� �� L����� ���� �{���������d8À � �
��� �� �l� + 0u ���]�� y y ���������������������������������������������������������������� ��x�� Y �� 0�� ������������ Y �6 � �����H��0��0��� � @
� $ 4 0� jukebox %'�' t 6 4 � � 6 ` �* 6 6 ������ @ @ ��� �_ andrew ��� ,���������҃�� ,��������� �����H��: � ,���h������ �� r ,�� : *���+ %'�'�' �' ���҃�r "3��� � �/ ������ E � X /�������C � � �������D � 9 �/(���� .,����
~ � � ��� ��� ( �/t��X���z � � �� .� .�������5 � � @�� .� 9 E��� �/������l������ @�� @�� (x��`�����@�� @���� ���� : yY�6Y t 6 ��? ��� ��� � (������}���� .������������ �% �/������4 � Y ������� ��
���, % � ���� ���� � � � } x } } } f } P } ; } } } �! �! �! �! �! �! �! �! �! k! ^! N! H! 8! -! ! J, R. / r1 :5 67 N9 <! <! <! <! 8 8 8 8 ���� ����k�������� �<