1 /*
2 * Copyright (c) 1998,1999,2000
3 * Traakan, Inc., Los Altos, CA
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * 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 AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 /*
30 * Project: NDMJOB
31 * Ident: $Id: $
32 *
33 * Description:
34 *
35 */
36
37
38 #include "ndmagents.h"
39
40
41 #ifndef NDMOS_OPTION_NO_CONTROL_AGENT
42
43
44 #define RETERR \
45 if (errcnt++ >= errskip) return errcnt;
46 #define ERROR(S) \
47 { \
48 if (errbuf) strcpy(errbuf, (S)); \
49 RETERR \
50 }
51
52
53 /*
54 * To just check a job:
55 * rc = ndma_job_audit (job, 0, 0);
56 * if (rc) { "error" }
57 *
58 * To display everything wrong with a job:
59 * i = n_err = 0;
60 * do {
61 * n_err = ndma_job_audit (job, errbuf, i);
62 * if (n_err) display (errbuf);
63 * i++;
64 * } while (i < n_err);
65 *
66 * if (n_err) { "error" }
67 */
68
ndma_job_audit(struct ndm_job_param * job,char * errbuf,int errskip)69 int ndma_job_audit(struct ndm_job_param* job, char* errbuf, int errskip)
70 {
71 int errcnt = 0;
72 char* audit_what;
73
74 switch (job->operation) {
75 default:
76 ERROR("invalid operation")
77 return -1;
78
79 case NDM_JOB_OP_BACKUP:
80 audit_what = "DfbBmM";
81 break;
82 case NDM_JOB_OP_EXTRACT:
83 audit_what = "DfbBmM";
84 break;
85 case NDM_JOB_OP_TOC:
86 audit_what = "DfbBmM";
87 break;
88 case NDM_JOB_OP_QUERY_AGENTS:
89 audit_what = "";
90 break;
91 case NDM_JOB_OP_INIT_LABELS:
92 audit_what = "TfmM";
93 break;
94 case NDM_JOB_OP_LIST_LABELS:
95 audit_what = "TfM";
96 break;
97 case NDM_JOB_OP_REMEDY_ROBOT:
98 audit_what = "";
99 break;
100 case NDM_JOB_OP_TEST_TAPE:
101 audit_what = "TfM";
102 break;
103 case NDM_JOB_OP_TEST_MOVER:
104 audit_what = "TfbM";
105 break;
106 case NDM_JOB_OP_TEST_DATA:
107 audit_what = "DB";
108 break;
109 case NDM_JOB_OP_REWIND_TAPE:
110 audit_what = "Tf";
111 break;
112 case NDM_JOB_OP_EJECT_TAPE:
113 audit_what = "Tf";
114 break;
115 case NDM_JOB_OP_MOVE_TAPE:
116 audit_what = "Rr@";
117 break;
118 case NDM_JOB_OP_IMPORT_TAPE:
119 audit_what = "Rr@";
120 break;
121 case NDM_JOB_OP_EXPORT_TAPE:
122 audit_what = "Rr@";
123 break;
124 case NDM_JOB_OP_LOAD_TAPE:
125 audit_what = "Rr@";
126 break;
127 case NDM_JOB_OP_UNLOAD_TAPE:
128 audit_what = "Rr";
129 break;
130 case NDM_JOB_OP_INIT_ELEM_STATUS:
131 audit_what = "Rr";
132 break;
133 }
134
135 while (*audit_what) switch (*audit_what++) {
136 case 'D': /* DATA agent provided */
137 if (job->data_agent.conn_type == NDMCONN_TYPE_NONE)
138 ERROR("missing DATA agent")
139 break;
140
141 case 'T': /* TAPE agent provided (use DATA if given) */
142 if (job->data_agent.conn_type == NDMCONN_TYPE_NONE &&
143 job->tape_agent.conn_type == NDMCONN_TYPE_NONE)
144 ERROR("missing TAPE or DATA agent")
145 break;
146
147 case 'R': /* ROBOT agent provided (use TAPE or DATA if given) */
148 if (job->data_agent.conn_type == NDMCONN_TYPE_NONE &&
149 job->tape_agent.conn_type == NDMCONN_TYPE_NONE &&
150 job->robot_agent.conn_type == NDMCONN_TYPE_NONE)
151 ERROR("missing ROBOT, TAPE or DATA agent")
152 break;
153
154 case 'B': /* Backup type */
155 if (!job->bu_type) ERROR("missing bu_type")
156 break;
157
158 case 'b': /* block (record) size */
159 if (!job->record_size) ERROR("missing record size")
160 break;
161
162 case 'f': /* tape file */
163 if (!job->tape_device) ERROR("missing tape device")
164 break;
165
166 case 'm': /* media entry/ies */
167 if (job->media_tab.n_media < 1) ERROR("missing media entry")
168 break;
169
170 case 'M': /* ? */
171 errcnt += ndma_job_media_audit(job, errbuf, errskip - errcnt);
172 break;
173
174 case 'r': /* robot file/device name */
175 if (!job->have_robot) ERROR("missing robot SCSI address");
176 break;
177
178 case '@': /* from and/or to address */
179 if (job->operation == NDM_JOB_OP_MOVE_TAPE ||
180 job->operation == NDM_JOB_OP_EXPORT_TAPE ||
181 job->operation == NDM_JOB_OP_LOAD_TAPE) {
182 if (!job->from_addr_given) ERROR("missing 'from' slot address");
183 }
184 if (job->operation == NDM_JOB_OP_MOVE_TAPE ||
185 job->operation == NDM_JOB_OP_IMPORT_TAPE) {
186 if (!job->to_addr_given) ERROR("missing 'to' slot address");
187 }
188 break;
189
190 default:
191 ERROR("INTERNAL BOTCH")
192 return -2;
193 }
194
195 if (job->robot_agent.conn_type != NDMCONN_TYPE_NONE && !job->have_robot &&
196 job->operation != NDM_JOB_OP_QUERY_AGENTS) {
197 ERROR("robot agent, but no robot")
198 }
199
200 return errcnt;
201 }
202
ndma_job_media_audit(struct ndm_job_param * job,char * errbuf,int errskip)203 int ndma_job_media_audit(struct ndm_job_param* job, char* errbuf, int errskip)
204 {
205 struct ndm_media_table* mtab = &job->media_tab;
206 int n_media = mtab->n_media;
207 struct ndmmedia* me;
208 struct ndmmedia* me2;
209 int errcnt = 0;
210
211 if (job->have_robot) {
212 for (me = mtab->head; me; me = me->next) {
213 if (!me->valid_slot) {
214 if (errbuf) {
215 sprintf(errbuf, "media #%d missing slot address", me->index);
216 }
217 RETERR
218 continue;
219 }
220 for (me2 = me->next; me2; me2 = me2->next) {
221 if (!me2->valid_slot) continue;
222 if (me->slot_addr == me2->slot_addr) {
223 if (errbuf) {
224 sprintf(errbuf, "media #%d dup slot addr w/ #%d", me->index,
225 me2->index);
226 }
227 RETERR
228 }
229 }
230 }
231 } else {
232 if (n_media > 1) { ERROR("no robot, too many media") }
233
234 for (me = mtab->head; me; me = me->next) {
235 if (me->valid_slot) {
236 if (errbuf) {
237 sprintf(errbuf, "media #%d slot address, but no robot", me->index);
238 }
239 RETERR
240 }
241 }
242 }
243
244 if (job->operation == NDM_JOB_OP_INIT_LABELS) {
245 for (me = mtab->head; me; me = me->next) {
246 if (!me->valid_label) {
247 if (errbuf) { sprintf(errbuf, "media #%d missing label", me->index); }
248 RETERR
249 }
250 }
251 }
252
253 return 0;
254 }
255
ndma_job_auto_adjust(struct ndm_job_param * job)256 void ndma_job_auto_adjust(struct ndm_job_param* job)
257 {
258 struct ndmmedia* me;
259
260 if (job->media_tab.n_media == 0 && !job->have_robot &&
261 job->operation != NDM_JOB_OP_INIT_LABELS) {
262 /* synthesize one media table entry */
263
264 me = ndma_store_media(&job->media_tab, 0);
265 if (me) {
266 /* As this is a fake media entry set valid_slot to 0 */
267 me->valid_slot = 0;
268 }
269 }
270 }
271
272 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
273