Imported Upstream version 3.3.2
[debian/amanda] / ndmp-src / ndmos.h
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  *      This is the #include file for the Operating System
36  *      (O/S) specific portion of the NDMJOBLIB library.
37  *      By O/S we mean the programming environment including
38  *      compilers, header files, as well the host O/S APIs.
39  *      O/S specific is clear and concise, so that's how we refer
40  *      to the hosting environment.
41  *
42  *      This file, ndmos.h, essentially #include's the right
43  *      ndmos_xxx.h for the hosting environment. The companion
44  *      source C files, ndmos_xxx*.c, are similarly selected by
45  *      ndmos.c.
46  *
47  *        (hacked in Amanda to just #include ndmos_glib.h and then follow up
48  *        with the usual defaults)
49  *
50  *      The strategy for separating the O/S specific and O/S
51  *      generic portions of NDMJOBLIB has four key points:
52  *
53  *        1) Isolate O/S specific portions in separate
54  *           files which can be developed, contributed,
55  *           and maintained independently of the overall
56  *           source base.
57  *
58  *        2) NEVER NEVER #ifdef based on O/S or programming
59  *           environment in the O/S generic portions. These
60  *           make collective maintenance and integration
61  *           too difficult.
62  *
63  *        3) Use O/S specific #define macros (NDMOS_...)
64  *           and C functions (ndmos_...) as wrappers around
65  *           the portions that vary between environments
66  *           and applications.
67  *
68  *        4) Use generic, objective-oriented #ifdef's to isolate
69  *           and omit functionality which may not be wanted in
70  *           all applications.
71  *
72  *      There are templates in ndmos_xxx.h and ndmos_xxx.c
73  *      to get started on a new O/S specific portion.
74  *      Send contributions to the current keeper of NDMJOB.
75  *      Contact ndmp-tech@ndmp.org for details.
76  *
77  *      >>>  DO NOT MODIFY THIS FILE OR ANY GENERIC  <<<
78  *      >>>  PORTION OF NDMJOBLIB FOR THE SAKE OF A  <<<
79  *      >>>  HOSTING ENVIRONMENT OR APPLICATION.     <<<
80  *
81  *      If you discover additional isolation requirements,
82  *      raise the issue on ndmp-tech@ndmp.org. Propose new
83  *      #define NDMOS_ macros to address them. Then, submit
84  *      the proposal with required changes to the current
85  *      keeper of NDMJOB. Changes to the generic portion which
86  *      use #ifdef's based on anything other than NDMOS_
87  *      macros will be summarily rejected.
88  *
89  *      There are four sections of this file:
90  *        1) Establish identities for various O/S platforms
91  *        2) Try to auto-recognize the environment
92  *        3) #include the right O/S specific ndmos_xxx.h
93  *        4) Establish default #define-itions for macros
94  *           left undefined
95  */
96
97
98 #ifndef _NDMOS_H
99 #define _NDMOS_H
100
101 /* set up the appropriate macros for use in various version-printing
102  * functions */
103 #define NDMOS_IDENT(A,B,C,D)   (((A)<<24)+((B)<<16)+((C)<<8)+(D))
104 #define NDMOS_ID_GLIB          NDMOS_IDENT('G','l','i','b')
105 #define NDMOS_ID NDMOS_ID_GLIB
106
107 /* unconditionally include ndmos_glib.h */
108 #include "ndmos_glib.h"
109
110 /*
111  * From here down, pre-processor symbols are #define'd to defaults
112  * if not already #define'd in the O/S specific header file.
113  *
114  * Application Program Interfaces (APIs). The macros give the
115  * O/S specific header a chance to use casts or different functions.
116  *
117  * NDMOS_API_BCOPY              -- memory copy
118  * NDMOS_API_BZERO              -- zero-fill memory
119  * NDMOS_API_MALLOC             -- memory allocator, no initialization
120  * NDMOS_API_FREE               -- memory deallocator
121  * NDMOS_API_STRTOLL            -- convert strings to long long
122  * NDMOS_API_STRDUP             -- malloc() and strcpy()
123  * NDMOS_API_STREND             -- return pointer to end of string
124  *
125  * Important constants that sometimes vary between O/S's.
126  *
127  * NDMOS_CONST_ALIGN            -- alignment for memory allocation
128  * NDMOS_CONST_EWOULDBLOCK      -- errno when async I/O would stall
129  * NDMOS_CONST_TAPE_REC_MAX     -- maximum tape record length
130  * NDMOS_CONST_TAPE_REC_MIN     -- minimum tape record length
131  * NDMOS_CONST_PATH_MAX         -- maximum path name length
132  * NDMOS_CONST_NDMJOBLIB_REVISION -- String for in-house change level
133  *                                 Convention "0" if no changes
134  *                                 from released source. If changes,
135  *                                 the initials of local keeper with
136  *                                 sequence number or date code.
137  * NDMOS_CONST_VENDOR_NAME      -- String for server_info_reply.vendor_name
138  * NDMOS_CONST_PRODUCT_NAME     -- String for server_info_reply.product_name
139  * NDMOS_CONST_PRODUCT_REVISION -- String for product change level
140  *                                 By "product" we mean the program
141  *                                 enclosing this NDMJOBLIB library.
142  * NDMOS_CONST_NDMOS_REVISION   -- String for ndmos_xxx change level
143  *
144  * Macros for certain small operations which can vary.
145  *
146  * NDMOS_MACRO_NEW              -- allocate a data structure, wrapper
147  *                                 around NDMOS_API_MALLOC() with casts
148  * NDMOS_MACRO_NEWN             -- allocate a vector of data structs
149  * NDMOS_MACRO_ZEROFILL         -- zero-fill data structure, wrapper
150  *                                 around NDMOS_API_BZERO()
151  * NDMOS_MACRO_SRAND            -- wrapper around srand(3), for MD5
152  * NDMOS_MACRO_RAND             -- wrapper around rand(3), for MD5
153  * NDMOS_MACRO_OK_TAPE_REC_LEN  -- Uses NDMOS_CONST_TAPE_REC_MIN/MAX
154  * NDMOS_MACRO_SET_SOCKADDR     -- Sets struct sockaddr_in with
155  *                                 respect to NDMOS_OPTION_HAVE_SIN_LEN
156  *
157  * The NDMOS_MACRO_xxx_ADDITIONS macros allow additional O/S
158  * specific members to key structures in ndmagents.h
159  *
160  * NDMOS_MACRO_CONTROL_AGENT_ADDITIONS  -- struct ndm_control_agent
161  * NDMOS_MACRO_DATA_AGENT_ADDITIONS     -- struct ndm_data_agent
162  * NDMOS_MACRO_ROBOT_AGENT_ADDITIONS    -- struct ndm_robot_agent
163  * NDMOS_MACRO_SESSION_ADDITIONS        -- struct ndm_session
164  * NDMOS_MACRO_TAPE_AGENT_ADDITIONS     -- struct ndm_tape_agent
165  *
166  * All NDMOS_OPTION_... parameters are either #define'd or #undef'ed.
167  * They are solely interpretted in #ifdef's and #ifndef's, and the
168  * value of the definition means nothing. These _OPTIONS_'s can be set
169  * on the command line (-D) in the Makefile, or in the O/S specific
170  * header file.
171  *
172  * NDMOS_OPTION_NO_NDMP2        -- omit NDMPv2 support
173  * NDMOS_OPTION_NO_NDMP3        -- omit NDMPv3 support
174  * NDMOS_OPTION_NO_NDMP4        -- omit NDMPv4 support
175  *
176  * NDMOS_OPTION_NO_CONTROL_AGENT -- omit CONTROL agent features
177  * NDMOS_OPTION_NO_DATA_AGENT   -- omit DATA agent features
178  * NDMOS_OPTION_NO_ROBOT_AGENT  -- omit ROBOT agent features
179  * NDMOS_OPTION_NO_TAPE_AGENT   -- omit TAPE agent features
180  *      For some purposes, an all-in-one is overkill, or perhaps
181  *      impractical. Everything is carefully constructed so
182  *      that certain agents can be omitted without disturbing
183  *      the rest. The two most obvious uses are to either
184  *      keep or omit just the CONTROL agent.
185  *
186  * NDMOS_OPTION_ALLOW_SCSI_AND_TAPE_BOTH_OPEN
187  *      The NDMP specification says that both TAPE and SCSI can not
188  *      be open at the same time. Then the workflow docs suggest
189  *      a separate process for the ROBOT agent to get around the
190  *      restriction. #define'ing this breaks the spec and allows
191  *      both to be open.
192  *
193  * NDMOS_OPTION_HAVE_SIN_LEN
194  *      In preparation for IPv6, some O/Ss use a sin_len field to
195  *      indicate the length of the address. This _OPTION_ affects
196  *      the standard NDMOS_MACRO_SET_SOCKADDR.
197  *
198  * NDMOS_OPTION_TAPE_SIMULATOR
199  *      Early in bring-up on a new system, it's a little easier to
200  *      get started by using the tape simulator. It represents
201  *      an idealized MTIO-type tape subsystem, and uses a disk
202  *      file to represent the tape. As the real O/S specific tape
203  *      subsystem interface is implemented (ndmos_tape_...()), the
204  *      tape simulator serves as a reference for correct implementation.
205  *
206  * NDMOS_OPTION_ROBOT_SIMULATOR
207  *      Similarly, for testing multi-tape operations, it's easier to
208  *      get started by using the robot simulator. It represents a simple
209  *      robot with ten slots and two drives.  It operates on a directory,
210  *      and uses rename() to load and unload tapes.  It operates in concert
211  *      with the tape simulator.  The robot name is a directory, and it
212  *      creates drives named 'drive0', 'drive1', etc. in that directory
213  *
214  * NDMOS_OPTION_USE_SELECT_FOR_CHAN_POLL -- use common poll() code
215  * NDMOS_OPTION_USE_POLL_FOR_CHAN_POLL   -- use common select() code
216  *      These two _OPTION_'s choose common code to implement
217  *      ndmos_chan_poll(). The select() and poll() functions are
218  *      fairly common and consistent among various O/S's to detect
219  *      ready I/O. Only one can be defined. If the common code
220  *      doesn't work out, don't define either _OPTION_ and implement
221  *      ndmos_chan_poll() in the O/S specific C source file.
222  */
223
224 /*
225  * Constants
226  */
227 #ifndef NDMOS_CONST_ALIGN
228 #define NDMOS_CONST_ALIGN               sizeof(unsigned long long)
229 #endif /* !NDMOS_CONST_ALIGN */
230
231 #ifndef NDMOS_CONST_TAPE_REC_MIN
232 #define NDMOS_CONST_TAPE_REC_MIN        1
233 #endif /* !NDMOS_CONST_TAPE_REC_MIN */
234
235 #ifndef NDMOS_CONST_TAPE_REC_MAX
236 #define NDMOS_CONST_TAPE_REC_MAX        (256*1024)
237 #endif /* !NDMOS_CONST_TAPE_REC_MAX */
238
239 #ifndef NDMOS_CONST_PATH_MAX
240 #define NDMOS_CONST_PATH_MAX            (1024)
241 #endif /* !NDMOS_CONST_PATH_MAX */
242
243 #ifndef NDMOS_CONST_EWOULDBLOCK
244 #ifdef EWOULDBLOCK
245 #define NDMOS_CONST_EWOULDBLOCK         EWOULDBLOCK
246 #else /* EWOULDBLOCK */
247 #define NDMOS_CONST_EWOULDBLOCK         EAGAIN
248 #endif /* EWOULDBLOCK */
249 #endif /* !NDMOS_CONST_EWOULDBLOCK */
250
251 #ifndef NDMOS_CONST_NDMJOBLIB_REVISION
252 #define NDMOS_CONST_NDMJOBLIB_REVISION "1.4a"
253 #endif /* !NDMOS_CONST_NDMJOBLIB_REVISION */
254
255 #ifndef NDMOS_CONST_VENDOR_NAME
256 #define NDMOS_CONST_VENDOR_NAME "PublicDomain"
257 #endif /* !NDMOS_CONST_VENDOR_NAME */
258
259 #ifndef NDMOS_CONST_PRODUCT_NAME
260 #define NDMOS_CONST_PRODUCT_NAME "NDMJOB"
261 #endif /* !NDMOS_CONST_PRODUCT_NAME */
262
263 #ifndef NDMOS_CONST_PRODUCT_REVISION
264 #define NDMOS_CONST_PRODUCT_REVISION "1.4a"
265 #endif /* !NDMOS_CONST_PRODUCT_REVISION */
266
267 #ifndef NDMOS_CONST_NDMOS_REVISION
268 #define NDMOS_CONST_NDMOS_REVISION "0"
269 #endif /* !NDMOS_CONST_NDMOS_REVISION */
270
271
272
273
274 /*
275  * Application Program Interfaces (APIs)
276  */
277 #ifndef NDMOS_API_BZERO
278 #define NDMOS_API_BZERO(P,N)    (void)bzero((void*)(P),(N))
279 #endif /* !NDMOS_API_BZERO */
280
281 #ifndef NDMOS_API_BCOPY
282 #define NDMOS_API_BCOPY(S,D,N)  (void)bcopy((void*)(S),(void*)(D),(N))
283 #endif /* !NDMOS_API_BCOPY */
284
285 #ifndef NDMOS_API_MALLOC
286 #define NDMOS_API_MALLOC(N)     malloc(N)
287 #endif /* !NDMOS_API_MALLOC */
288
289 #ifndef NDMOS_API_FREE
290 #define NDMOS_API_FREE(P)       free((void*)(P))
291 #endif /* !NDMOS_API_FREE */
292
293 #ifndef NDMOS_API_STRTOLL
294 #define NDMOS_API_STRTOLL(P,PP,BASE) strtoll(P,PP,BASE)
295 #endif /* !NDMOS_API_STRTOLL */
296
297 #ifndef NDMOS_API_STRDUP
298 #define NDMOS_API_STRDUP(S)     strdup(S)
299 #endif /* !NDMOS_API_STRDUP */
300
301 #ifndef NDMOS_API_STREND
302 extern char *ndml_strend(char *s);      /* ndml_util.c */
303 #define NDMOS_API_STREND(S)     ndml_strend(S)
304 #endif /* !NDMOS_API_STREND */
305
306
307
308
309 /*
310  * Macros
311  */
312 #ifndef NDMOS_MACRO_NEW
313 #define NDMOS_MACRO_NEW(T)      ((T *) NDMOS_API_MALLOC(sizeof (T)))
314 #endif /* !NDMOS_MACRO_NEW */
315
316 #ifndef NDMOS_MACRO_NEWN
317 #define NDMOS_MACRO_NEWN(T,N)   ((T *) NDMOS_API_MALLOC(sizeof (T) * (N)))
318 #endif /* !NDMOS_MACRO_NEWN */
319
320 #ifndef NDMOS_MACRO_FREE
321 #define NDMOS_MACRO_FREE(T) free(T)
322 #endif
323
324 #ifndef NDMOS_MACRO_ZEROFILL
325 #define NDMOS_MACRO_ZEROFILL(P) NDMOS_API_BZERO(P,sizeof *(P))
326 #endif /* !NDMOS_MACRO_ZEROFILL */
327
328 #ifndef NDMOS_MACRO_SRAND
329 #define NDMOS_MACRO_SRAND() srand(time(0))
330 #endif /* !NDMOS_MACRO_SRAND */
331
332 #ifndef NDMOS_MACRO_RAND
333 #define NDMOS_MACRO_RAND() rand()
334 #endif /* !NDMOS_MACRO_RAND */
335
336 #ifndef NDMOS_MACRO_OK_TAPE_REC_LEN
337 #define NDMOS_MACRO_OK_TAPE_REC_LEN(LEN) \
338         (NDMOS_CONST_TAPE_REC_MIN <= (LEN) \
339          && (LEN) <= NDMOS_CONST_TAPE_REC_MAX)
340 #endif /* !NDMOS_MACRO_OK_TAPE_REC_LEN */
341
342 #ifndef NDMOS_MACRO_SET_SOCKADDR
343 #ifdef NDMOS_OPTION_HAVE_SIN_LEN
344 #define NDMOS_MACRO_SET_SOCKADDR(SA,INADDR,PORT) \
345         ( NDMOS_MACRO_ZEROFILL (SA), \
346           ((struct sockaddr_in *)(SA))->sin_len = sizeof *(SA), \
347           ((struct sockaddr_in *)(SA))->sin_family = AF_INET, \
348           ((struct sockaddr_in *)(SA))->sin_addr.s_addr = htonl(INADDR), \
349           ((struct sockaddr_in *)(SA))->sin_port = htons(PORT))
350 #else /* NDMOS_OPTION_HAVE_SIN_LEN */
351 #define NDMOS_MACRO_SET_SOCKADDR(SA,INADDR,PORT) \
352         ( NDMOS_MACRO_ZEROFILL (SA), \
353           ((struct sockaddr_in *)(SA))->sin_family = AF_INET, \
354           ((struct sockaddr_in *)(SA))->sin_addr.s_addr = htonl(INADDR), \
355           ((struct sockaddr_in *)(SA))->sin_port = htons(PORT))
356 #endif /* NDMOS_OPTION_HAVE_SIN_LEN */
357 #endif /* !NDMOS_MACRO_SET_SOCKADDR */
358
359
360
361
362 /*
363  * Composite effects
364  */
365
366 #ifdef NDMOS_OPTION_NO_DATA_AGENT
367 #ifdef NDMOS_OPTION_NO_TAPE_AGENT
368 #ifdef NDMOS_OPTION_NO_ROBOT_AGENT
369 #define NDMOS_EFFECT_NO_SERVER_AGENTS
370 #endif /* !NDMOS_OPTION_NO_ROBOT_AGENT */
371 #endif /* !NDMOS_OPTION_NO_TAPE_AGENT */
372 #endif /* !NDMOS_OPTION_NO_DATA_AGENT */
373
374 #ifdef NDMOS_OPTION_NO_NDMP3
375 #ifdef NDMOS_OPTION_NO_NDMP4
376 #define NDMOS_EFFECT_NO_NDMP3_NOR_NDMP4
377 #endif /* !NDMOS_OPTION_NO_NDMP3 */
378 #endif /* !NDMOS_OPTION_NO_NDMP4 */
379
380 /* check for a conflict: robot sim requires tape sim */
381 #ifdef NDMOS_OPTION_ROBOT_SIMULATOR
382 #ifndef NDMOS_OPTION_TAPE_SIMULATOR
383 #error robot simulator requires the tape simulator
384 #endif /* NDMOS_OPTION_TAPE_SIMULATOR */
385 #ifdef NDMOS_COMMON_SCSI_INTERFACE
386 #error robot simulator and ndmos scsi interface are incompatible
387 #endif
388 #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */
389
390 /*
391  * simulator fields
392  */
393
394 #ifdef NDMOS_OPTION_TAPE_SIMULATOR
395 #define NDMOS_MACRO_TAPE_AGENT_ADDITIONS \
396         int                     tape_fd; \
397         char                    drive_name[PATH_MAX]; \
398         int                     weof_on_close; \
399         int                     sent_leom;
400 #endif /* NDMOS_OPTION_TAPE_SIMULATOR */
401
402 #ifdef NDMOS_OPTION_ROBOT_SIMULATOR
403 #define NDMOS_MACRO_ROBOT_AGENT_ADDITIONS \
404             char sim_dir[PATH_MAX];
405 #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */
406
407 #endif /* _NDMOS_H */