dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fs.d / nfs / nfslog / buffer_list.c
blob525983ef2d03bb049fd0d382bf37617c53d72511
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <errno.h>
30 #include <syslog.h>
31 #include <libintl.h>
32 #include <unistd.h>
33 #include <strings.h>
34 #include <string.h>
35 #include <assert.h>
36 #include <stdlib.h>
37 #include "nfslogd.h"
38 #include "../lib/nfslogtab.h"
39 #include "buffer_list.h"
41 static int buildbuffer_list(struct buffer_ent **, timestruc_t *);
42 static void free_buffer_ent(struct buffer_ent *);
43 static struct buffer_ent *findbuffer(struct buffer_ent *, char *);
44 static void free_sharepnt_list(struct sharepnt_ent *);
45 static void free_sharepnt_ent(struct sharepnt_ent *);
46 #ifdef DEBUG
47 static void print_sharepnt_list(struct sharepnt_ent *);
48 #endif
49 static struct sharepnt_ent *findsharepnt(struct sharepnt_ent *, char *,
50 struct sharepnt_ent **);
53 * Builds the buffer list from NFSLOGTAB and returns it in *listpp.
54 * Returns 0 on success, non-zero error code otherwise.
56 int
57 getbuffer_list(struct buffer_ent **listpp, timestruc_t *lu)
59 *listpp = NULL;
60 return (buildbuffer_list(listpp, lu));
64 * If NFSLOGTAB has not been modified since the last time we read it,
65 * it simply returns the same buffer list, otherwise it re-reads NFSLOGTAB
66 * and rebuilds the list.
67 * No NFSLOGTAB is not treated as an error.
68 * Returns 0 on success, non-zero error code otherwise
70 int
71 checkbuffer_list(struct buffer_ent **listpp, timestruc_t *lu)
73 struct stat st;
74 int error = 0;
76 if (stat(NFSLOGTAB, &st) == -1) {
77 error = errno;
78 if (error != ENOENT) {
79 syslog(LOG_ERR, gettext("Can't stat %s - %s"),
80 NFSLOGTAB, strerror(error));
81 error = 0;
83 return (error);
86 if (lu->tv_sec == st.st_mtim.tv_sec &&
87 lu->tv_nsec == st.st_mtim.tv_nsec)
88 return (0);
90 free_buffer_list(listpp); /* free existing list first */
91 return (buildbuffer_list(listpp, lu));
95 * Does the actual work of reading NFSLOGTAB, and building the
96 * buffer list. If *be_head already contains entries, it will
97 * update the list with new information.
98 * Returns 0 on success, non-zero error code otherwise.
100 static int
101 buildbuffer_list(struct buffer_ent **be_head, timestruc_t *lu)
103 FILE *fd;
104 struct buffer_ent *be_tail = NULL, *bep;
105 struct sharepnt_ent *se_tail = NULL, *sep;
106 struct logtab_ent *lep;
107 struct stat st;
108 int error = 0, res;
110 if ((fd = fopen(NFSLOGTAB, "r+")) == NULL) {
111 error = errno;
112 if (error != ENOENT) {
113 syslog(LOG_ERR, gettext("%s - %s\n"), NFSLOGTAB,
114 strerror(error));
115 error = 0;
117 return (error);
120 if (lockf(fileno(fd), F_LOCK, 0L) < 0) {
121 error = errno;
122 syslog(LOG_ERR, gettext("cannot lock %s - %s\n"), NFSLOGTAB,
123 strerror(error));
124 (void) fclose(fd);
125 return (error);
128 assert(*be_head == NULL);
129 while ((res = logtab_getent(fd, &lep)) > 0) {
130 if (bep = findbuffer(*be_head, lep->le_buffer)) {
132 * Add sharepnt to buffer list
134 if (sep = findsharepnt(bep->be_sharepnt,
135 lep->le_path, &se_tail)) {
137 * Sharepoint already in list,
138 * update its state.
140 sep->se_state = lep->le_state;
141 } else {
143 * Need to add to sharepoint list
145 sep = (struct sharepnt_ent *)
146 malloc(sizeof (*sep));
147 if (sep == NULL) {
148 error = ENOMEM;
149 goto errout;
151 (void) memset(sep, 0, sizeof (*sep));
153 sep->se_name = strdup(lep->le_path);
154 if (sep->se_name == NULL) {
155 error = ENOMEM;
156 goto errout;
158 sep->se_state = lep->le_state;
160 assert(se_tail != NULL);
161 assert(se_tail->se_next == NULL);
162 se_tail->se_next = sep;
164 } else {
166 * Add new buffer to list
168 bep = (struct buffer_ent *)malloc(sizeof (*bep));
169 if (bep == NULL) {
170 error = ENOMEM;
171 goto errout;
173 (void) memset(bep, 0, sizeof (*bep));
175 bep->be_name = strdup(lep->le_buffer);
176 if (bep->be_name == NULL) {
177 error = ENOMEM;
178 goto errout;
181 if (*be_head == NULL)
182 *be_head = bep;
183 else
184 be_tail->be_next = bep;
185 be_tail = bep;
187 bep->be_sharepnt = (struct sharepnt_ent *)
188 malloc(sizeof (*(bep->be_sharepnt)));
189 (void) memset(bep->be_sharepnt, 0,
190 sizeof (*(bep->be_sharepnt)));
192 if (bep->be_sharepnt == NULL) {
193 error = ENOMEM;
194 goto errout;
196 bep->be_sharepnt->se_name = strdup(lep->le_path);
197 if (bep->be_sharepnt->se_name == NULL) {
198 error = ENOMEM;
199 goto errout;
201 bep->be_sharepnt->se_state = lep->le_state;
205 if (res < 0) {
206 error = EIO;
207 goto errout;
211 * Get modification time while we have the file locked.
213 if (lu) {
214 if ((error = fstat(fileno(fd), &st)) == -1) {
215 syslog(LOG_ERR, gettext("Can't stat %s"), NFSLOGTAB);
216 goto errout;
218 *lu = st.st_mtim;
221 (void) fclose(fd);
222 return (error);
224 errout:
225 (void) fclose(fd);
226 if (lep)
227 logtab_ent_free(lep);
228 free_buffer_list(be_head);
229 assert(*be_head == NULL);
230 syslog(LOG_ERR, gettext("cannot read %s: %s\n"), NFSLOGTAB,
231 strerror(error));
233 return (error);
237 * Removes the entry from the buffer list and frees it.
239 void
240 remove_buffer_ent(struct buffer_ent **be_listpp, struct buffer_ent *bep)
242 struct buffer_ent *p, *prev;
244 for (p = prev = *be_listpp; p != NULL; p = p->be_next) {
245 if (p == bep) {
246 if (p == *be_listpp)
247 *be_listpp = (*be_listpp)->be_next;
248 else
249 prev->be_next = bep->be_next;
250 free_buffer_ent(bep);
251 break;
253 prev = p;
258 * Frees the buffer list.
260 void
261 free_buffer_list(struct buffer_ent **be_listpp)
263 struct buffer_ent *bep, *nextp;
265 for (bep = *be_listpp; bep != NULL; bep = nextp) {
266 nextp = bep->be_next;
267 free_buffer_ent(bep);
269 *be_listpp = NULL;
272 static void
273 free_buffer_ent(struct buffer_ent *bep)
275 assert(bep != NULL);
276 if (debug)
277 (void) printf("freeing %s\n", bep->be_name);
278 free(bep->be_name);
279 if (bep->be_sharepnt != NULL)
280 free_sharepnt_list(bep->be_sharepnt);
281 free(bep);
284 static void
285 free_sharepnt_list(struct sharepnt_ent *sep_listp)
287 struct sharepnt_ent *nextp;
289 for (; sep_listp != NULL; sep_listp = nextp) {
290 nextp = sep_listp->se_next;
291 free_sharepnt_ent(sep_listp);
293 free(sep_listp);
297 * Removes the entry from the sharepnt list and frees it.
299 void
300 remove_sharepnt_ent(struct sharepnt_ent **se_listpp, struct sharepnt_ent *sep)
302 struct sharepnt_ent *p, *prev;
304 for (p = prev = *se_listpp; p != NULL; p = p->se_next) {
305 if (p == sep) {
306 if (p == *se_listpp)
307 *se_listpp = (*se_listpp)->se_next;
308 else
309 prev->se_next = sep->se_next;
310 free_sharepnt_ent(sep);
311 break;
313 prev = p;
317 static void
318 free_sharepnt_ent(struct sharepnt_ent *sep)
320 assert(sep != NULL);
321 if (debug)
322 (void) printf("freeing %s\n", sep->se_name);
323 free(sep->se_name);
324 free(sep);
327 #ifdef DEBUG
328 void
329 printbuffer_list(struct buffer_ent *bep)
331 for (; bep != NULL; bep = bep->be_next) {
332 (void) printf("%s\n", bep->be_name);
333 if (bep->be_sharepnt != NULL)
334 print_sharepnt_list(bep->be_sharepnt);
338 static void
339 print_sharepnt_list(struct sharepnt_ent *sep)
341 for (; sep != NULL; sep = sep->se_next)
342 (void) printf("\t(%d) %s\n", sep->se_state, sep->se_name);
344 #endif
347 * Returns a pointer to the buffer matching 'name', NULL otherwise.
349 static struct buffer_ent *
350 findbuffer(struct buffer_ent *bep, char *name)
352 for (; bep != NULL; bep = bep->be_next) {
353 if (strcmp(bep->be_name, name) == 0)
354 return (bep);
356 return (NULL);
360 * Returns a pointer the sharepoint entry matching 'name'.
361 * Otherwise, it sets '*se_tail' to the last element of the list
362 * to make insertion of new element easier, and returns NULL.
364 static struct sharepnt_ent *
365 findsharepnt(
366 struct sharepnt_ent *sep,
367 char *name,
368 struct sharepnt_ent **se_tail)
370 struct sharepnt_ent *tail;
372 for (; sep != NULL; sep = sep->se_next) {
373 if (strcmp(sep->se_name, name) == 0)
374 return (sep);
375 tail = sep;
377 *se_tail = tail;
378 return (NULL);