2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Miscellaneous Bacula memory and thread safe routines
21 * Generally, these are interfaces to system or standard
24 * Bacula utility functions are in util.c
30 #include "lib/bregex.h"
35 static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER;
36 static pthread_cond_t timer = PTHREAD_COND_INITIALIZER;
41 POOLMEM *quote_string(POOLMEM *snew, const char *old)
52 for (i=0; old[i]; i++) {
81 * Quote a where (list of addresses separated by spaces)
83 POOLMEM *quote_where(POOLMEM *snew, const char *old)
94 for (i=0; old[i]; i++) {
120 * This routine is a somewhat safer unlink in that it
121 * allows you to run a regex on the filename before
122 * excepting it. It also requires the file to be in
123 * the working directory.
125 int safer_unlink(const char *pathname, const char *regx)
130 const int nmatch = 30;
131 regmatch_t pmatch[nmatch];
134 /* Name must start with working directory */
135 if (strncmp(pathname, working_directory, strlen(working_directory)) != 0) {
136 Pmsg1(000, "Safe_unlink excluded: %s\n", pathname);
140 /* Compile regex expression */
141 rc = regcomp(&preg1, regx, REG_EXTENDED);
143 regerror(rc, &preg1, prbuf, sizeof(prbuf));
144 Pmsg2(000, _("safe_unlink could not compile regex pattern \"%s\" ERR=%s\n"),
149 /* Unlink files that match regexes */
150 if (regexec(&preg1, pathname, nmatch, pmatch, 0) == 0) {
151 Dmsg1(100, "safe_unlink unlinking: %s\n", pathname);
152 rtn = unlink(pathname);
154 Pmsg2(000, "safe_unlink regex failed: regex=%s file=%s\n", regx, pathname);
162 * This routine will sleep (sec, microsec). Note, however, that if a
163 * signal occurs, it will return early. It is up to the caller
164 * to recall this routine if he/she REALLY wants to sleep the
167 int bmicrosleep(int32_t sec, int32_t usec)
169 struct timespec timeout;
174 timeout.tv_sec = sec;
175 timeout.tv_nsec = usec * 1000;
177 #ifdef HAVE_NANOSLEEP
178 stat = nanosleep(&timeout, NULL);
179 if (!(stat < 0 && errno == ENOSYS)) {
182 /* If we reach here it is because nanosleep is not supported by the OS */
185 /* Do it the old way */
186 gettimeofday(&tv, &tz);
187 timeout.tv_nsec += tv.tv_usec * 1000;
188 timeout.tv_sec += tv.tv_sec;
189 while (timeout.tv_nsec >= 1000000000) {
190 timeout.tv_nsec -= 1000000000;
194 Dmsg2(200, "pthread_cond_timedwait sec=%d usec=%d\n", sec, usec);
195 /* Note, this unlocks mutex during the sleep */
197 stat = pthread_cond_timedwait(&timer, &timer_mutex, &timeout);
200 Dmsg2(200, "pthread_cond_timedwait stat=%d ERR=%s\n", stat,
208 * Guarantee that the string is properly terminated */
209 char *bstrncpy(char *dest, const char *src, int maxlen)
211 strncpy(dest, src, maxlen-1);
217 * Guarantee that the string is properly terminated */
218 char *bstrncpy(char *dest, POOL_MEM &src, int maxlen)
220 strncpy(dest, src.c_str(), maxlen-1);
226 * Note: Here the maxlen is the maximum length permitted
227 * stored in dest, while on Unix systems, it is the maximum characters
228 * that may be copied from src.
230 char *bstrncat(char *dest, const char *src, int maxlen)
232 int len = strlen(dest);
233 if (len < maxlen-1) {
234 strncpy(dest+len, src, maxlen-len-1);
241 * Note: Here the maxlen is the maximum length permitted
242 * stored in dest, while on Unix systems, it is the maximum characters
243 * that may be copied from src.
245 char *bstrncat(char *dest, POOL_MEM &src, int maxlen)
247 int len = strlen(dest);
248 if (len < maxlen-1) {
249 strncpy(dest+len, src.c_str(), maxlen-len-1);
256 * Allows one or both pointers to be NULL
258 bool bstrcmp(const char *s1, const char *s2)
260 if (s1 == s2) return true;
261 if (s1 == NULL || s2 == NULL) return false;
262 return strcmp(s1, s2) == 0;
266 * Allows one or both pointers to be NULL
268 bool bstrcasecmp(const char *s1, const char *s2)
270 if (s1 == s2) return true;
271 if (s1 == NULL || s2 == NULL) return false;
272 return strcasecmp(s1, s2) == 0;
277 * Get character length of UTF-8 string
280 * U-00000000 - U-0000007F: 0xxxxxxx
281 * U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
282 * U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
283 * U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
284 * U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
285 * U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
287 int cstrlen(const char *str)
289 uint8_t *p = (uint8_t *)str;
295 if ((*p & 0xC0) != 0xC0) {
300 if ((*p & 0xD0) == 0xC0) {
305 if ((*p & 0xF0) == 0xD0) {
310 if ((*p & 0xF8) == 0xF0) {
315 if ((*p & 0xFC) == 0xF8) {
320 if ((*p & 0xFE) == 0xFC) {
325 p++; /* Shouln't get here but must advance */
330 /* We need to disable the malloc() macro if SMARTALLOC is not used,
331 * else, it points to b_malloc() and causes problems.
340 void *bmalloc(size_t size)
345 buf = sm_malloc(file, line, size);
351 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
357 void *b_malloc(const char *file, int line, size_t size)
362 buf = sm_malloc(file, line, size);
368 e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
374 void bfree(void *buf)
377 sm_free(__FILE__, __LINE__, buf);
383 void *brealloc (void *buf, size_t size)
386 buf = sm_realloc(__FILE__, __LINE__, buf, size);
388 buf = realloc(buf, size);
392 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
398 void *bcalloc(size_t size1, size_t size2)
402 buf = calloc(size1, size2);
405 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
410 /* Code now in src/lib/bsnprintf.c */
411 #ifndef USE_BSNPRINTF
417 int bsnprintf(char *str, int32_t size, const char *fmt, ...)
422 va_start(arg_ptr, fmt);
423 len = bvsnprintf(str, size, fmt, arg_ptr);
429 * Implement vsnprintf()
431 int bvsnprintf(char *str, int32_t size, const char *format, va_list ap)
433 #ifdef HAVE_VSNPRINTF
435 len = vsnprintf(str, size, format, ap);
443 buflen = size > BIG_BUF ? size : BIG_BUF;
444 buf = get_memory(buflen);
445 len = vsprintf(buf, format, ap);
447 Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
449 memcpy(str, buf, len);
450 str[len] = 0; /* len excludes the null */
455 #endif /* USE_BSNPRINTF */
457 #ifndef HAVE_LOCALTIME_R
459 struct tm *localtime_r(const time_t *timep, struct tm *tm)
461 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
465 ltm = localtime(timep);
467 memcpy(tm, ltm, sizeof(struct tm));
470 return ltm ? tm : NULL;
472 #endif /* HAVE_LOCALTIME_R */
474 #ifndef HAVE_READDIR_R
478 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
480 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
486 ndir = readdir(dirp);
489 memcpy(entry, ndir, sizeof(struct dirent));
490 strcpy(entry->d_name, ndir->d_name);
500 #endif /* HAVE_READDIR_R */
503 int b_strerror(int errnum, char *buf, size_t bufsiz)
505 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
511 msg = strerror(errnum);
513 msg = _("Bad errno");
516 bstrncpy(buf, msg, bufsiz);
522 /* These routines are not normally turned on */
524 void b_memset(const char *file, int line, void *mem, int val, size_t num)
526 /* Testing for 2000 byte zero at beginning of Volume block */
527 if (num > 1900 && num < 3000) {
528 Pmsg3(000, _("Memset for %d bytes at %s:%d\n"), (int)num, file, line);
530 memset(mem, val, num);
534 #if !defined(HAVE_WIN32)
535 static int del_pid_file_ok = FALSE;
537 static int pid_fd = -1;
539 #ifdef HAVE_FCNTL_LOCK
540 /* a convenient function [un]lock file using fnctl()
541 * code must be in F_UNLCK, F_RDLCK, F_WRLCK
542 * return -1 for error and errno is set
544 int fcntl_lock(int fd, int code)
548 l.l_whence = l.l_start = l.l_len = 0;
550 return fcntl(fd, F_SETLK, &l);
554 /* Create a disk pid "lock" file
556 * 0: Error with the error message in errmsg
558 * 2: Successs, but a previous file was found
560 #if !defined(HAVE_FCNTL_LOCK) || defined(HAVE_WIN32)
561 int create_lock_file(char *fname, const char *progname, const char *filetype, POOLMEM **errmsg, int *fd)
564 #if !defined(HAVE_WIN32)
570 if (stat(fname, &statp) == 0) {
571 /* File exists, see what we have */
573 if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
574 read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
575 sscanf(pidbuf, "%d", &oldpid) != 1) {
577 Mmsg(errmsg, _("Cannot open %s file. %s ERR=%s\n"), filetype, fname,
579 close(pidfd); /* if it was successfully opened */
582 /* Some OSes (IRIX) don't bother to clean out the old pid files after a crash, and
583 * since they use a deterministic algorithm for assigning PIDs, we can have
584 * pid conflicts with the old PID file after a reboot.
585 * The intent the following code is to check if the oldpid read from the pid
586 * file is the same as the currently executing process's pid,
587 * and if oldpid == getpid(), skip the attempt to
588 * kill(oldpid,0), since the attempt is guaranteed to succeed,
589 * but the success won't actually mean that there is an
590 * another Bacula process already running.
591 * For more details see bug #797.
593 if ((oldpid != (int)getpid()) && (kill(oldpid, 0) != -1 || errno != ESRCH)) {
594 Mmsg(errmsg, _("%s is already running. pid=%d\nCheck file %s\n"),
595 progname, oldpid, fname);
598 /* He is not alive, so take over file ownership */
599 unlink(fname); /* remove stale pid file */
602 /* Create new pid file */
603 if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) {
604 len = sprintf(pidbuf, "%d\n", (int)getpid());
605 write(pidfd, pidbuf, len);
607 /* ret is already 1 */
610 Mmsg(errmsg, _("Could not open %s file. %s ERR=%s\n"), filetype, fname, be.bstrerror());
616 #else /* defined(HAVE_FCNTL_LOCK) */
617 int create_lock_file(char *fname, const char *progname, const char *filetype, POOLMEM **errmsg, int *fd)
623 /* Open the pidfile for writing */
624 if ((*fd = open(fname, O_CREAT|O_RDWR, 0640)) >= 0) {
625 if (fcntl_lock(*fd, F_WRLCK) == -1) {
627 /* already locked by someone else, try to read the pid */
628 if (read(*fd, &pidbuf, sizeof(pidbuf)) > 0 &&
629 sscanf(pidbuf, "%d", &oldpid) == 1) {
630 Mmsg(errmsg, _("%s is already running. pid=%d, check file %s\n"),
631 progname, oldpid, fname);
633 Mmsg(errmsg, _("Cannot lock %s file. %s ERR=%s\n"), filetype, fname, be.bstrerror());
640 len = sprintf(pidbuf, "%d\n", (int)getpid());
641 write(*fd, pidbuf, len);
642 /* KEEP THE FILE OPEN TO KEEP THE LOCK !!! */
646 Mmsg(errmsg, _("Cannot not open %s file. %s ERR=%s\n"), filetype, fname, be.bstrerror());
653 * Create a standard "Unix" pid file.
655 void create_pid_file(char *dir, const char *progname, int port)
657 POOLMEM *errmsg = get_pool_memory(PM_MESSAGE);
658 POOLMEM *fname = get_pool_memory(PM_FNAME);
660 Mmsg(fname, "%s/%s.%d.pid", dir, progname, port);
661 if (create_lock_file(fname, progname, "pid", &errmsg, &pid_fd) == 0) {
662 Emsg1(M_ERROR_TERM, 0, "%s", errmsg);
665 #if !defined(HAVE_WIN32)
666 del_pid_file_ok = TRUE; /* we created it so we can delete it */
669 free_pool_memory(fname);
670 free_pool_memory(errmsg);
674 * Delete the pid file if we created it
676 int delete_pid_file(char *dir, const char *progname, int port)
678 #if !defined(HAVE_WIN32)
679 POOLMEM *fname = get_pool_memory(PM_FNAME);
683 if (!del_pid_file_ok) {
684 free_pool_memory(fname);
687 del_pid_file_ok = FALSE;
688 Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
690 free_pool_memory(fname);
698 uint64_t last_jobs_addr;
699 uint64_t reserved[20];
702 static struct s_state_hdr state_hdr = {
709 * Open and read the state file for the daemon
711 void read_state_file(char *dir, const char *progname, int port)
716 POOLMEM *fname = get_pool_memory(PM_FNAME);
717 struct s_state_hdr hdr;
718 int hdr_size = sizeof(hdr);
720 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
721 /* If file exists, see what we have */
722 // Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
723 if ((sfd = open(fname, O_RDONLY|O_BINARY)) < 0) {
725 Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
726 sfd, (int)sizeof(hdr), be.bstrerror());
729 if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
731 Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n",
732 sfd, (int)stat, hdr_size, be.bstrerror());
735 if (hdr.version != state_hdr.version) {
736 Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
737 state_hdr.version, hdr.version);
741 if (strcmp(hdr.id, state_hdr.id) != 0) {
742 Dmsg0(000, "State file header id invalid.\n");
745 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
746 if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) {
757 free_pool_memory(fname);
761 * Write the state file
763 static pthread_mutex_t state_mutex = PTHREAD_MUTEX_INITIALIZER;
765 void write_state_file(char *dir, const char *progname, int port)
769 POOLMEM *fname = get_pool_memory(PM_FNAME);
771 P(state_mutex); /* Only one job at a time can call here */
772 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
773 /* Create new state file */
775 if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
777 Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.bstrerror());
778 Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.bstrerror());
781 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
783 Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror());
786 // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
787 state_hdr.last_jobs_addr = sizeof(state_hdr);
788 state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
789 // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
790 if (lseek(sfd, 0, SEEK_SET) < 0) {
792 Dmsg1(000, "lseek error: ERR=%s\n", be.bstrerror());
795 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
797 Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.bstrerror());
801 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
810 free_pool_memory(fname);
814 /* BSDI does not have this. This is a *poor* simulation */
817 strtoll(const char *ptr, char **endptr, int base)
819 return (long long int)strtod(ptr, endptr);
824 * Bacula's implementation of fgets(). The difference is that it handles
825 * being interrupted by a signal (e.g. a SIGCHLD).
828 char *bfgets(char *s, int size, FILE *fd)
833 for (int i=0; i < size-1; i++) {
837 } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN));
847 if (ch == '\r') { /* Support for Mac/Windows file format */
849 if (ch != '\n') { /* Mac (\r only) */
850 (void)ungetc(ch, fd); /* Push next character back to fd */
863 * Bacula's implementation of fgets(). The difference is that it handles
864 * being interrupted by a signal (e.g. a SIGCHLD) and it has a
865 * different calling sequence which implements input lines of
866 * up to a million characters.
868 char *bfgets(POOLMEM *&s, FILE *fd)
875 soft_max = sizeof_pool_memory(s) - 10;
880 } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN));
890 if (soft_max > 1000000) {
893 s = check_pool_memory_size(s, soft_max+10000);
894 soft_max = sizeof_pool_memory(s) - 10;
898 if (ch == '\r') { /* Support for Mac/Windows file format */
900 if (ch != '\n') { /* Mac (\r only) */
901 (void)ungetc(ch, fd); /* Push next character back to fd */
914 * Make a "unique" filename. It is important that if
915 * called again with the same "what" that the result
916 * will be identical. This allows us to use the file
917 * without saving its name, and re-generate the name
918 * so that it can be deleted.
920 void make_unique_filename(POOLMEM **name, int Id, char *what)
922 Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);
925 char *escape_filename(const char *file_path)
927 if (file_path == NULL || strpbrk(file_path, "\"\\") == NULL) {
931 char *escaped_path = (char *)bmalloc(2 * (strlen(file_path) + 1));
932 char *cur_char = escaped_path;
935 if (*file_path == '\\' || *file_path == '"') {
939 *cur_char++ = *file_path++;
948 * For the moment preventing suspensions is only
949 * implemented on Windows.
952 void prevent_os_suspensions()
955 void allow_os_suspensions()
960 #if HAVE_BACKTRACE && HAVE_GCC
961 /* if some names are not resolved you can try using : addr2line, like this
962 * $ addr2line -e bin/bacula-sd -a 0x43cd11
964 * use the the -rdynamic option in the linker, like this
965 * $ LDFLAGS="-rdynamic" make setup
968 #include <execinfo.h>
971 const size_t max_depth = 100;
973 void *stack_addrs[max_depth];
974 char **stack_strings;
976 stack_depth = backtrace(stack_addrs, max_depth);
977 stack_strings = backtrace_symbols(stack_addrs, stack_depth);
979 for (size_t i = 3; i < stack_depth; i++) {
980 size_t sz = 200; /* just a guess, template names will go much wider */
981 char *function = (char *)actuallymalloc(sz);
982 char *begin = 0, *end = 0;
983 /* find the parentheses and address offset surrounding the mangled name */
984 for (char *j = stack_strings[i]; *j; ++j) {
987 } else if (*j == '+') {
994 /* found our mangled name, now in [begin, end] */
997 char *ret = abi::__cxa_demangle(begin, function, &sz, &status);
999 /* return value may be a realloc() of the input */
1002 /* demangling failed, just pretend it's a C function with no args */
1003 strncpy(function, begin, sz);
1004 strncat(function, "()", sz);
1005 function[sz-1] = '\0';
1007 Pmsg2(000, " %s:%s\n", stack_strings[i], function);
1010 /* didn't find the mangled name, just print the whole line */
1011 Pmsg1(000, " %s\n", stack_strings[i]);
1013 actuallyfree(function);
1015 actuallyfree(stack_strings); /* malloc()ed by backtrace_symbols */
1017 #else /* HAVE_BACKTRACE && HAVE_GCC */
1018 void stack_trace() {}
1019 #endif /* HAVE_BACKTRACE && HAVE_GCC */
1021 #ifdef HAVE_SYS_STATVFS_H
1022 #include <sys/statvfs.h>
1024 #define statvfs statfs
1026 /* statvfs.h defines ST_APPEND, which is also used by Bacula */
1030 int fs_get_free_space(const char *path, int64_t *freeval, int64_t *totalval)
1033 /* For Windows must have statvfs */
1034 #if defined(HAVE_WIN32)
1035 #if !defined(HAVE_SYS_STATVFS_H)
1036 *totalval = *freeval = 0;
1043 if (statvfs(path, &st) == 0) {
1044 *freeval = (uint64_t)st.f_bavail * (uint64_t)st.f_frsize;
1045 *totalval = (uint64_t)st.f_blocks * (uint64_t)st.f_frsize;
1049 *totalval = *freeval = 0;
1053 /* This function is used after a fork, the memory manager is not be initialized
1054 * properly, so we must stay simple.
1056 void setup_env(char *envp[])
1059 #if defined(HAVE_SETENV)
1061 for (int i=0; envp[i] ; i++) {
1062 p = strchr(envp[i], '='); /* HOME=/tmp */
1064 *p=0; /* HOME\0tmp\0 */
1065 setenv(envp[i], p+1, true);
1069 #elif defined(HAVE_PUTENV)
1070 for (int i=0; envp[i] ; i++) {
1074 #error "putenv() and setenv() are not available on this system"
1079 /* Small function to copy a file somewhere else,
1080 * for debug purpose.
1082 int copyfile(const char *src, const char *dst)
1084 int fd_src=-1, fd_dst=-1;
1088 fd_src = open(src, O_RDONLY);
1090 Dmsg2(0, "Unable to open %s ERR=%s\n", src, be.bstrerror(errno));
1093 fd_dst = open(dst, O_WRONLY | O_CREAT | O_EXCL, 0600);
1095 Dmsg2(0, "Unable to open %s ERR=%s\n", dst, be.bstrerror(errno));
1099 while ((len = read(fd_src, buf, sizeof(buf))) > 0)
1101 char *out_ptr = buf;
1103 lenw = write(fd_dst, out_ptr, len);
1107 } else if (errno != EINTR) {
1108 Dmsg3(0, "Unable to write %d bytes in %s. ERR=%s\n", len, dst, be.bstrerror(errno));
1116 if (close(fd_dst) < 0) {
1117 Dmsg2(0, "Unable to close %s properly. ERR=%s\n", dst, be.bstrerror(errno));
1129 /* The poll() code is currently disabled */
1135 int fd_wait_data(int fd, fd_wait_mode mode, int sec, int msec)
1138 struct pollfd fds[NB_EVENT]; /* The structure for one event */
1141 fds[0].events = (mode == WAIT_READ) ? POLLIN : POLLOUT;
1143 ret = poll(fds, NB_EVENT, sec * 1000 + msec);
1145 /* Check if poll actually succeed */
1147 case 0: /* timeout; no event detected */
1150 case -1: /* report error and abort */
1154 if (fds[0].revents & POLLIN || fds[0].revents & POLLOUT) {
1158 return -1; /* unexpected... */
1161 return -1; /* unexpected... */
1165 /* The select() code with a bigger fd_set was tested on Linux, FreeBSD and SunOS */
1166 #if defined(HAVE_LINUX_OS) || defined(HAVE_FREEBSD_OS) || defined(HAVE_SUN_OS) || defined(HAVE_WIN32)
1167 #define SELECT_MAX_FD 7990
1169 #define SELECT_MAX_FD 1023 /* For others, we keep it low */
1172 int fd_wait_data(int fd, fd_wait_mode mode, int sec, int msec)
1175 /* TODO: Allocate the fd_set when fd > SELECT_MAX_FD */
1183 if (fd > SELECT_MAX_FD) {
1184 Pmsg1(0, "Too many open files for the current system fd=%d\n", fd);
1188 memset(&bfd_buf, 0, sizeof(bfd_buf)); /* FD_ZERO(&fdset) */
1189 FD_SET((unsigned)fd, &fdset);
1192 tv.tv_usec = msec * 1000;
1194 if (mode == WAIT_READ) {
1195 ret = select(fd + 1, &fdset, NULL, NULL, &tv);
1197 } else { /* WAIT_WRITE */
1198 ret = select(fd + 1, NULL, &fdset, NULL, &tv);
1202 case 0: /* timeout */
1205 return -1; /* error return */
1213 /* Use SOCK_CLOEXEC option when calling accept(). If not available,
1214 * do it ourself (but with a race condition...)
1216 int baccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
1220 fd = accept4(sockfd, addr, addrlen, SOCK_CLOEXEC);
1222 fd = accept(sockfd, addr, addrlen);
1224 # ifdef HAVE_DECL_FD_CLOEXEC
1226 int tmp_errno = errno;
1227 if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC) < 0) {
1229 Dmsg2(0, "Unable to set the CLOEXEC flag on fd=%d ERR=%s\n", fd, be.bstrerror());
1234 # endif /* HAVE_DECL_FD_CLOEXEC */
1235 #endif /* HAVE_ACCEPT4 */
1240 FILE *bfopen(const char *path, const char *mode)
1245 bstrncpy(options, mode, sizeof(options));
1247 #if defined(HAVE_STREAM_CLOEXEC)
1248 bstrncat(options, STREAM_CLOEXEC, sizeof(options));
1251 fp = fopen(path, options);
1253 #if !defined(HAVE_STREAM_CLOEXEC) && defined(HAVE_DECL_FD_CLOEXEC)
1255 int fd = fileno(fp);
1257 int tmp_errno = errno;
1258 if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC) < 0) {
1260 Dmsg2(0, "Unable to set the CLOEXEC flag on fd=%d ERR=%s\n", fd, be.bstrerror());
1271 /* The main idea of the test is pretty simple, we have a writer and a reader, and
1272 * they wait a little bit to read or send data over the fifo.
1273 * So, for the first packets, the writer will wait, then the reader will wait
1274 * read/write requests should always be fast. Only the time of the fd_wait_data()
1277 #include "findlib/namedpipe.h"
1278 #define PIPENAME "/tmp/wait.pipe.%d"
1280 #define NBPACKETS 10
1281 #define BUFSIZE 128*512 /* The pipe size looks to be 65K */
1289 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
1290 pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
1303 bsnprintf(buf, sizeof(buf), PIPENAME, j->nb);
1304 if (namedpipe_create(&p, buf, 0600) < 0) {
1306 Dmsg2(0, "R: Unable to create the fifo %s. ERR=%s\n", buf, be.bstrerror());
1310 fd = namedpipe_open(&p, buf, O_RDONLY);
1313 Dmsg2(0, "R: Unable to open the fifo %s. ERR=%s\n", buf, be.bstrerror());
1318 pthread_cond_wait(&cond, &cond_mutex);
1320 for (int i = 0; i < NBPACKETS; i++) {
1321 if (i < (NBPACKETS/2)) {
1324 s = get_current_btime();
1325 r = fd_wait_data(fd, WAIT_READ, 10, 0);
1327 e = get_current_btime();
1328 Dmsg2(0, "Wait to read pkt %d %lldms\n",i, (int64_t) (e - s));
1330 if (i <= NBPACKETS/2) {
1331 ASSERT2((e-s) < 10000, "In the 1st phase, we are blocking the process");
1333 ASSERT2((e-s) > 10000, "In the 2nd phase, the writer is slowing down things");
1336 s = get_current_btime();
1337 nb = read(fd, buf, sizeof(buf));
1338 e = get_current_btime();
1339 Dmsg3(0, "Read pkt %d %d bytes in %lldms\n",i, (int)nb, (int64_t) (e - s));
1340 ASSERT2((e-s) < 10000, "The read operation should be FAST");
1356 bsnprintf(buf, sizeof(buf), PIPENAME, j->nb);
1358 if (namedpipe_create(&p, buf, 0600) < 0) {
1360 Dmsg2(0, "W: Unable to create the fifo %s. ERR=%s\n", buf, be.bstrerror());
1365 fd = namedpipe_open(&p, buf, O_WRONLY);
1368 Dmsg2(0, "W: Unable to open the fifo %s. ERR=%s\n", buf, be.bstrerror());
1375 pthread_cond_wait(&cond, &cond_mutex);
1380 for (int i=0; i < NBPACKETS; i++) {
1381 if (i > (NBPACKETS/2)) {
1384 s = get_current_btime();
1385 if (fd_wait_data(fd, WAIT_WRITE, 10, 0) > 0) {
1386 e = get_current_btime();
1387 Dmsg2(0, "Wait to write pkt %d %lldms\n",i, (int64_t) (e - s));
1389 if (i == 0 || i > NBPACKETS/2) { /* The first packet doesn't count */
1390 ASSERT2((e-s) < 100000, "In the 2nd phase, it's fast to send, we are the blocker");
1392 ASSERT2((e-s) > 100000, "In the 1st phase, we wait for the reader");
1395 s = get_current_btime();
1396 nb = write(fd, buf, sizeof(buf));
1397 e = get_current_btime();
1398 Dmsg3(0, "Wrote pkt %d %d bytes in %lldms\n", i, (int)nb, (int64_t) (e - s));
1399 ASSERT2((e-s) < 100000, "The write operation should never block");
1406 int main(int argc, char **argv)
1408 job pthread_list[10000];
1409 int j = (argc >= 2) ? atoi(argv[1]) : 1;
1410 int maxfd = (argc == 3) ? atoi(argv[2]) : 0;
1415 set_debug_flags((char *)"h");
1417 for (int i=3; i < maxfd; i++) {
1418 open("/dev/null", O_RDONLY);
1421 for (int i=0; i < j; i++) {
1422 pthread_list[i].nb=i;
1423 pthread_create(&pthread_list[i].writer, NULL, th2, &pthread_list[i]);
1424 pthread_create(&pthread_list[i].reader, NULL, th1, &pthread_list[i]);
1427 while (nb_ready < j*2) {
1431 Dmsg0(0, "All threads are started\n");
1433 pthread_cond_broadcast(&cond);
1436 for (int i=0; i < j; i++) {
1437 pthread_join(pthread_list[i].writer, NULL);
1438 pthread_join(pthread_list[i].reader, NULL);
1441 for (int i=3; i < maxfd; i++) {