2 * Copyright 2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and
30 * documentation are those of the authors and should not be
31 * interpreted as representing official policies, either expressed
32 * or implied, of GRNET S.A.
43 #include <sys/syscall.h>
46 #include <sys/types.h>
51 #include <sys/domain.h>
52 #include <xtypes/domain.h>
53 #include <xseg/domain.h>
55 #include <xtypes/xlock.h>
57 int (*xseg_snprintf)(char *str, size_t size, const char *format, ...) = snprintf;
59 char __xseg_errbuf[4096];
61 static struct xlock __lock = { .owner = Noone};
63 void __lock_domain(void)
65 (void)xlock_acquire(&__lock, 1);
68 void __unlock_domain(void)
70 xlock_release(&__lock);
73 void __load_plugin(const char *name)
78 unsigned int namelen = strlen(name);
80 strncpy(_name, "xseg_", 5);
81 strncpy(_name + 5, name, 80);
82 strncpy(_name + 5 + namelen, ".so", 3);
83 _name[5 + namelen + 3 ] = 0;
84 dl = dlopen(_name, RTLD_NOW);
86 XSEGLOG("Cannot load plugin '%s': %s\n", _name, dlerror());
90 strncpy(_name + 5 + namelen, "_init", 5);
92 init = (void (*)(void))(long)dlsym(dl, _name);
94 XSEGLOG("Init function '%s' not found!\n", _name);
99 //XSEGLOG("Plugin '%s' loaded.\n", name);
102 uint64_t __get_id(void)
104 return (uint64_t)syscall(SYS_gettid);
107 void __xseg_log(const char *msg)
113 void *xtypes_malloc(unsigned long size)
118 void xtypes_free(void *ptr)
123 void __get_current_time(struct timeval *tv) {
124 gettimeofday(tv, NULL);
127 int __renew_logctx(struct log_ctx *lc, char *peer_name,
128 enum log_level log_level, char *logfile, uint32_t flags)
133 strncpy(lc->peer_name, peer_name, MAX_PEER_NAME);
134 lc->peer_name[MAX_PEER_NAME -1] = 0;
137 lc->log_level = log_level;
138 if (logfile && logfile[0]) {
139 strncpy(lc->filename, logfile, MAX_LOGFILE_LEN);
140 lc->filename[MAX_LOGFILE_LEN - 1] = 0;
142 else if (!(flags & REOPEN_FILE) || lc->logfile == STDERR_FILENO)
145 fd = open(lc->filename, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
150 tmp_fd = lc->logfile;
154 flags &= ~REOPEN_FILE;
155 if ((flags|lc->flags) & REDIRECT_STDOUT){
156 fd = dup2(lc->logfile, STDOUT_FILENO);
160 if ((flags|lc->flags) & REDIRECT_STDERR){
161 fd = dup2(lc->logfile, STDERR_FILENO);
169 int (*renew_logctx)(struct log_ctx *lc, char *peer_name,
170 enum log_level log_level, char *logfile, uint32_t flags) = __renew_logctx;
172 int __init_logctx(struct log_ctx *lc, char *peer_name,
173 enum log_level log_level, char *logfile, uint32_t flags)
178 strncpy(lc->peer_name, peer_name, MAX_PEER_NAME);
179 lc->peer_name[MAX_PEER_NAME -1] = 0;
185 /* set logfile to stderr by default */
186 lc->logfile = STDERR_FILENO;
188 /* duplicate stdout, stderr */
189 fd = dup(STDOUT_FILENO);
193 lc->stdout_orig = fd;
195 fd = dup(STDERR_FILENO);
199 lc->stderr_orig = fd;
201 lc->log_level = log_level;
202 if (!logfile || !logfile[0]) {
203 // lc->logfile = lc->stderr_orig;
207 strncpy(lc->filename, logfile, MAX_LOGFILE_LEN);
208 lc->filename[MAX_LOGFILE_LEN - 1] = 0;
209 fd = open(lc->filename, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR);
211 // lc->logfile = lc->stderr_orig;
216 if (flags & REDIRECT_STDOUT){
217 fd = dup2(lc->logfile, STDOUT_FILENO);
221 if (flags & REDIRECT_STDERR){
222 fd = dup2(lc->logfile, STDERR_FILENO);
230 int (*init_logctx)(struct log_ctx *lc, char *peer_name,
231 enum log_level log_level, char *logfile, uint32_t flags) = __init_logctx;
233 void __xseg_log2(struct log_ctx *lc, enum log_level level, char *fmt, ...)
237 char timebuf[1024], buffer[4096];
239 char *t = NULL, *pn = NULL;
246 case E: t = "XSEG[EE]"; break;
247 case W: t = "XSEG[WW]"; break;
248 case I: t = "XSEG[II]"; break;
249 case D: t = "XSEG[DD]"; break;
250 default: t = "XSEG[UNKNONW]"; break;
254 pn = "Invalid peer name";
257 ctime_r(&timeval, timebuf);
258 *strchr(timebuf, '\n') = '\0';
260 buf += sprintf(buf, "%s: ", t);
261 buf += snprintf(buf, MAX_PEER_NAME + 2, "%s: ", lc->peer_name);
262 buf += sprintf(buf, "%s (%ld):\n\t", timebuf, timeval);
263 unsigned long rem = sizeof(buffer) - (buf - buffer);
264 buf += vsnprintf(buf, rem, fmt, ap);
265 if (buf >= buffer + sizeof(buffer))
266 buf = buffer + sizeof(buffer) - 2;/* enough to hold \n and \0 */
267 buf += sprintf(buf, "\n");
272 fd = *(volatile int *)&lc->logfile;
274 r = write(fd, buffer + sum, count - sum);
277 fd = *(volatile int *)&lc->logfile;
279 //XSEGLOG("Error while writing log");
285 } while (sum < count);
286 /* No need to check for error */
293 void xseg_printtrace(void)
300 size = backtrace (array, 10);
301 strings = backtrace_symbols (array, size);
303 XSEGLOG("Obtained %zd stack frames.\n", size);
305 for (i = 0; i < size; i++)
306 XSEGLOG ("%s\n", strings[i]);