MacOS needs a ${CACHEDIR}/cores/ for core dumps to work
[arla.git] / arlad / state.c
blobe17a658ff8925fd071c3abf2c1f97bce0ec9efed
1 /*
2 * Copyright (c) 2001 - 2002 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
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 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
35 * The interface for the on disk storage of data when arla is down
38 #include "arla_local.h"
39 RCSID("$Id$");
42 * Save the fcache inforation in `fn', call `func' until `func' return
43 * a none zero value. A negative value is an errno, and a positive is
44 * a signal to terminate the loop (success). `ptr' is passed to
45 * `func'.
48 int
49 state_store_fcache(const char *fn, store_fcache_fn func, void *ptr)
51 int ret, fd, save_errno;
52 struct fcache_store st;
53 uint32_t u1, u2;
54 char file[MAXPATHLEN];
56 snprintf(file, sizeof(file), "%s.new", fn);
58 fd = open (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
59 if (fd < 0)
60 return errno;
61 u1 = FCACHE_MAGIC_COOKIE;
62 u2 = FCACHE_VERSION;
64 if (write (fd, &u1, sizeof(u1)) != sizeof(u1)
65 || write (fd, &u2, sizeof(u2)) != sizeof(u2)) {
66 save_errno = errno;
68 close (fd);
69 return save_errno;
72 while (1) {
74 memset(&st, 0, sizeof(st));
76 ret = (*func)(&st, ptr);
77 if (ret < 0) { /* errors */
78 close(fd);
79 return -ret;
80 } else if (ret == STORE_SKIP) {
81 continue;
82 } else if (ret == STORE_NEXT) {
83 if (write(fd, &st, sizeof(st)) != sizeof(st)) {
84 save_errno = errno;
85 close(fd);
86 return save_errno;
88 } else if (ret == STORE_DONE) {
89 break;
90 } else
91 abort();
94 if(close (fd))
95 return errno;
96 if (rename (file, fn))
97 return errno;
99 return 0;
103 state_recover_fcache(const char *file, store_fcache_fn func, void *ptr)
105 int fd;
106 struct fcache_store st;
107 uint32_t u1, u2;
109 fd = open (file, O_RDONLY | O_BINARY, 0);
110 if (fd < 0)
111 return errno;
112 if (read (fd, &u1, sizeof(u1)) != sizeof(u1)
113 || read (fd, &u2, sizeof(u2)) != sizeof(u2)) {
114 close (fd);
115 return EINVAL;
117 if (u1 != FCACHE_MAGIC_COOKIE) {
118 #if 0
119 arla_warnx (ADEBFCACHE, "dump file not recognized, ignoring");
120 #endif
121 close (fd);
122 return EINVAL;
124 if (u2 != FCACHE_VERSION) {
125 #if 0
126 arla_warnx (ADEBFCACHE, "unknown dump file version number %u", u2);
127 #endif
128 close (fd);
129 return EINVAL;
132 while (read (fd, &st, sizeof(st)) == sizeof(st)) {
134 st.cell[sizeof(st.cell)-1] = '\0';
135 st.parentcell[sizeof(st.parentcell)-1] = '\0';
137 if ((*func)(&st, ptr)) {
138 close(fd);
139 return 1;
142 close (fd);
144 return 0;
148 * Save the volcache inforation in `fn', call `func' until `func' return
149 * a none zero value. A negative value is an errno, and a positive is
150 * a signal to terminate the loop (success). `ptr' is passed to
151 * `func'.
155 state_store_volcache(const char *fn, store_volcache_fn func, void *ptr)
157 int ret, fd, save_errno;
158 struct volcache_store st;
159 uint32_t u1, u2;
160 char file[MAXPATHLEN];
162 snprintf(file, sizeof(file), "%s.new", fn);
164 fd = open (file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
165 if (fd < 0)
166 return errno;
167 u1 = VOLCACHE_MAGIC_COOKIE;
168 u2 = VOLCACHE_VERSION;
170 if (write (fd, &u1, sizeof(u1)) != sizeof(u1)
171 || write (fd, &u2, sizeof(u2)) != sizeof(u2)) {
172 save_errno = errno;
174 close (fd);
175 return save_errno;
178 while (1) {
180 memset(&st, 0, sizeof(st));
182 ret = (*func)(&st, ptr);
183 if (ret < 0) { /* errors */
184 close(fd);
185 return -ret;
186 } else if (ret == STORE_SKIP) {
187 continue;
188 } else if (ret == STORE_NEXT) {
189 if (write(fd, &st, sizeof(st)) != sizeof(st)) {
190 save_errno = errno;
191 close(fd);
192 return save_errno;
194 } else if (ret == STORE_DONE) {
195 break;
196 } else
197 abort();
200 if(close (fd))
201 return errno;
202 if (rename (file, fn))
203 return errno;
205 return 0;
209 state_recover_volcache(const char *file, store_volcache_fn func, void *ptr)
211 int fd;
212 struct volcache_store st;
213 uint32_t u1, u2;
215 fd = open (file, O_RDONLY | O_BINARY, 0);
216 if (fd < 0)
217 return errno;
218 if (read (fd, &u1, sizeof(u1)) != sizeof(u1)
219 || read (fd, &u2, sizeof(u2)) != sizeof(u2)) {
220 close (fd);
221 return EINVAL;
223 if (u1 != VOLCACHE_MAGIC_COOKIE) {
224 #if 0
225 arla_warnx (ADEBVOLCACHE, "dump file not recognized, ignoring");
226 #endif
227 close (fd);
228 return EINVAL;
230 if (u2 != VOLCACHE_VERSION) {
231 #if 0
232 arla_warnx (ADEBVOLCACHE, "unknown dump file version number %u", u2);
233 #endif
234 close (fd);
235 return EINVAL;
238 while (read (fd, &st, sizeof(st)) == sizeof(st)) {
240 st.cell[sizeof(st.cell)-1] = '\0';
242 if ((*func)(&st, ptr)) {
243 close(fd);
244 return 1;
247 close (fd);
249 return 0;