1 /*
2 * CDDL HEADER START
3 *
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.
8 *
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.
13 *
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]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/resource.h>
30 #include <sys/time.h>
31 #include <stdlib.h>
32 #include <libintl.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <errno.h>
36 #include <stdarg.h>
37 #include <poll.h>
38 #include <unistd.h>
39 #include <project.h>
40 #include <pwd.h>
41 #include <pthread.h>
42
43 #include "rdfile.h"
44 #include "rdimpl.h"
45 #include "rdutil.h"
46
47 static char PRG_FMT[] = "%s: ";
48 static char ERR_FMT[] = ": %s\n";
49 static char *modulname = "srm provider";
50
51 extern jmp_buf dm_jmpbuffer;
52 extern char errmsg[];
53 extern void monitor_stop();
54
55 extern pthread_mutex_t logLock;
56
57 /*PRINTFLIKE1*/
58 void
format_err(char * format,...)59 format_err(char *format, ...)
60 {
61 int pos = 0;
62 va_list alist;
63 pos += sprintf(errmsg, PRG_FMT, modulname);
64 va_start(alist, format);
65 pos += vsprintf(errmsg + pos, format, alist);
66 va_end(alist);
67 if (strchr(format, '\n') == NULL)
68 (void) sprintf(errmsg + pos, "\n");
69 }
70
71 /*PRINTFLIKE1*/
72 void
format_errno(char * format,...)73 format_errno(char *format, ...)
74 {
75 int err = errno, pos = 0;
76 va_list alist;
77 pos += sprintf(errmsg, PRG_FMT, modulname);
78 va_start(alist, format);
79 pos += vsprintf(errmsg + pos, format, alist);
80 va_end(alist);
81 if (strchr(format, '\n') == NULL)
82 pos += sprintf(errmsg + pos, ERR_FMT,
83 (err != 0) ? strerror(err) : "");
84 }
85
86 /*PRINTFLIKE1*/
87 void
dmerror(char * format,...)88 dmerror(char *format, ...)
89 {
90 int err = errno, pos = 0;
91 va_list alist;
92
93 pos += sprintf(errmsg, PRG_FMT, modulname);
94 va_start(alist, format);
95 pos += vsprintf(errmsg + pos, format, alist);
96 va_end(alist);
97 if (strchr(format, '\n') == NULL)
98 pos += sprintf(errmsg + pos, ERR_FMT, strerror(err));
99 longjmp(dm_jmpbuffer, 1);
100 }
101
102 void *
Realloc(void * ptr,size_t size)103 Realloc(void *ptr, size_t size)
104 {
105 int cnt = 0;
106 void *sav = ptr;
107
108 eagain: if ((ptr = realloc(ptr, size)))
109 return (ptr);
110
111 log_err("realloc(ptr=0x%p, size=%u)", (void *)ptr, (uint_t)size);
112 if ((++cnt <= 3) && (errno == EAGAIN)) {
113 napms(5000); /* wait for 5 seconds */
114 ptr = sav;
115 goto eagain;
116 }
117 ptr = sav;
118 dmerror("not enough memory");
119 /*NOTREACHED*/
120 return (NULL); /* keep gcc happy */
121 }
122
123 void *
Malloc(size_t size)124 Malloc(size_t size)
125 {
126 return (Realloc(NULL, size));
127 }
128
129 void *
Zalloc(size_t size)130 Zalloc(size_t size)
131 {
132 return (memset(Realloc(NULL, size), 0, size));
133 }
134
135 void
Free(void * ptr)136 Free(void *ptr)
137 {
138 free(ptr);
139 }
140
141 int
Setrlimit()142 Setrlimit()
143 {
144 struct rlimit rlim;
145 int rv, fd_limit;
146
147 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
148 dmerror("getrlimit failed");
149 fd_limit = (int)rlim.rlim_cur;
150
151 rlim.rlim_cur = rlim.rlim_max;
152
153 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1)
154 rv = fd_limit;
155 else
156 rv = (int)rlim.rlim_cur;
157
158 log_msg("fd_limit set to %d\n", rv);
159
160 return (rv);
161 }
162
163 void
list_alloc(list_t * list,int size)164 list_alloc(list_t *list, int size)
165 {
166 if (size > 0) {
167 list->l_size = size;
168 list->l_ptrs = Zalloc(sizeof (void *) * (size + 1));
169 }
170 }
171
172 void
list_init(list_t * list,int type)173 list_init(list_t *list, int type)
174 {
175 if (list == NULL)
176 return;
177
178 list->l_type = type;
179
180 list->l_type = type;
181 }
182
183
184 void
getusrname(int uid,char * name,int length)185 getusrname(int uid, char *name, int length)
186 {
187 struct passwd *pwd;
188
189 if ((pwd = getpwuid(uid)) == NULL) {
190 log_err("getpwuid(uid=%d,..)", uid);
191 (void) snprintf(name, length, "%d", uid);
192 } else {
193 (void) snprintf(name, length, "%s", pwd->pw_name);
194 }
195 }
196
197 void
getprojname(projid_t projid,char * str,int len)198 getprojname(projid_t projid, char *str, int len)
199 {
200 struct project proj;
201 char projbuf[PROJECT_BUFSZ];
202
203 if (getprojbyid(projid, &proj, projbuf, PROJECT_BUFSZ) != NULL) {
204 (void) snprintf(str, len, "%s", proj.pj_name);
205 } else {
206 log_err("getprojbyid(projid=%ld,..)", (long)projid);
207 (void) snprintf(str, len, "%-6ld", (long)projid);
208 }
209
210 }
211
212
213 void
napms(int ms)214 napms(int ms)
215 {
216
217 (void) poll(NULL, 0, ms);
218 }
219
get_timestamp()220 longlong_t get_timestamp() {
221 struct timeval tv;
222 struct timezone tz;
223
224 (void) gettimeofday(&tv, &tz);
225 return (tv.tv_usec + ((longlong_t)tv.tv_sec * MICROSEC));
226 }
227
228
229 static FILE *logf = NULL;
230 static char buf[RDS_MAXLINE];
231 static hrtime_t hrt_base = 0;
232 static int call_cnt = 0;
233 static int bytes_written = 0;
234
235 void
log_open(char * file)236 log_open(char *file)
237 {
238 if (strcmp(file, "stderr") == 0)
239 logf = stderr;
240 else
241 logf = fopen(file, "w+");
242 }
243
244
245 void
log_close()246 log_close()
247 {
248 if (logf != NULL && logf != stderr)
249 (void) fclose(logf);
250 }
251
252
253 /*PRINTFLIKE1*/
254 void
log_msg(char * fmt,...)255 log_msg(char *fmt, ...)
256 {
257 va_list ap;
258 int n;
259 hrtime_t hrt;
260
261 if (logf == NULL)
262 return;
263 if (pthread_mutex_lock(&logLock) == 0) {
264 if (logf != stderr && bytes_written > RDS_MAXLOG_FILE) {
265 bytes_written = 0;
266 rewind(logf);
267 }
268
269 if (hrt_base == 0)
270 hrt_base = gethrtime() / 1000000;
271
272 hrt = gethrtime() / 1000000;
273 va_start(ap, fmt);
274 (void) vsnprintf(buf, RDS_MAXLINE, fmt, ap);
275 if ((n = fprintf(logf, "%4d:%08lld ms:%s",
276 call_cnt++, hrt - hrt_base, buf)) != -1)
277 bytes_written += n;
278 (void) fflush(logf);
279 va_end(ap);
280
281 if (pthread_mutex_unlock(&logLock) != 0)
282 perror("log pthread_mutex_unlock");
283
284 } else
285 perror("log pthread_mutex_lock");
286 }
287
288 /*PRINTFLIKE1*/
289 void
log_err(char * fmt,...)290 log_err(char *fmt, ...)
291 {
292 va_list ap;
293 int n;
294 hrtime_t hrt;
295 int err = errno;
296
297 if (logf == NULL)
298 return;
299 if (pthread_mutex_lock(&logLock) == 0) {
300 if (logf != stderr && bytes_written > RDS_MAXLOG_FILE) {
301 bytes_written = 0;
302 rewind(logf);
303 }
304
305 if (hrt_base == 0)
306 hrt_base = gethrtime() / 1000000;
307
308 hrt = gethrtime() / 1000000;
309 va_start(ap, fmt);
310 (void) vsnprintf(buf, RDS_MAXLINE, fmt, ap);
311 if ((n = fprintf(logf, "%4d:%08lld ms:ERROR: %s: (errno %d), %s\n",
312 call_cnt++, hrt - hrt_base, buf, err,
313 (err != 0) ? strerror(err) : "")) != -1)
314 bytes_written += n;
315 (void) fflush(logf);
316 va_end(ap);
317
318 if (pthread_mutex_unlock(&logLock) != 0)
319 perror("log pthread_mutex_unlock");
320
321 } else
322 perror("log pthread_mutex_lock");
323 }
324