1 /*****************************************************************************\
2 * $Id: ipmi-sdr.c,v 1.20 2010-02-08 22:09:40 chu11 Exp $
3 *****************************************************************************
4 * Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
5 * Copyright (C) 2006-2007 The Regents of the University of California.
6 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
7 * Written by Albert Chu <chu11@llnl.gov>
8 * UCRL-CODE-222073
9 *
10 * This file is part of Ipmimonitoring, an IPMI sensor monitoring
11 * library. For details, see http://www.llnl.gov/linux/.
12 *
13 * Ipmimonitoring is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 3 of the License, or (at your
16 * option) any later version.
17 *
18 * Ipmimonitoring is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with Ipmimonitoring. If not, see <http://www.gnu.org/licenses/>.
25 \*****************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif /* HAVE_CONFIG_H */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #if STDC_HEADERS
34 #include <string.h>
35 #endif /* STDC_HEADERS */
36 #if HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif /* HAVE_UNISTD_H */
39 #include <sys/mman.h>
40 #include <assert.h>
41 #include <errno.h>
42
43 #include "freeipmi/sdr/ipmi-sdr.h"
44
45 #include "ipmi-sdr-common.h"
46 #include "ipmi-sdr-defs.h"
47 #include "ipmi-sdr-trace.h"
48 #include "ipmi-sdr-util.h"
49
50 #include "freeipmi-portability.h"
51
52 static char *ipmi_sdr_cache_errmsgs[] =
53 {
54 "success",
55 "context null",
56 "context invalid",
57 "invalid parameters",
58 "out of memory",
59 "filename invalid",
60 "file system error",
61 "filename path permission error",
62 "context performing other operation",
63 "SDR cache exists",
64 "SDR record with an identical record id already written",
65 "SDR record length invalid",
66 "SDR record count invalid",
67 "SDR cache reading initialization already called",
68 "cache reading not initialized",
69 "SDR cache does not exist",
70 "SDR cache invalid",
71 "SDR cache out of date",
72 "stats not compiled",
73 "invalid sdr record",
74 "incomplete sdr record",
75 "cannot parse or calculate",
76 "error returned in callback",
77 "not found",
78 "internal IPMI error",
79 "internal system error",
80 "buffer overflow",
81 "internal error",
82 "errnum out of range",
83 NULL
84 };
85
86 ipmi_sdr_ctx_t
ipmi_sdr_ctx_create(void)87 ipmi_sdr_ctx_create (void)
88 {
89 struct ipmi_sdr_ctx *ctx = NULL;
90
91 if (!(ctx = (ipmi_sdr_ctx_t)malloc (sizeof (struct ipmi_sdr_ctx))))
92 {
93 ERRNO_TRACE (errno);
94 return (NULL);
95 }
96 memset (ctx, '\0', sizeof (struct ipmi_sdr_ctx));
97 ctx->magic = IPMI_SDR_CTX_MAGIC;
98 ctx->flags = IPMI_SDR_FLAGS_DEFAULT;
99 ctx->debug_prefix = NULL;
100
101 if (!(ctx->saved_offsets = list_create ((ListDelF)free)))
102 {
103 ERRNO_TRACE (errno);
104 goto cleanup;
105 }
106
107 sdr_init_ctx (ctx);
108 return (ctx);
109
110 cleanup:
111 if (ctx)
112 {
113 if (ctx->saved_offsets)
114 list_destroy (ctx->saved_offsets);
115 free (ctx);
116 }
117 return (NULL);
118 }
119
120 void
ipmi_sdr_ctx_destroy(ipmi_sdr_ctx_t ctx)121 ipmi_sdr_ctx_destroy (ipmi_sdr_ctx_t ctx)
122 {
123 if (!ctx || ctx->magic != IPMI_SDR_CTX_MAGIC)
124 return;
125
126 if (ctx->callback_lock)
127 {
128 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_CONTEXT_PERFORMING_OTHER_OPERATION);
129 return;
130 }
131
132 /* ignore potential error, destroy path */
133 if (ctx->fd >= 0)
134 close (ctx->fd);
135 /* ignore potential error, void return func */
136 if (ctx->sdr_cache)
137 munmap (ctx->sdr_cache, ctx->file_size);
138
139 list_destroy (ctx->saved_offsets);
140
141 ctx->magic = ~IPMI_SDR_CTX_MAGIC;
142 ctx->operation = IPMI_SDR_OPERATION_UNINITIALIZED;
143 free (ctx->debug_prefix);
144 free (ctx);
145 }
146
147 int
ipmi_sdr_ctx_errnum(ipmi_sdr_ctx_t ctx)148 ipmi_sdr_ctx_errnum (ipmi_sdr_ctx_t ctx)
149 {
150 if (!ctx)
151 return (IPMI_SDR_ERR_CONTEXT_NULL);
152 else if (ctx->magic != IPMI_SDR_CTX_MAGIC)
153 return (IPMI_SDR_ERR_CONTEXT_INVALID);
154 else
155 return (ctx->errnum);
156 }
157
158 char *
ipmi_sdr_ctx_strerror(int errnum)159 ipmi_sdr_ctx_strerror (int errnum)
160 {
161 if (errnum >= IPMI_SDR_ERR_SUCCESS && errnum <= IPMI_SDR_ERR_ERRNUMRANGE)
162 return (ipmi_sdr_cache_errmsgs[errnum]);
163 else
164 return (ipmi_sdr_cache_errmsgs[IPMI_SDR_ERR_ERRNUMRANGE]);
165 }
166
167 char *
ipmi_sdr_ctx_errormsg(ipmi_sdr_ctx_t ctx)168 ipmi_sdr_ctx_errormsg (ipmi_sdr_ctx_t ctx)
169 {
170 return (ipmi_sdr_ctx_strerror (ipmi_sdr_ctx_errnum (ctx)));
171 }
172
173 int
ipmi_sdr_ctx_get_flags(ipmi_sdr_ctx_t ctx,unsigned int * flags)174 ipmi_sdr_ctx_get_flags (ipmi_sdr_ctx_t ctx, unsigned int *flags)
175 {
176 if (!ctx || ctx->magic != IPMI_SDR_CTX_MAGIC)
177 {
178 ERR_TRACE (ipmi_sdr_ctx_errormsg (ctx), ipmi_sdr_ctx_errnum (ctx));
179 return (-1);
180 }
181
182 if (!flags)
183 {
184 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARAMETERS);
185 return (-1);
186 }
187
188 *flags = ctx->flags;
189 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
190 return (0);
191 }
192
193 int
ipmi_sdr_ctx_set_flags(ipmi_sdr_ctx_t ctx,unsigned int flags)194 ipmi_sdr_ctx_set_flags (ipmi_sdr_ctx_t ctx, unsigned int flags)
195 {
196 if (!ctx || ctx->magic != IPMI_SDR_CTX_MAGIC)
197 {
198 ERR_TRACE (ipmi_sdr_ctx_errormsg (ctx), ipmi_sdr_ctx_errnum (ctx));
199 return (-1);
200 }
201
202 if (flags & ~IPMI_SDR_FLAGS_DEBUG_DUMP)
203 {
204 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARAMETERS);
205 return (-1);
206 }
207
208 ctx->flags = flags;
209 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
210 return (0);
211 }
212
213 char *
ipmi_sdr_ctx_get_debug_prefix(ipmi_sdr_ctx_t ctx)214 ipmi_sdr_ctx_get_debug_prefix (ipmi_sdr_ctx_t ctx)
215 {
216 if (!ctx || ctx->magic != IPMI_SDR_CTX_MAGIC)
217 {
218 ERR_TRACE (ipmi_sdr_ctx_errormsg (ctx), ipmi_sdr_ctx_errnum (ctx));
219 return (NULL);
220 }
221
222 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
223 return (ctx)->debug_prefix;
224 }
225
226 int
ipmi_sdr_ctx_set_debug_prefix(ipmi_sdr_ctx_t ctx,const char * debug_prefix)227 ipmi_sdr_ctx_set_debug_prefix (ipmi_sdr_ctx_t ctx, const char *debug_prefix)
228 {
229 if (!ctx || ctx->magic != IPMI_SDR_CTX_MAGIC)
230 {
231 ERR_TRACE (ipmi_sdr_ctx_errormsg (ctx), ipmi_sdr_ctx_errnum (ctx));
232 return (-1);
233 }
234
235 free (ctx->debug_prefix);
236 ctx->debug_prefix = NULL;
237
238 if (debug_prefix)
239 {
240 if (!(ctx->debug_prefix = strdup (debug_prefix)))
241 {
242 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_OUT_OF_MEMORY);
243 return (-1);
244 }
245 }
246
247 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
248 return (0);
249 }
250