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 if (errcnt++ >= errskip) return errcnt;
45 #define ERROR(S) { if (errbuf) strcpy(errbuf, (S)); RETERR }
46
47
48 /*
49 * To just check a job:
50 * rc = ndma_job_audit (job, 0, 0);
51 * if (rc) { "error" }
52 *
53 * To display everything wrong with a job:
54 * i = n_err = 0;
55 * do {
56 * n_err = ndma_job_audit (job, errbuf, i);
57 * if (n_err) display (errbuf);
58 * i++;
59 * } while (i < n_err);
60 *
61 * if (n_err) { "error" }
62 */
63
64 int
ndma_job_audit(struct ndm_job_param * job,char * errbuf,int errskip)65 ndma_job_audit (struct ndm_job_param *job, char *errbuf, int errskip)
66 {
67 int errcnt = 0;
68 char * audit_what;
69
70 switch (job->operation) {
71 default:
72 ERROR ("invalid operatiton")
73 return -1;
74
75 case NDM_JOB_OP_BACKUP: audit_what = "DfbBmM"; break;
76 case NDM_JOB_OP_EXTRACT: audit_what = "DfbBmM"; break;
77 case NDM_JOB_OP_TOC: audit_what = "DfbBmM"; break;
78 case NDM_JOB_OP_QUERY_AGENTS: audit_what = ""; break;
79 case NDM_JOB_OP_INIT_LABELS: audit_what = "TfmM"; break;
80 case NDM_JOB_OP_LIST_LABELS: audit_what = "TfM"; break;
81 case NDM_JOB_OP_REMEDY_ROBOT: audit_what = ""; break;
82 case NDM_JOB_OP_TEST_TAPE: audit_what = "TfM"; break;
83 case NDM_JOB_OP_TEST_MOVER: audit_what = "TfbM"; break;
84 case NDM_JOB_OP_TEST_DATA: audit_what = "DB"; break;
85 case NDM_JOB_OP_REWIND_TAPE: audit_what = "Tf"; break;
86 case NDM_JOB_OP_EJECT_TAPE: audit_what = "Tf"; break;
87 case NDM_JOB_OP_MOVE_TAPE: audit_what = "Rr@"; break;
88 case NDM_JOB_OP_IMPORT_TAPE: audit_what = "Rr@"; break;
89 case NDM_JOB_OP_EXPORT_TAPE: audit_what = "Rr@"; break;
90 case NDM_JOB_OP_LOAD_TAPE: audit_what = "Rr@"; break;
91 case NDM_JOB_OP_UNLOAD_TAPE: audit_what = "Rr"; break;
92 case NDM_JOB_OP_INIT_ELEM_STATUS: audit_what = "Rr"; break;
93 }
94
95 while (*audit_what) switch (*audit_what++) {
96 case 'D': /* DATA agent provided */
97 if (job->data_agent.conn_type == NDMCONN_TYPE_NONE)
98 ERROR("missing DATA agent")
99 break;
100
101 case 'T': /* TAPE agent provided (use DATA if given) */
102 if (job->data_agent.conn_type == NDMCONN_TYPE_NONE
103 && job->tape_agent.conn_type == NDMCONN_TYPE_NONE)
104 ERROR("missing TAPE or DATA agent")
105 break;
106
107 case 'R': /* ROBOT agent provided (use TAPE or DATA if given) */
108 if (job->data_agent.conn_type == NDMCONN_TYPE_NONE
109 && job->tape_agent.conn_type == NDMCONN_TYPE_NONE
110 && job->robot_agent.conn_type == NDMCONN_TYPE_NONE)
111 ERROR("missing ROBOT, TAPE or DATA agent")
112 break;
113
114 case 'B': /* Backup type */
115 if (!job->bu_type)
116 ERROR("missing bu_type")
117 break;
118
119 case 'b': /* block (record) size */
120 if (!job->record_size)
121 ERROR("missing record size")
122 break;
123
124 case 'f': /* tape file */
125 if (!job->tape_device)
126 ERROR("missing tape device")
127 break;
128
129 case 'm': /* media entry/ies */
130 if (job->media_tab.n_media < 1)
131 ERROR("missing media entry")
132 break;
133
134 case 'M': /* ? */
135 errcnt += ndma_job_media_audit (job, errbuf, errskip-errcnt);
136 break;
137
138 case 'r': /* robot file/device name */
139 if (!job->have_robot)
140 ERROR ("missing robot SCSI address");
141 break;
142
143 case '@': /* from and/or to address */
144 if (job->operation == NDM_JOB_OP_MOVE_TAPE
145 || job->operation == NDM_JOB_OP_EXPORT_TAPE
146 || job->operation == NDM_JOB_OP_LOAD_TAPE) {
147 if (!job->from_addr_given)
148 ERROR ("missing 'from' slot address");
149 }
150 if (job->operation == NDM_JOB_OP_MOVE_TAPE
151 || job->operation == NDM_JOB_OP_IMPORT_TAPE) {
152 if (!job->to_addr_given)
153 ERROR ("missing 'to' slot address");
154 }
155 break;
156
157 default:
158 ERROR ("INTERNAL BOTCH")
159 return -2;
160 }
161
162 if (job->robot_agent.conn_type != NDMCONN_TYPE_NONE
163 && !job->have_robot
164 && job->operation != NDM_JOB_OP_QUERY_AGENTS) {
165 ERROR ("robot agent, but no robot")
166 }
167
168 return errcnt;
169 }
170
171 int
ndma_job_media_audit(struct ndm_job_param * job,char * errbuf,int errskip)172 ndma_job_media_audit (struct ndm_job_param *job, char *errbuf, int errskip)
173 {
174 struct ndm_media_table *mtab = &job->media_tab;
175 int n_media = mtab->n_media;
176 struct ndmmedia * me;
177 struct ndmmedia * me2;
178 int errcnt = 0;
179 int i, j;
180
181 if (job->have_robot) {
182 for (i = 0; i < n_media; i++) {
183 me = &mtab->media[i];
184 if (!me->valid_slot) {
185 if (errbuf) {
186 sprintf (errbuf,
187 "media #%d missing slot address",
188 i+1);
189 }
190 RETERR
191 continue;
192 }
193 for (j = i+1; j < n_media; j++) {
194 me2 = &mtab->media[j];
195 if (! me2->valid_slot)
196 continue;
197 if (me->slot_addr == me2->slot_addr) {
198 if (errbuf) {
199 sprintf (errbuf,
200 "media #%d dup slot addr w/ #%d",
201 i+1, j+1);
202 }
203 RETERR
204 }
205 }
206 }
207 } else {
208 if (n_media > 1) {
209 ERROR ("no robot, too many media")
210 }
211
212 for (i = 0; i < n_media; i++) {
213 me = &mtab->media[i];
214 if (me->valid_slot) {
215 if (errbuf) {
216 sprintf (errbuf,
217 "media #%d slot address, but no robot",
218 i+1);
219 }
220 RETERR
221 }
222 }
223 }
224
225 if (job->operation == NDM_JOB_OP_INIT_LABELS) {
226 for (i = 0; i < n_media; i++) {
227 me = &mtab->media[i];
228 if (! me->valid_label) {
229 if (errbuf) {
230 sprintf (errbuf,
231 "media #%d missing label",
232 i+1);
233 }
234 RETERR
235 }
236 }
237 }
238
239 return 0;
240 }
241
242 void
ndma_job_auto_adjust(struct ndm_job_param * job)243 ndma_job_auto_adjust (struct ndm_job_param *job)
244 {
245 if (job->media_tab.n_media == 0
246 && !job->have_robot
247 && job->operation != NDM_JOB_OP_INIT_LABELS) {
248 /* synthesize one media table entry */
249 NDMOS_MACRO_ZEROFILL (&job->media_tab.media[0]);
250 job->media_tab.n_media = 1;
251 }
252 }
253
254 #endif /* !NDMOS_OPTION_NO_CONTROL_AGENT */
255