1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
/*
* program putback
*
* puts back media in scsi-changer
*
* usage: /usr/sbin/putback
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/chio.h>
#define PROG "putback"
#define CHANGER "/dev/sch0"
#define DEBUG 0 /* set to 1 for debug output */
/* ---------------------------------------------------------------------- */
int main(int argc, char *argv[])
{
struct changer_params params;
struct changer_get_element *dt;
struct changer_move move;
char *h;
int fd,i,drive,cside;
if (argc != 1) {
fprintf(stderr,"Usage: %s\n",argv[0]);
exit(1);
}
if (-1 == (fd = open(CHANGER,O_RDONLY))) {
perror(PROG ": open " CHANGER);
exit(1);
}
/* read changer status information */
if (ioctl(fd,CHIOGPARAMS,¶ms)) {
perror(PROG ": ioctl CHIOGPARAMS");
exit(1);
}
#if DEBUG
fprintf(stderr,PROG ": %d drives, %d slots\n",
params.cp_ndrives,params.cp_nslots);
#endif
dt = malloc(sizeof(struct changer_get_element)*params.cp_ndrives);
for (i = 0; i < params.cp_ndrives; i++) {
dt[i].cge_type=CHET_DT;
dt[i].cge_unit=i;
if (ioctl(fd,CHIOGELEM,dt+i)) {
fprintf(stderr,PROG ":ioctl CHIOGELEM mt %d: %s\n",
i,strerror(errno));
exit(1);
}
if (NULL != (h = strchr(dt[i].cge_pvoltag,' '))) *h = '\0';
if (NULL != (h = strchr(dt[i].cge_avoltag,' '))) *h = '\0';
}
for (drive=0; drive<params.cp_ndrives; drive++) {
if (dt[drive].cge_status & CESTATUS_FULL) {
/* put back the old media ... */
if (!(dt[drive].cge_flags & CGE_SRC)) {
fprintf(stderr,PROG ": source element for drive %d unknown\n",
drive);
exit(1);
}
memset(&move,0,sizeof(struct changer_move));
move.cm_totype = dt[drive].cge_srctype;
move.cm_tounit = dt[drive].cge_srcunit;
move.cm_fromtype = CHET_DT;
move.cm_fromunit = drive;
cside = ((dt[drive].cge_flags & CGE_INVERT) == CGE_INVERT);
move.cm_flags = (cside == 0) ? 0 : CM_INVERT;
if (ioctl(fd,CHIOMOVE,&move)) {
fprintf(stderr,PROG ": ioctl MOVE (unload): %s\n",
sys_errlist[errno]);
exit(1);
}
}
}
exit(0);
}
|