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