2 * Copyright (c) 1998,1999,2000
3 * Traakan, Inc., Los Altos, CA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
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.
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
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.
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
47 * (hacked in Amanda to just #include ndmos_glib.h and then follow up
48 * with the usual defaults)
50 * The strategy for separating the O/S specific and O/S
51 * generic portions of NDMJOBLIB has four key points:
53 * 1) Isolate O/S specific portions in separate
54 * files which can be developed, contributed,
55 * and maintained independently of the overall
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
63 * 3) Use O/S specific #define macros (NDMOS_...)
64 * and C functions (ndmos_...) as wrappers around
65 * the portions that vary between environments
68 * 4) Use generic, objective-oriented #ifdef's to isolate
69 * and omit functionality which may not be wanted in
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.
77 * >>> DO NOT MODIFY THIS FILE OR ANY GENERIC <<<
78 * >>> PORTION OF NDMJOBLIB FOR THE SAKE OF A <<<
79 * >>> HOSTING ENVIRONMENT OR APPLICATION. <<<
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.
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
101 /* set up the appropriate macros for use in various version-printing
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
107 /* unconditionally include ndmos_glib.h */
108 #include "ndmos_glib.h"
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.
114 * Application Program Interfaces (APIs). The macros give the
115 * O/S specific header a chance to use casts or different functions.
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
125 * Important constants that sometimes vary between O/S's.
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
144 * Macros for certain small operations which can vary.
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
157 * The NDMOS_MACRO_xxx_ADDITIONS macros allow additional O/S
158 * specific members to key structures in ndmagents.h
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
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
172 * NDMOS_OPTION_NO_NDMP2 -- omit NDMPv2 support
173 * NDMOS_OPTION_NO_NDMP3 -- omit NDMPv3 support
174 * NDMOS_OPTION_NO_NDMP4 -- omit NDMPv4 support
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.
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
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.
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.
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
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.
227 #ifndef NDMOS_CONST_ALIGN
228 #define NDMOS_CONST_ALIGN sizeof(unsigned long long)
229 #endif /* !NDMOS_CONST_ALIGN */
231 #ifndef NDMOS_CONST_TAPE_REC_MIN
232 #define NDMOS_CONST_TAPE_REC_MIN 1
233 #endif /* !NDMOS_CONST_TAPE_REC_MIN */
235 #ifndef NDMOS_CONST_TAPE_REC_MAX
236 #define NDMOS_CONST_TAPE_REC_MAX (256*1024)
237 #endif /* !NDMOS_CONST_TAPE_REC_MAX */
239 #ifndef NDMOS_CONST_PATH_MAX
240 #define NDMOS_CONST_PATH_MAX (1024)
241 #endif /* !NDMOS_CONST_PATH_MAX */
243 #ifndef NDMOS_CONST_EWOULDBLOCK
245 #define NDMOS_CONST_EWOULDBLOCK EWOULDBLOCK
246 #else /* EWOULDBLOCK */
247 #define NDMOS_CONST_EWOULDBLOCK EAGAIN
248 #endif /* EWOULDBLOCK */
249 #endif /* !NDMOS_CONST_EWOULDBLOCK */
251 #ifndef NDMOS_CONST_NDMJOBLIB_REVISION
252 #define NDMOS_CONST_NDMJOBLIB_REVISION "1.4a"
253 #endif /* !NDMOS_CONST_NDMJOBLIB_REVISION */
255 #ifndef NDMOS_CONST_VENDOR_NAME
256 #define NDMOS_CONST_VENDOR_NAME "PublicDomain"
257 #endif /* !NDMOS_CONST_VENDOR_NAME */
259 #ifndef NDMOS_CONST_PRODUCT_NAME
260 #define NDMOS_CONST_PRODUCT_NAME "NDMJOB"
261 #endif /* !NDMOS_CONST_PRODUCT_NAME */
263 #ifndef NDMOS_CONST_PRODUCT_REVISION
264 #define NDMOS_CONST_PRODUCT_REVISION "1.4a"
265 #endif /* !NDMOS_CONST_PRODUCT_REVISION */
267 #ifndef NDMOS_CONST_NDMOS_REVISION
268 #define NDMOS_CONST_NDMOS_REVISION "0"
269 #endif /* !NDMOS_CONST_NDMOS_REVISION */
275 * Application Program Interfaces (APIs)
277 #ifndef NDMOS_API_BZERO
278 #define NDMOS_API_BZERO(P,N) (void)bzero((void*)(P),(N))
279 #endif /* !NDMOS_API_BZERO */
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 */
285 #ifndef NDMOS_API_MALLOC
286 #define NDMOS_API_MALLOC(N) malloc(N)
287 #endif /* !NDMOS_API_MALLOC */
289 #ifndef NDMOS_API_FREE
290 #define NDMOS_API_FREE(P) free((void*)(P))
291 #endif /* !NDMOS_API_FREE */
293 #ifndef NDMOS_API_STRTOLL
294 #define NDMOS_API_STRTOLL(P,PP,BASE) strtoll(P,PP,BASE)
295 #endif /* !NDMOS_API_STRTOLL */
297 #ifndef NDMOS_API_STRDUP
298 #define NDMOS_API_STRDUP(S) strdup(S)
299 #endif /* !NDMOS_API_STRDUP */
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 */
312 #ifndef NDMOS_MACRO_NEW
313 #define NDMOS_MACRO_NEW(T) ((T *) NDMOS_API_MALLOC(sizeof (T)))
314 #endif /* !NDMOS_MACRO_NEW */
316 #ifndef NDMOS_MACRO_NEWN
317 #define NDMOS_MACRO_NEWN(T,N) ((T *) NDMOS_API_MALLOC(sizeof (T) * (N)))
318 #endif /* !NDMOS_MACRO_NEWN */
320 #ifndef NDMOS_MACRO_FREE
321 #define NDMOS_MACRO_FREE(T) free(T)
324 #ifndef NDMOS_MACRO_ZEROFILL
325 #define NDMOS_MACRO_ZEROFILL(P) NDMOS_API_BZERO(P,sizeof *(P))
326 #endif /* !NDMOS_MACRO_ZEROFILL */
328 #ifndef NDMOS_MACRO_SRAND
329 #define NDMOS_MACRO_SRAND() srand(time(0))
330 #endif /* !NDMOS_MACRO_SRAND */
332 #ifndef NDMOS_MACRO_RAND
333 #define NDMOS_MACRO_RAND() rand()
334 #endif /* !NDMOS_MACRO_RAND */
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 */
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 */
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 */
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 */
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
388 #endif /* NDMOS_OPTION_ROBOT_SIMULATOR */
394 #ifdef NDMOS_OPTION_TAPE_SIMULATOR
395 #define NDMOS_MACRO_TAPE_AGENT_ADDITIONS \
397 char drive_name[PATH_MAX]; \
400 #endif /* NDMOS_OPTION_TAPE_SIMULATOR */
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 */
407 #endif /* _NDMOS_H */