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 47static char PRG_FMT[] = "%s: "; 48static char ERR_FMT[] = ": %s\n"; 49static char *modulname = "srm provider"; 50 51extern jmp_buf dm_jmpbuffer; 52extern char errmsg[]; 53extern void monitor_stop(); 54 55extern pthread_mutex_t logLock; 56 57/*PRINTFLIKE1*/ 58void 59format_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*/ 72void 73format_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*/ 87void 88dmerror(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 102void * 103Realloc(void *ptr, size_t size) 104{ 105 int cnt = 0; 106 void *sav = ptr; 107 108eagain: 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 123void * 124Malloc(size_t size) 125{ 126 return (Realloc(NULL, size)); 127} 128 129void * 130Zalloc(size_t size) 131{ 132 return (memset(Realloc(NULL, size), 0, size)); 133} 134 135void 136Free(void *ptr) 137{ 138 free(ptr); 139} 140 141int 142Setrlimit() 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 163void 164list_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 172void 173list_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 184void 185getusrname(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 197void 198getprojname(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 213void 214napms(int ms) 215{ 216 217 (void) poll(NULL, 0, ms); 218} 219 220longlong_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 229static FILE *logf = NULL; 230static char buf[RDS_MAXLINE]; 231static hrtime_t hrt_base = 0; 232static int call_cnt = 0; 233static int bytes_written = 0; 234 235void 236log_open(char *file) 237{ 238 if (strcmp(file, "stderr") == 0) 239 logf = stderr; 240 else 241 logf = fopen(file, "w+"); 242} 243 244 245void 246log_close() 247{ 248 if (logf != NULL && logf != stderr) 249 (void) fclose(logf); 250} 251 252 253/*PRINTFLIKE1*/ 254void 255log_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*/ 289void 290log_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