1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

initial version

(This used to be ctdb commit 5bba7deef9b03a68d336c138e83d6d4fac35bfce)
This commit is contained in:
Andrew Tridgell 2006-11-18 10:41:20 +11:00
commit 6613b7d438
37 changed files with 32281 additions and 0 deletions

61
ctdb/Makefile.in Normal file
View File

@ -0,0 +1,61 @@
#!gmake
#
CC = @CC@
prefix = @prefix@
exec_prefix = @exec_prefix@
datarootdir = @datarootdir@
includedir = @includedir@
libdir = @libdir@
bindir = @bindir@
VPATH = @srcdir@:@tdbdir@:@tallocdir@:@libreplacedir@
srcdir = @srcdir@
builddir = @builddir@
EXTRA_OBJ=@EXTRA_OBJ@
CFLAGS=-g -I$(srcdir)/include -Iinclude -I$(srcdir) \
-I@tallocdir@ -I@tdbdir@/include -I@libreplacedir@ \
-DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"@SHLIBEXT@\" -DUSE_MMAP=1 @CFLAGS@
LIB_FLAGS=@LDFLAGS@ -Llib @LIBS@ -lpopt
EVENTS_OBJ = lib/events/events.o lib/events/events_standard.o
CTDB_OBJ = ctdb_tcp_child.o ctdb_tcp.o util.o
OBJS = @TDBOBJ@ @TALLOCOBJ@ @LIBREPLACEOBJ@ $(EXTRA_OBJ) $(EVENTS_OBJ) $(CTDB_OBJ)
BINS = bin/ctdb_test
DIRS = lib bin
all: showflags dirs $(OBJS) $(BINS)
showflags:
@echo 'ctdb will be compiled with flags:'
@echo ' CFLAGS = $(CFLAGS)'
@echo ' LIBS = $(LIBS)'
.c.o:
@echo Compiling $*.c
@mkdir -p `dirname $@`
@$(CC) $(CFLAGS) -c $< -o $@
dirs:
@mkdir -p $(DIRS)
bin/ctdb_test: $(OBJS) ctdb_test.o
@echo Linking $@
@$(CC) $(CFLAGS) -o $@ ctdb_test.o $(OBJS) $(LIB_FLAGS)
clean:
rm -f *.o */*.o
rm -f $(BINS)
distclean: clean
rm -f *~ */*~
rm -rf bin lib
rm -f config.log config.status config.cache include/config.h
rm -f Makefile
realdistclean: distclean
rm -f configure.in include/config.h.in

1
ctdb/aclocal.m4 vendored Normal file
View File

@ -0,0 +1 @@
m4_include(libreplace.m4)

17
ctdb/autogen.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
rm -rf autom4te.cache
rm -f configure config.h.in
IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace"
IPATHS="$IPATHS -I lib/talloc -I talloc -I ../talloc"
IPATHS="$IPATHS -I lib/tdb -I tdb -I ../tdb"
IPATHS="$IPATHS -I lib/popt -I popt -I ../popt"
autoheader $IPATHS || exit 1
autoconf $IPATHS || exit 1
rm -rf autom4te.cache
echo "Now run ./configure and then make."
exit 0

1466
ctdb/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

712
ctdb/config.h Normal file
View File

@ -0,0 +1,712 @@
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Whether strndup is broken */
/* #undef BROKEN_STRNDUP */
/* Whether strnlen is broken */
/* #undef BROKEN_STRNLEN */
/* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the `asprintf' function. */
#define HAVE_ASPRINTF 1
/* Whether the bool type is available */
#define HAVE_BOOL 1
/* Define to 1 if you have the `bzero' function. */
#define HAVE_BZERO 1
/* Whether there is a C99 compliant vsnprintf */
#define HAVE_C99_VSNPRINTF 1
/* Define to 1 if you have the `chroot' function. */
#define HAVE_CHROOT 1
/* Define to 1 if you have the `chsize' function. */
/* #undef HAVE_CHSIZE */
/* Whether or not we have comparison_fn_t */
#define HAVE_COMPARISON_FN_T 1
/* Define to 1 if you have the <compat.h> header file. */
/* #undef HAVE_COMPAT_H */
/* Define to 1 if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define to 1 if you have the declaration of `asprintf', and to 0 if you
don't. */
#define HAVE_DECL_ASPRINTF 1
/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
don't. */
#define HAVE_DECL_SNPRINTF 1
/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
don't. */
#define HAVE_DECL_VASPRINTF 1
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
don't. */
#define HAVE_DECL_VSNPRINTF 1
/* Define to 1 if you have the <direct.h> header file. */
/* #undef HAVE_DIRECT_H */
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the `dlclose' function. */
#define HAVE_DLCLOSE 1
/* Define to 1 if you have the `dlerror' function. */
#define HAVE_DLERROR 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `dlopen' function. */
#define HAVE_DLOPEN 1
/* Define to 1 if you have the `dlsym' function. */
#define HAVE_DLSYM 1
/* Define to 1 if you have the `endnetgrent' function. */
#define HAVE_ENDNETGRENT 1
/* Define to 1 if you have the `epoll_create' function. */
#define HAVE_EPOLL_CREATE 1
/* Whether errno() is available */
#define HAVE_ERRNO_DECL 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <fnmatch.h> header file. */
#define HAVE_FNMATCH_H 1
/* Define to 1 if you have the `ftruncate' function. */
#define HAVE_FTRUNCATE 1
/* Whether there is a __FUNCTION__ macro */
#define HAVE_FUNCTION_MACRO 1
/* Define to 1 if you have the `getdents' function. */
/* #undef HAVE_GETDENTS */
/* Define to 1 if you have the `getdirentries' function. */
/* #undef HAVE_GETDIRENTRIES */
/* Define to 1 if you have the `getnetgrent' function. */
#define HAVE_GETNETGRENT 1
/* Define to 1 if you have the <getopt.h> header file. */
#define HAVE_GETOPT_H 1
/* Define to 1 if you have the `getpagesize' function. */
#define HAVE_GETPAGESIZE 1
/* Define to 1 if you have the `getpgrp' function. */
#define HAVE_GETPGRP 1
/* Define to 1 if you have the <grp.h> header file. */
#define HAVE_GRP_H 1
/* Whether the compiler supports immediate structures */
#define HAVE_IMMEDIATE_STRUCTURES 1
/* Define to 1 if you have the `initgroups' function. */
#define HAVE_INITGROUPS 1
/* Define to 1 if you have the `innetgr' function. */
#define HAVE_INNETGR 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <locale.h> header file. */
#define HAVE_LOCALE_H 1
/* Define to 1 if the system has the type `long long'. */
#define HAVE_LONG_LONG 1
/* Define to 1 if you have the `lstat' function. */
#define HAVE_LSTAT 1
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define if target mkdir supports mode option */
#define HAVE_MKDIR_MODE 1
/* Define to 1 if you have the `mkdtemp' function. */
#define HAVE_MKDTEMP 1
/* Define to 1 if you have the `mktime' function. */
#define HAVE_MKTIME 1
/* Define to 1 if you have the `mmap' function. */
#define HAVE_MMAP 1
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the <netdb.h> header file. */
#define HAVE_NETDB_H 1
/* Define to 1 if you have the <netinet/in.h> header file. */
#define HAVE_NETINET_IN_H 1
/* Define to 1 if you have the <netinet/in_ip.h> header file. */
/* #undef HAVE_NETINET_IN_IP_H */
/* Define to 1 if you have the <netinet/in_systm.h> header file. */
#define HAVE_NETINET_IN_SYSTM_H 1
/* Define to 1 if you have the <netinet/ip.h> header file. */
#define HAVE_NETINET_IP_H 1
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#define HAVE_NETINET_TCP_H 1
/* usability of net/if.h */
#define HAVE_NET_IF_H 1
/* Whether the open(2) accepts O_DIRECT */
/* #undef HAVE_OPEN_O_DIRECT */
/* Define to 1 if you have the `pipe' function. */
#define HAVE_PIPE 1
/* Define to 1 if you have the `pread' function. */
#define HAVE_PREAD 1
/* Whether pread() is available */
#define HAVE_PREAD_DECL 1
/* Define to 1 if you have the `printf' function. */
#define HAVE_PRINTF 1
/* Define to 1 if you have the <pwd.h> header file. */
#define HAVE_PWD_H 1
/* Define to 1 if you have the `pwrite' function. */
#define HAVE_PWRITE 1
/* Whether pwrite() is available */
#define HAVE_PWRITE_DECL 1
/* Define to 1 if you have the `rand' function. */
#define HAVE_RAND 1
/* Define to 1 if you have the `random' function. */
#define HAVE_RANDOM 1
/* Define to 1 if you have the `rename' function. */
#define HAVE_RENAME 1
/* Whether mkstemp is secure */
#define HAVE_SECURE_MKSTEMP 1
/* Define to 1 if you have the `setbuffer' function. */
#define HAVE_SETBUFFER 1
/* Define to 1 if you have the `setegid' function. */
#define HAVE_SETEGID 1
/* Define to 1 if you have the `setenv' function. */
#define HAVE_SETENV 1
/* Define to 1 if you have the `seteuid' function. */
#define HAVE_SETEUID 1
/* Define to 1 if you have the `setlinebuf' function. */
#define HAVE_SETLINEBUF 1
/* Define to 1 if you have the `setnetgrent' function. */
#define HAVE_SETNETGRENT 1
/* Define to 1 if you have the `setresgid' function. */
#define HAVE_SETRESGID 1
/* Whether setresgid() is available */
#define HAVE_SETRESGID_DECL 1
/* Define to 1 if you have the `setresuid' function. */
#define HAVE_SETRESUID 1
/* Whether setresuid() is available */
#define HAVE_SETRESUID_DECL 1
/* Define to 1 if you have the <shadow.h> header file. */
#define HAVE_SHADOW_H 1
/* Whether we have the atomic_t variable type */
#define HAVE_SIG_ATOMIC_T_TYPE 1
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
/* Define to 1 if you have the `socketpair' function. */
#define HAVE_SOCKETPAIR 1
/* Define to 1 if you have the `srand' function. */
#define HAVE_SRAND 1
/* Define to 1 if you have the `srandom' function. */
#define HAVE_SRANDOM 1
/* Define to 1 if you have the <standards.h> header file. */
/* #undef HAVE_STANDARDS_H */
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdbool.h> header file. */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strcasestr' function. */
#define HAVE_STRCASESTR 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the `strftime' function. */
#define HAVE_STRFTIME 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcat' function. */
/* #undef HAVE_STRLCAT */
/* Define to 1 if you have the `strlcpy' function. */
/* #undef HAVE_STRLCPY */
/* Define to 1 if you have the `strndup' function. */
#define HAVE_STRNDUP 1
/* Define to 1 if you have the `strnlen' function. */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the `strtok_r' function. */
#define HAVE_STRTOK_R 1
/* Define to 1 if you have the `strtoll' function. */
#define HAVE_STRTOLL 1
/* Define to 1 if you have the `strtoq' function. */
#define HAVE_STRTOQ 1
/* Define to 1 if you have the `strtoull' function. */
#define HAVE_STRTOULL 1
/* Define to 1 if you have the `strtouq' function. */
#define HAVE_STRTOUQ 1
/* Define to 1 if `st_rdev' is member of `struct stat'. */
#define HAVE_STRUCT_STAT_ST_RDEV 1
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
`HAVE_STRUCT_STAT_ST_RDEV' instead. */
#define HAVE_ST_RDEV 1
/* Define to 1 if you have the `syslog' function. */
#define HAVE_SYSLOG 1
/* Define to 1 if you have the <syslog.h> header file. */
#define HAVE_SYSLOG_H 1
/* Define to 1 if you have the <sys/acl.h> header file. */
#define HAVE_SYS_ACL_H 1
/* Define to 1 if you have the <sys/capability.h> header file. */
/* #undef HAVE_SYS_CAPABILITY_H */
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_DIR_H */
/* Define to 1 if you have the <sys/epoll.h> header file. */
#define HAVE_SYS_EPOLL_H 1
/* Define to 1 if you have the <sys/fcntl.h> header file. */
#define HAVE_SYS_FCNTL_H 1
/* Define to 1 if you have the <sys/filio.h> header file. */
/* #undef HAVE_SYS_FILIO_H */
/* Define to 1 if you have the <sys/filsys.h> header file. */
/* #undef HAVE_SYS_FILSYS_H */
/* Define to 1 if you have the <sys/fs/s5param.h> header file. */
/* #undef HAVE_SYS_FS_S5PARAM_H */
/* Define to 1 if you have the <sys/id.h> header file. */
/* #undef HAVE_SYS_ID_H */
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 1
/* Define to 1 if you have the <sys/ipc.h> header file. */
#define HAVE_SYS_IPC_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/mode.h> header file. */
/* #undef HAVE_SYS_MODE_H */
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/param.h> header file. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/priv.h> header file. */
/* #undef HAVE_SYS_PRIV_H */
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/security.h> header file. */
/* #undef HAVE_SYS_SECURITY_H */
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/shm.h> header file. */
#define HAVE_SYS_SHM_H 1
/* Define to 1 if you have the <sys/socket.h> header file. */
#define HAVE_SYS_SOCKET_H 1
/* Define to 1 if you have the <sys/sockio.h> header file. */
/* #undef HAVE_SYS_SOCKIO_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/syslog.h> header file. */
#define HAVE_SYS_SYSLOG_H 1
/* Define to 1 if you have the <sys/termio.h> header file. */
/* #undef HAVE_SYS_TERMIO_H */
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/un.h> header file. */
#define HAVE_SYS_UN_H 1
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 1
/* Define to 1 if you have the <termio.h> header file. */
#define HAVE_TERMIO_H 1
/* Define to 1 if you have the `timegm' function. */
#define HAVE_TIMEGM 1
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `usleep' function. */
#define HAVE_USLEEP 1
/* Define to 1 if you have the `utime' function. */
#define HAVE_UTIME 1
/* Define to 1 if you have the <utime.h> header file. */
#define HAVE_UTIME_H 1
/* Define to 1 if you have the <vararg.h> header file. */
/* #undef HAVE_VARARG_H */
/* Define to 1 if you have the `vasprintf' function. */
#define HAVE_VASPRINTF 1
/* Whether va_copy() is available */
#define HAVE_VA_COPY 1
/* Whether the C compiler understands volatile */
#define HAVE_VOLATILE 1
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
/* Define to 1 if you have the `vsyslog' function. */
#define HAVE_VSYSLOG 1
/* Define to 1 if you have the `waitpid' function. */
#define HAVE_WAITPID 1
/* Define to 1 if you have the <windows.h> header file. */
/* #undef HAVE_WINDOWS_H */
/* Define to 1 if you have the <winsock2.h> header file. */
/* #undef HAVE_WINSOCK2_H */
/* Define to 1 if you have the <ws2tcpip.h> header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Whether the _Bool type is available */
#define HAVE__Bool 1
/* Whether the __VA_ARGS__ macro is available */
#define HAVE__VA_ARGS__MACRO 1
/* Define to 1 if you have the `__strtoll' function. */
/* #undef HAVE___STRTOLL */
/* Define to 1 if you have the `__strtoull' function. */
/* #undef HAVE___STRTOULL */
/* Whether __va_copy() is available */
/* #undef HAVE___VA_COPY */
/* Whether there is a __func__ macro */
/* #undef HAVE_func_MACRO */
/* Whether MMAP is broken */
/* #undef MMAP_BLACKLIST */
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* Whether getpass should be replaced */
/* #undef REPLACE_GETPASS */
/* Whether inet_ntoa should be replaced */
/* #undef REPLACE_INET_NTOA */
/* replace readdir */
/* #undef REPLACE_READDIR */
/* replace readdir using getdents() */
/* #undef REPLACE_READDIR_GETDENTS */
/* replace readdir using getdirentries() */
/* #undef REPLACE_READDIR_GETDIRENTRIES */
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Whether seekdir returns an int */
/* #undef SEEKDIR_RETURNS_INT */
/* The size of `char', as computed by sizeof. */
#define SIZEOF_CHAR 1
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG 4
/* The size of `long long', as computed by sizeof. */
#define SIZEOF_LONG_LONG 8
/* The size of `off_t', as computed by sizeof. */
#define SIZEOF_OFF_T 8
/* The size of `short', as computed by sizeof. */
#define SIZEOF_SHORT 2
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4
/* The size of `ssize_t', as computed by sizeof. */
#define SIZEOF_SSIZE_T 4
/* The size of `void *', as computed by sizeof. */
#define SIZEOF_VOID_P 4
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Whether telldir takes a const pointer */
/* #undef TELLDIR_TAKES_CONST_DIR */
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */
/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
/* # undef _ALL_SOURCE */
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#define _FILE_OFFSET_BITS 64
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
#ifndef _OSF_SOURCE
# define _OSF_SOURCE 1
#endif
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Whether to enable POSIX support */
/* #undef _POSIX_C_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
/* Whether to enable System V compatibility */
/* #undef _SYSV */
#ifndef _XOPEN_SOURCE_EXTENDED
# define _XOPEN_SOURCE_EXTENDED 1
#endif
/* Enable extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef gid_t */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef ino_t */
/* Define to `short' if <sys/types.h> does not define. */
/* #undef int16_t */
/* Define to `long' if <sys/types.h> does not define. */
/* #undef int32_t */
/* Define to `long long' if <sys/types.h> does not define. */
/* #undef int64_t */
/* Define to `char' if <sys/types.h> does not define. */
/* #undef int8_t */
/* Define to `unsigned long long' if <sys/types.h> does not define. */
/* #undef intptr_t */
/* Define to `off_t' if <sys/types.h> does not define. */
/* #undef loff_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef mode_t */
/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to `loff_t' if <sys/types.h> does not define. */
#define offset_t loff_t
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */
/* Define to `unsigned long long' if <sys/types.h> does not define. */
/* #undef ptrdiff_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
/* Socket length type */
/* #undef socklen_t */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef ssize_t */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef uid_t */
/* Define to `unsigned short' if <sys/types.h> does not define. */
/* #undef uint16_t */
/* Define to `unsigned long' if <sys/types.h> does not define. */
/* #undef uint32_t */
/* Define to `unsigned long long' if <sys/types.h> does not define. */
/* #undef uint64_t */
/* Define to `unsigned char' if <sys/types.h> does not define. */
/* #undef uint8_t */
/* Define to `unsigned int' if <sys/types.h> does not define. */
#define uint_t unsigned int

711
ctdb/config.h.in Normal file
View File

@ -0,0 +1,711 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Whether strndup is broken */
#undef BROKEN_STRNDUP
/* Whether strnlen is broken */
#undef BROKEN_STRNLEN
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF
/* Whether the bool type is available */
#undef HAVE_BOOL
/* Define to 1 if you have the `bzero' function. */
#undef HAVE_BZERO
/* Whether there is a C99 compliant vsnprintf */
#undef HAVE_C99_VSNPRINTF
/* Define to 1 if you have the `chroot' function. */
#undef HAVE_CHROOT
/* Define to 1 if you have the `chsize' function. */
#undef HAVE_CHSIZE
/* Whether or not we have comparison_fn_t */
#undef HAVE_COMPARISON_FN_T
/* Define to 1 if you have the <compat.h> header file. */
#undef HAVE_COMPAT_H
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if you have the declaration of `asprintf', and to 0 if you
don't. */
#undef HAVE_DECL_ASPRINTF
/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
don't. */
#undef HAVE_DECL_SNPRINTF
/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
don't. */
#undef HAVE_DECL_VASPRINTF
/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
don't. */
#undef HAVE_DECL_VSNPRINTF
/* Define to 1 if you have the <direct.h> header file. */
#undef HAVE_DIRECT_H
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
/* Define to 1 if you have the `dlclose' function. */
#undef HAVE_DLCLOSE
/* Define to 1 if you have the `dlerror' function. */
#undef HAVE_DLERROR
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `dlopen' function. */
#undef HAVE_DLOPEN
/* Define to 1 if you have the `dlsym' function. */
#undef HAVE_DLSYM
/* Define to 1 if you have the `endnetgrent' function. */
#undef HAVE_ENDNETGRENT
/* Define to 1 if you have the `epoll_create' function. */
#undef HAVE_EPOLL_CREATE
/* Whether errno() is available */
#undef HAVE_ERRNO_DECL
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the <fnmatch.h> header file. */
#undef HAVE_FNMATCH_H
/* Define to 1 if you have the `ftruncate' function. */
#undef HAVE_FTRUNCATE
/* Whether there is a __FUNCTION__ macro */
#undef HAVE_FUNCTION_MACRO
/* Define to 1 if you have the `getdents' function. */
#undef HAVE_GETDENTS
/* Define to 1 if you have the `getdirentries' function. */
#undef HAVE_GETDIRENTRIES
/* Define to 1 if you have the `getnetgrent' function. */
#undef HAVE_GETNETGRENT
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
/* Define to 1 if you have the `getpagesize' function. */
#undef HAVE_GETPAGESIZE
/* Define to 1 if you have the `getpgrp' function. */
#undef HAVE_GETPGRP
/* Define to 1 if you have the <grp.h> header file. */
#undef HAVE_GRP_H
/* Whether the compiler supports immediate structures */
#undef HAVE_IMMEDIATE_STRUCTURES
/* Define to 1 if you have the `initgroups' function. */
#undef HAVE_INITGROUPS
/* Define to 1 if you have the `innetgr' function. */
#undef HAVE_INNETGR
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if the system has the type `long long'. */
#undef HAVE_LONG_LONG
/* Define to 1 if you have the `lstat' function. */
#undef HAVE_LSTAT
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define if target mkdir supports mode option */
#undef HAVE_MKDIR_MODE
/* Define to 1 if you have the `mkdtemp' function. */
#undef HAVE_MKDTEMP
/* Define to 1 if you have the `mktime' function. */
#undef HAVE_MKTIME
/* Define to 1 if you have the `mmap' function. */
#undef HAVE_MMAP
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/in_ip.h> header file. */
#undef HAVE_NETINET_IN_IP_H
/* Define to 1 if you have the <netinet/in_systm.h> header file. */
#undef HAVE_NETINET_IN_SYSTM_H
/* Define to 1 if you have the <netinet/ip.h> header file. */
#undef HAVE_NETINET_IP_H
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
/* usability of net/if.h */
#undef HAVE_NET_IF_H
/* Whether the open(2) accepts O_DIRECT */
#undef HAVE_OPEN_O_DIRECT
/* Define to 1 if you have the `pipe' function. */
#undef HAVE_PIPE
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
/* Whether pread() is available */
#undef HAVE_PREAD_DECL
/* Define to 1 if you have the `printf' function. */
#undef HAVE_PRINTF
/* Define to 1 if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
/* Define to 1 if you have the `pwrite' function. */
#undef HAVE_PWRITE
/* Whether pwrite() is available */
#undef HAVE_PWRITE_DECL
/* Define to 1 if you have the `rand' function. */
#undef HAVE_RAND
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
/* Define to 1 if you have the `rename' function. */
#undef HAVE_RENAME
/* Whether mkstemp is secure */
#undef HAVE_SECURE_MKSTEMP
/* Define to 1 if you have the `setbuffer' function. */
#undef HAVE_SETBUFFER
/* Define to 1 if you have the `setegid' function. */
#undef HAVE_SETEGID
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
/* Define to 1 if you have the `seteuid' function. */
#undef HAVE_SETEUID
/* Define to 1 if you have the `setlinebuf' function. */
#undef HAVE_SETLINEBUF
/* Define to 1 if you have the `setnetgrent' function. */
#undef HAVE_SETNETGRENT
/* Define to 1 if you have the `setresgid' function. */
#undef HAVE_SETRESGID
/* Whether setresgid() is available */
#undef HAVE_SETRESGID_DECL
/* Define to 1 if you have the `setresuid' function. */
#undef HAVE_SETRESUID
/* Whether setresuid() is available */
#undef HAVE_SETRESUID_DECL
/* Define to 1 if you have the <shadow.h> header file. */
#undef HAVE_SHADOW_H
/* Whether we have the atomic_t variable type */
#undef HAVE_SIG_ATOMIC_T_TYPE
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if you have the `socketpair' function. */
#undef HAVE_SOCKETPAIR
/* Define to 1 if you have the `srand' function. */
#undef HAVE_SRAND
/* Define to 1 if you have the `srandom' function. */
#undef HAVE_SRANDOM
/* Define to 1 if you have the <standards.h> header file. */
#undef HAVE_STANDARDS_H
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stdbool.h> header file. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcasestr' function. */
#undef HAVE_STRCASESTR
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
#undef HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strndup' function. */
#undef HAVE_STRNDUP
/* Define to 1 if you have the `strnlen' function. */
#undef HAVE_STRNLEN
/* Define to 1 if you have the `strtok_r' function. */
#undef HAVE_STRTOK_R
/* Define to 1 if you have the `strtoll' function. */
#undef HAVE_STRTOLL
/* Define to 1 if you have the `strtoq' function. */
#undef HAVE_STRTOQ
/* Define to 1 if you have the `strtoull' function. */
#undef HAVE_STRTOULL
/* Define to 1 if you have the `strtouq' function. */
#undef HAVE_STRTOUQ
/* Define to 1 if `st_rdev' is member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_RDEV
/* Define to 1 if your `struct stat' has `st_rdev'. Deprecated, use
`HAVE_STRUCT_STAT_ST_RDEV' instead. */
#undef HAVE_ST_RDEV
/* Define to 1 if you have the `syslog' function. */
#undef HAVE_SYSLOG
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/acl.h> header file. */
#undef HAVE_SYS_ACL_H
/* Define to 1 if you have the <sys/capability.h> header file. */
#undef HAVE_SYS_CAPABILITY_H
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_DIR_H
/* Define to 1 if you have the <sys/epoll.h> header file. */
#undef HAVE_SYS_EPOLL_H
/* Define to 1 if you have the <sys/fcntl.h> header file. */
#undef HAVE_SYS_FCNTL_H
/* Define to 1 if you have the <sys/filio.h> header file. */
#undef HAVE_SYS_FILIO_H
/* Define to 1 if you have the <sys/filsys.h> header file. */
#undef HAVE_SYS_FILSYS_H
/* Define to 1 if you have the <sys/fs/s5param.h> header file. */
#undef HAVE_SYS_FS_S5PARAM_H
/* Define to 1 if you have the <sys/id.h> header file. */
#undef HAVE_SYS_ID_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/ipc.h> header file. */
#undef HAVE_SYS_IPC_H
/* Define to 1 if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define to 1 if you have the <sys/mode.h> header file. */
#undef HAVE_SYS_MODE_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_NDIR_H
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/priv.h> header file. */
#undef HAVE_SYS_PRIV_H
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/security.h> header file. */
#undef HAVE_SYS_SECURITY_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/shm.h> header file. */
#undef HAVE_SYS_SHM_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/sockio.h> header file. */
#undef HAVE_SYS_SOCKIO_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/syslog.h> header file. */
#undef HAVE_SYS_SYSLOG_H
/* Define to 1 if you have the <sys/termio.h> header file. */
#undef HAVE_SYS_TERMIO_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
/* Define to 1 if you have the `timegm' function. */
#undef HAVE_TIMEGM
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `usleep' function. */
#undef HAVE_USLEEP
/* Define to 1 if you have the `utime' function. */
#undef HAVE_UTIME
/* Define to 1 if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
/* Define to 1 if you have the <vararg.h> header file. */
#undef HAVE_VARARG_H
/* Define to 1 if you have the `vasprintf' function. */
#undef HAVE_VASPRINTF
/* Whether va_copy() is available */
#undef HAVE_VA_COPY
/* Whether the C compiler understands volatile */
#undef HAVE_VOLATILE
/* Define to 1 if you have the `vsnprintf' function. */
#undef HAVE_VSNPRINTF
/* Define to 1 if you have the `vsyslog' function. */
#undef HAVE_VSYSLOG
/* Define to 1 if you have the `waitpid' function. */
#undef HAVE_WAITPID
/* Define to 1 if you have the <windows.h> header file. */
#undef HAVE_WINDOWS_H
/* Define to 1 if you have the <winsock2.h> header file. */
#undef HAVE_WINSOCK2_H
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#undef HAVE_WS2TCPIP_H
/* Whether the _Bool type is available */
#undef HAVE__Bool
/* Whether the __VA_ARGS__ macro is available */
#undef HAVE__VA_ARGS__MACRO
/* Define to 1 if you have the `__strtoll' function. */
#undef HAVE___STRTOLL
/* Define to 1 if you have the `__strtoull' function. */
#undef HAVE___STRTOULL
/* Whether __va_copy() is available */
#undef HAVE___VA_COPY
/* Whether there is a __func__ macro */
#undef HAVE_func_MACRO
/* Whether MMAP is broken */
#undef MMAP_BLACKLIST
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Whether getpass should be replaced */
#undef REPLACE_GETPASS
/* Whether inet_ntoa should be replaced */
#undef REPLACE_INET_NTOA
/* replace readdir */
#undef REPLACE_READDIR
/* replace readdir using getdents() */
#undef REPLACE_READDIR_GETDENTS
/* replace readdir using getdirentries() */
#undef REPLACE_READDIR_GETDIRENTRIES
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Whether seekdir returns an int */
#undef SEEKDIR_RETURNS_INT
/* The size of `char', as computed by sizeof. */
#undef SIZEOF_CHAR
/* The size of `int', as computed by sizeof. */
#undef SIZEOF_INT
/* The size of `long', as computed by sizeof. */
#undef SIZEOF_LONG
/* The size of `long long', as computed by sizeof. */
#undef SIZEOF_LONG_LONG
/* The size of `off_t', as computed by sizeof. */
#undef SIZEOF_OFF_T
/* The size of `short', as computed by sizeof. */
#undef SIZEOF_SHORT
/* The size of `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T
/* The size of `ssize_t', as computed by sizeof. */
#undef SIZEOF_SSIZE_T
/* The size of `void *', as computed by sizeof. */
#undef SIZEOF_VOID_P
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Whether telldir takes a const pointer */
#undef TELLDIR_TAKES_CONST_DIR
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to 1 if on AIX 3.
System headers sometimes define this.
We just want to avoid a redefinition error message. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to 1 if on MINIX. */
#undef _MINIX
#ifndef _OSF_SOURCE
# define _OSF_SOURCE 1
#endif
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Whether to enable POSIX support */
#undef _POSIX_C_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Whether to enable System V compatibility */
#undef _SYSV
#ifndef _XOPEN_SOURCE_EXTENDED
# define _XOPEN_SOURCE_EXTENDED 1
#endif
/* Enable extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef ino_t
/* Define to `short' if <sys/types.h> does not define. */
#undef int16_t
/* Define to `long' if <sys/types.h> does not define. */
#undef int32_t
/* Define to `long long' if <sys/types.h> does not define. */
#undef int64_t
/* Define to `char' if <sys/types.h> does not define. */
#undef int8_t
/* Define to `unsigned long long' if <sys/types.h> does not define. */
#undef intptr_t
/* Define to `off_t' if <sys/types.h> does not define. */
#undef loff_t
/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define to `loff_t' if <sys/types.h> does not define. */
#undef offset_t
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `unsigned long long' if <sys/types.h> does not define. */
#undef ptrdiff_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Socket length type */
#undef socklen_t
/* Define to `int' if <sys/types.h> does not define. */
#undef ssize_t
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t
/* Define to `unsigned short' if <sys/types.h> does not define. */
#undef uint16_t
/* Define to `unsigned long' if <sys/types.h> does not define. */
#undef uint32_t
/* Define to `unsigned long long' if <sys/types.h> does not define. */
#undef uint64_t
/* Define to `unsigned char' if <sys/types.h> does not define. */
#undef uint8_t
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef uint_t

1021
ctdb/config.status Executable file

File diff suppressed because it is too large Load Diff

1579
ctdb/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

22878
ctdb/configure vendored Executable file

File diff suppressed because it is too large Load Diff

32
ctdb/configure.ac Normal file
View File

@ -0,0 +1,32 @@
AC_PREREQ(2.50)
AC_DEFUN([AC_CHECK_LIB_EXT], [
AC_CHECK_LIB([$1],[$3],[$4],[$5],[$7])
ac_cv_lib_ext_$1_$3=$ac_cv_lib_$1_$3
])
AC_DEFUN([AC_CHECK_FUNC_EXT], [
AC_CHECK_FUNC([$1],[$3],[$4])
ac_cv_func_ext_$1=$ac_cv_func_$1
])
AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""])
AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""])
AC_DEFUN([SMB_EXT_LIB], [echo -n ""])
AC_DEFUN([SMB_ENABLE], [echo -n ""])
AC_INIT(ctdb.h)
AC_CONFIG_SRCDIR([ctdb_daemon.c])
AC_LIBREPLACE_ALL_CHECKS
if test "$ac_cv_prog_gcc" = yes; then
CFLAGS="$CFLAGS -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings"
fi
AC_CONFIG_HEADER(config.h)
EXTRA_OBJ=""
m4_include(libtalloc.m4)
m4_include(libtdb.m4)
AC_SUBST(EXTRA_OBJ)
AC_OUTPUT(Makefile)

74
ctdb/ctdb.h Normal file
View File

@ -0,0 +1,74 @@
/*
ctdb database library
Copyright (C) Andrew Tridgell 2006
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
structure passed to a ctdb call function
*/
struct ctdb_call {
TDB_DATA key; /* record key */
TDB_DATA record_data; /* current data in the record */
TDB_DATA *new_data; /* optionally updated record data */
TDB_DATA *call_data; /* optionally passed from caller */
TDB_DATA *reply_data; /* optionally returned by function */
};
#define CTDB_ERR_INVALID 1
#define CTDB_ERR_NOMEM 2
/*
initialise ctdb subsystem
*/
struct ctdb_context *ctdb_init(TALLOC_CTX *mem_ctx);
/*
tell ctdb what nodes are available. This takes a filename, which will contain
1 node address per line, in a transport specific format
*/
int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist);
/*
error string for last ctdb error
*/
const char *ctdb_errstr(struct ctdb_context *);
/* a ctdb call function */
typedef int (*ctdb_fn_t)(struct ctdb_call *);
/*
setup a ctdb call function
*/
int ctdb_set_call(struct ctdb_context *ctdb, ctdb_fn_t fn, int id);
/*
attach to a ctdb database
*/
int ctdb_attach(struct ctdb_context *ctdb, const char *name, int tdb_flags,
int open_flags, mode_t mode);
/*
make a ctdb call. The associated ctdb call function will be called on the DMASTER
for the given record
*/
int ctdb_call(struct ctdb_context *ctdb, TDB_DATA key, int call_id,
TDB_DATA *call_data, TDB_DATA *reply_data);

20
ctdb/ctdb_daemon.c Normal file
View File

@ -0,0 +1,20 @@
/*
ctdb database library
Copyright (C) Andrew Tridgell 2006
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

59
ctdb/ctdb_private.h Normal file
View File

@ -0,0 +1,59 @@
/*
ctdb database library
Copyright (C) Andrew Tridgell 2006
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
a pending ctdb request
*/
struct ctdb_request {
};
/*
an installed ctdb remote call
*/
struct ctdb_registered_call {
struct ctdb_registered_call *next, *prev;
uint32_t id;
ctdb_fn_t fn;
};
/*
state associated with one node
*/
struct ctdb_node {
struct ctdb_context *ctdb;
struct ctdb_node *next, *prev;
const char *address;
int port;
int fd;
};
/* main state of the ctdb daemon */
struct ctdb_context {
struct event_context *ev;
struct ctdb_node *nodes; /* list of nodes in the cluster */
struct ctdb_registered_call *calls; /* list of registered calls */
char *err_msg;
struct tdb_context *ltdb;
};
#define CTDB_SOCKET "/tmp/ctdb.sock"

218
ctdb/ctdb_tcp.c Normal file
View File

@ -0,0 +1,218 @@
/*
ctdb over TCP
Copyright (C) Andrew Tridgell 2006
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "includes.h"
#include "lib/events/events.h"
#include "system/network.h"
#include "system/filesys.h"
#include "ctdb_private.h"
/*
initialise the ctdb daemon.
if the ctdb dispatcher daemon has already been started then this
does nothing. Otherwise it forks the ctdb dispatcher daemon and
starts the daemons connecting to each other
NOTE: In current code the daemon does not fork. This is for testing purposes only
and to simplify the code.
*/
struct ctdb_context *ctdb_init(TALLOC_CTX *mem_ctx)
{
struct ctdb_context *ctdb;
ctdb = talloc_zero(mem_ctx, struct ctdb_context);
return ctdb;
}
const char *ctdb_errstr(struct ctdb_context *ctdb)
{
return ctdb->err_msg;
}
/*
remember an error message
*/
static void ctdb_set_error(struct ctdb_context *ctdb, const char *fmt, ...)
{
va_list ap;
talloc_free(ctdb->err_msg);
va_start(ap, fmt);
ctdb->err_msg = talloc_vasprintf(ctdb, fmt, ap);
va_end(ap);
}
/*
called when socket becomes readable
*/
static void ctdb_node_read(struct event_context *ev, struct fd_event *fde,
uint16_t flags, void *private)
{
struct ctdb_node *node = talloc_get_type(private, struct ctdb_node);
printf("connection to node %s:%u is readable\n", node->address, node->port);
event_set_fd_flags(fde, 0);
}
static void ctdb_node_connect(struct event_context *ev, struct timed_event *te,
struct timeval t, void *private);
/*
called when socket becomes writeable on connect
*/
static void ctdb_node_connect_write(struct event_context *ev, struct fd_event *fde,
uint16_t flags, void *private)
{
struct ctdb_node *node = talloc_get_type(private, struct ctdb_node);
struct ctdb_context *ctdb = node->ctdb;
int error;
socklen_t len;
if (getsockopt(node->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0 ||
errno != 0) {
close(node->fd);
event_add_timed(ctdb->ev, node, timeval_current_ofs(1, 0),
ctdb_node_connect, node);
return;
}
printf("Established connection to %s:%u\n", node->address, node->port);
talloc_free(fde);
event_add_fd(node->ctdb->ev, node, node->fd, EVENT_FD_READ,
ctdb_node_read, node);
}
/*
called when we should try and establish a tcp connection to a node
*/
static void ctdb_node_connect(struct event_context *ev, struct timed_event *te,
struct timeval t, void *private)
{
struct ctdb_node *node = talloc_get_type(node, struct ctdb_node);
struct ctdb_context *ctdb = node->ctdb;
unsigned v;
struct sockaddr_in sock_out;
node->fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
v = fcntl(node->fd, F_GETFL, 0);
fcntl(node->fd, F_SETFL, v | O_NONBLOCK);
inet_pton(AF_INET, node->address, &sock_out.sin_addr);
sock_out.sin_port = htons(node->port);
sock_out.sin_family = PF_INET;
if (connect(node->fd, &sock_out, sizeof(sock_out)) != 0 &&
errno != EINPROGRESS) {
/* try again once a second */
close(node->fd);
event_add_timed(ctdb->ev, node, timeval_current_ofs(1, 0),
ctdb_node_connect, node);
return;
}
/* non-blocking connect - wait for write event */
event_add_fd(node->ctdb->ev, node, node->fd, EVENT_FD_WRITE,
ctdb_node_connect_write, node);
}
/*
add a node to the list of active nodes
*/
static int ctdb_add_node(struct ctdb_context *ctdb, char *nstr)
{
struct ctdb_node *node;
/* expected to be in IP:port format */
char *p;
p = strchr(nstr, ':');
if (p == NULL) {
ctdb_set_error(ctdb, "Badly formed node '%s'\n", nstr);
return -1;
}
*p++ = 0;
node = talloc(ctdb, struct ctdb_node);
node->address = talloc_strdup(node, nstr);
node->port = strtoul(p, NULL, 0);
node->fd = -1;
node->ctdb = ctdb;
DLIST_ADD(ctdb->nodes, node);
event_add_timed(ctdb->ev, node, timeval_zero(), ctdb_node_connect, node);
return 0;
}
/*
setup the node list from a file
*/
int ctdb_set_nlist(struct ctdb_context *ctdb, const char *nlist)
{
char **lines;
int nlines;
int i;
lines = file_lines_load(nlist, &nlines, ctdb);
if (lines == NULL) {
ctdb_set_error(ctdb, "Failed to load nlist '%s'\n", nlist);
return -1;
}
for (i=0;i<nlines;i++) {
if (ctdb_add_node(ctdb, lines[i]) != 0) {
talloc_free(lines);
return -1;
}
}
talloc_free(lines);
return 0;
}
/*
add a node to the list of active nodes
*/
int ctdb_set_call(struct ctdb_context *ctdb, ctdb_fn_t fn, int id)
{
struct ctdb_registered_call *call;
call = talloc(ctdb, struct ctdb_registered_call);
call->fn = fn;
call->id = id;
DLIST_ADD(ctdb->calls, call);
return 0;
}
/*
attach to a specific database
*/
int ctdb_attach(struct ctdb_context *ctdb, const char *name, int tdb_flags,
int open_flags, mode_t mode)
{
ctdb->ltdb = tdb_open(name, 0, TDB_INTERNAL, 0, 0);
if (ctdb->ltdb == NULL) {
ctdb_set_error(ctdb, "Failed to open tdb %s\n", name);
return -1;
}
return 0;
}

70
ctdb/ctdb_tcp_child.c Normal file
View File

@ -0,0 +1,70 @@
/*
ctdb over TCP
Copyright (C) Andrew Tridgell 2006
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "includes.h"
#include "system/network.h"
#include "system/filesys.h"
#include "ctdb_private.h"
struct ctdb_child_state {
int sock;
struct event_context *ev;
};
/*
create a unix domain socket and bind it
return a file descriptor open on the socket
*/
static int ux_socket_bind(const char *name)
{
int fd;
struct sockaddr_un addr;
/* get rid of any old socket */
unlink(name);
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd == -1) return -1;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, name, sizeof(addr.sun_path));
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
close(fd);
return -1;
}
return fd;
}
/*
start the ctdb tcp child daemon
*/
int ctdb_tcp_child(void)
{
struct ctdb_child_state *state;
state = talloc(NULL, struct ctdb_child_state);
state->sock = ux_socket_bind(CTDB_SOCKET);
return 0;
}

166
ctdb/ctdb_test.c Normal file
View File

@ -0,0 +1,166 @@
/*
ctdb test harness
Copyright (C) Andrew Tridgell 2006
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "replace.h"
#include "system/filesys.h"
#include "tdb.h"
#include "talloc.h"
#include "ctdb.h"
#include "popt.h"
enum my_functions {FUNC_SORT=1, FUNC_FETCH=2};
static int int_compare(int *i1, int *i2)
{
return *i1 - *i2;
}
/*
add an integer into a record in sorted order
*/
static int sort_func(struct ctdb_call *call)
{
if (call->call_data == NULL ||
call->call_data->dsize != sizeof(int)) {
return CTDB_ERR_INVALID;
}
call->new_data = talloc(call, TDB_DATA);
if (call->new_data == NULL) {
return CTDB_ERR_NOMEM;
}
call->new_data->dptr = talloc_size(call,
call->record_data.dsize +
call->call_data->dsize);
if (call->new_data->dptr == NULL) {
return CTDB_ERR_NOMEM;
}
call->new_data->dsize = call->record_data.dsize + call->call_data->dsize;
memcpy(call->new_data->dptr+call->record_data.dsize,
call->call_data->dptr, call->call_data->dsize);
qsort(call->new_data->dptr, call->new_data->dsize / sizeof(int),
sizeof(int), (comparison_fn_t)int_compare);
return 0;
}
/*
ctdb call function to fetch a record
*/
static int fetch_func(struct ctdb_call *call)
{
call->reply_data = &call->record_data;
return 0;
}
/*
main program
*/
int main(int argc, const char *argv[])
{
struct ctdb_context *ctdb;
const char *nlist = NULL;
struct poptOption popt_options[] = {
POPT_AUTOHELP
{ "nlist", 0, POPT_ARG_STRING, &nlist, 0, "node list file", "filename" },
};
int opt;
const char **extra_argv;
int extra_argc = 0;
int i, ret;
TDB_DATA key, data;
poptContext pc;
pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
while ((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
default:
fprintf(stderr, "Invalid option %s: %s\n",
poptBadOption(pc, 0), poptStrerror(opt));
exit(1);
}
}
/* setup the remaining options for the main program to use */
extra_argv = poptGetArgs(pc);
if (extra_argv) {
extra_argv++;
while (extra_argv[extra_argc]) extra_argc++;
}
if (nlist == NULL) {
printf("You must provide a node list with --nlist\n");
exit(1);
}
/* initialise ctdb */
ctdb = ctdb_init(NULL);
if (ctdb == NULL) {
printf("Failed to init ctdb\n");
exit(1);
}
/* tell ctdb what nodes are available */
ret = ctdb_set_nlist(ctdb, nlist);
if (ret == -1) {
printf("ctdb_set_nlist failed - %s\n", ctdb_errstr(ctdb));
exit(1);
}
/* setup a ctdb call function */
ret = ctdb_set_call(ctdb, sort_func, FUNC_SORT);
ret = ctdb_set_call(ctdb, fetch_func, FUNC_FETCH);
/* attach to a specific database */
ret = ctdb_attach(ctdb, "test.tdb", TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0666);
if (ret == -1) {
printf("ctdb_attach failed - %s\n", ctdb_errstr(ctdb));
exit(1);
}
key.dptr = "test";
key.dsize = strlen("test")+1;
/* add some random data */
for (i=0;i<100;i++) {
int v = random();
data.dptr = (uint8_t *)&v;
data.dsize = sizeof(v);
ret = ctdb_call(ctdb, key, FUNC_SORT, &data, NULL);
if (ret == -1) {
printf("ctdb_call FUNC_SORT failed - %s\n", ctdb_errstr(ctdb));
exit(1);
}
}
/* fetch the record */
ret = ctdb_call(ctdb, key, FUNC_FETCH, NULL, &data);
if (ret == -1) {
printf("ctdb_call FUNC_FETCH failed - %s\n", ctdb_errstr(ctdb));
exit(1);
}
for (i=0;i<data.dsize/sizeof(int);i++) {
printf("%3d\n", ((int *)data.dptr)[i]);
}
/* shut it down */
talloc_free(ctdb);
return 0;
}

29
ctdb/includes.h Normal file
View File

@ -0,0 +1,29 @@
#define HAVE_UNIXSOCKET 1
#include "replace.h"
#include "talloc.h"
#include "tdb.h"
#include "ctdb.h"
#include "dlinklist.h"
typedef bool BOOL;
#define True 1
#define False 0
#define DEBUG(lvl, x) printf x
#define _PUBLIC_
#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x))
struct timeval timeval_zero(void);
bool timeval_is_zero(const struct timeval *tv);
struct timeval timeval_current(void);
struct timeval timeval_set(uint32_t secs, uint32_t usecs);
int timeval_compare(const struct timeval *tv1, const struct timeval *tv2);
struct timeval timeval_until(const struct timeval *tv1,
const struct timeval *tv2);
_PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs);
char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx);

238
ctdb/install-sh Executable file
View File

@ -0,0 +1,238 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View File

@ -0,0 +1,7 @@
K 10
svn:ignore
V 14
.sconsign
*.d
END

View File

@ -0,0 +1,112 @@
8
dir
19729
svn+ssh://tridge@cvs.samba.org/home/svn/samba/branches/SAMBA_4_0/source/lib/events
svn+ssh://tridge@cvs.samba.org/home/svn/samba
2006-08-30T11:29:34.384714Z
17930
jelmer
has-props
svn:special svn:externals svn:needs-lock
0c0555d6-39d7-0310-84fc-f1cc0bd64818
config.m4
file
2005-02-15T10:04:21.000000Z
1282a085894097e490c4362dd2bfc4bb
2005-02-03T11:56:03.346078Z
5197
tridge
events_standard.c
file
2006-09-01T04:14:43.000000Z
5c3eae22143044dbb2bcba2a5eaafca2
2006-08-30T11:29:34.384714Z
17930
jelmer
events.c
file
2006-03-08T00:18:09.000000Z
5cb1576c79a1680a1439c07e5cd84079
2006-03-05T17:44:16.286806Z
13842
jelmer
events_internal.h
file
2005-12-09T23:46:11.000000Z
c77ab0d0a4b0db529ccf1175e50d7ff2
2005-12-09T16:43:19.753634Z
12140
metze
events_liboop.c
file
2006-05-24T07:14:55.000000Z
26a6f3a336c876daad780ed71dd8018a
2006-05-24T07:34:11.364684Z
15854
tridge
events.h
file
2006-03-20T03:25:13.000000Z
576e09771a89f8540d0314e5b81e74a8
2006-03-18T15:42:57.807892Z
14542
jelmer
config.mk
file
2006-04-29T08:13:02.000000Z
c3df7aca33e0005d86c389a8f5a04441
2006-04-24T15:47:59.920131Z
15207
jelmer

View File

@ -0,0 +1 @@
8

View File

@ -0,0 +1,2 @@
AC_CHECK_HEADERS(sys/epoll.h)
AC_CHECK_FUNCS(epoll_create)

View File

@ -0,0 +1,7 @@
##############################
# Start SUBSYSTEM LIBEVENTS
[SUBSYSTEM::LIBEVENTS]
OBJ_FILES = events.o events_standard.o
PUBLIC_DEPENDENCIES = LIBTALLOC
# End SUBSYSTEM LIBEVENTS
##############################

View File

@ -0,0 +1,175 @@
/*
Unix SMB/CIFS implementation.
main select loop and event handling
Copyright (C) Andrew Tridgell 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
PLEASE READ THIS BEFORE MODIFYING!
This module is a general abstraction for the main select loop and
event handling. Do not ever put any localised hacks in here, instead
register one of the possible event types and implement that event
somewhere else.
There are 2 types of event handling that are handled in this module:
1) a file descriptor becoming readable or writeable. This is mostly
used for network sockets, but can be used for any type of file
descriptor. You may only register one handler for each file
descriptor/io combination or you will get unpredictable results
(this means that you can have a handler for read events, and a
separate handler for write events, but not two handlers that are
both handling read events)
2) a timed event. You can register an event that happens at a
specific time. You can register as many of these as you
like. They are single shot - add a new timed event in the event
handler to get another event.
To setup a set of events you first need to create a event_context
structure using the function event_context_init(); This returns a
'struct event_context' that you use in all subsequent calls.
After that you can add/remove events that you are interested in
using event_add_*() and talloc_free()
Finally, you call event_loop_wait_once() to block waiting for one of the
events to occor or event_loop_wait() which will loop
forever.
*/
#include "includes.h"
#include "lib/events/events.h"
#include "lib/events/events_internal.h"
/*
create a event_context structure for a specific implemementation.
This must be the first events call, and all subsequent calls pass
this event_context as the first element. Event handlers also
receive this as their first argument.
This function is for allowing third-party-applications to hook in gluecode
to their own event loop code, so that they can make async usage of our client libs
NOTE: use event_context_init() inside of samba!
*/
struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct event_ops *ops, void *private_data)
{
struct event_context *ev;
int ret;
ev = talloc_zero(mem_ctx, struct event_context);
if (!ev) return NULL;
ev->ops = ops;
ret = ev->ops->context_init(ev, private_data);
if (ret != 0) {
talloc_free(ev);
return NULL;
}
return ev;
}
/*
create a event_context structure. This must be the first events
call, and all subsequent calls pass this event_context as the first
element. Event handlers also receive this as their first argument.
*/
struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
{
const struct event_ops *ops = event_standard_get_ops();
return event_context_init_ops(mem_ctx, ops, NULL);
}
/*
add a fd based event
return NULL on failure (memory allocation error)
*/
struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
int fd, uint16_t flags, event_fd_handler_t handler,
void *private_data)
{
return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
}
/*
return the fd event flags
*/
uint16_t event_get_fd_flags(struct fd_event *fde)
{
if (!fde) return 0;
return fde->event_ctx->ops->get_fd_flags(fde);
}
/*
set the fd event flags
*/
void event_set_fd_flags(struct fd_event *fde, uint16_t flags)
{
if (!fde) return;
fde->event_ctx->ops->set_fd_flags(fde, flags);
}
/*
add a timed event
return NULL on failure
*/
struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private_data)
{
return ev->ops->add_timed(ev, mem_ctx, next_event, handler, private_data);
}
/*
do a single event loop using the events defined in ev
*/
_PUBLIC_ int event_loop_once(struct event_context *ev)
{
return ev->ops->loop_once(ev);
}
/*
return on failure or (with 0) if all fd events are removed
*/
int event_loop_wait(struct event_context *ev)
{
return ev->ops->loop_wait(ev);
}
/*
find an event context that is a parent of the given memory context,
or create a new event context as a child of the given context if
none is found
This should be used in preference to event_context_init() in places
where you would prefer to use the existing event context if possible
(which is most situations)
*/
struct event_context *event_context_find(TALLOC_CTX *mem_ctx)
{
struct event_context *ev = talloc_find_parent_bytype(mem_ctx, struct event_context);
if (ev == NULL) {
ev = event_context_init(mem_ctx);
}
return ev;
}

View File

@ -0,0 +1,71 @@
/*
Unix SMB/CIFS implementation.
generalised event loop handling
Copyright (C) Andrew Tridgell 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __EVENTS_H__
#define __EVENTS_H__
struct event_context;
struct event_ops;
struct fd_event;
struct timed_event;
/* event handler types */
typedef void (*event_fd_handler_t)(struct event_context *, struct fd_event *,
uint16_t , void *);
typedef void (*event_timed_handler_t)(struct event_context *, struct timed_event *,
struct timeval , void *);
struct event_context *event_context_init(TALLOC_CTX *mem_ctx);
struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct event_ops *ops, void *private_data);
struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
int fd, uint16_t flags, event_fd_handler_t handler,
void *private);
struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private);
int event_loop_once(struct event_context *ev);
int event_loop_wait(struct event_context *ev);
uint16_t event_get_fd_flags(struct fd_event *fde);
void event_set_fd_flags(struct fd_event *fde, uint16_t flags);
struct event_context *event_context_find(TALLOC_CTX *mem_ctx);
/* bits for file descriptor event flags */
#define EVENT_FD_READ 1
#define EVENT_FD_WRITE 2
#define EVENT_FD_WRITEABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
#define EVENT_FD_READABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ)
#define EVENT_FD_NOT_WRITEABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE)
#define EVENT_FD_NOT_READABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ)
#endif /* __EVENTS_H__ */

View File

@ -0,0 +1,81 @@
/*
Unix SMB/CIFS implementation.
generalised event loop handling
Internal structs
Copyright (C) Stefan Metzmacher 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
struct event_ops {
/* conntext init */
int (*context_init)(struct event_context *ev, void *private_data);
/* fd_event functions */
struct fd_event *(*add_fd)(struct event_context *ev,
TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
event_fd_handler_t handler,
void *private_data);
uint16_t (*get_fd_flags)(struct fd_event *fde);
void (*set_fd_flags)(struct fd_event *fde, uint16_t flags);
/* timed_event functions */
struct timed_event *(*add_timed)(struct event_context *ev,
TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private_data);
/* loop functions */
int (*loop_once)(struct event_context *ev);
int (*loop_wait)(struct event_context *ev);
};
struct fd_event {
struct fd_event *prev, *next;
struct event_context *event_ctx;
int fd;
uint16_t flags; /* see EVENT_FD_* flags */
event_fd_handler_t handler;
/* this is private for the specific handler */
void *private_data;
/* this is private for the events_ops implementation */
uint16_t additional_flags;
void *additional_data;
};
struct timed_event {
struct timed_event *prev, *next;
struct event_context *event_ctx;
struct timeval next_event;
event_timed_handler_t handler;
/* this is private for the specific handler */
void *private_data;
/* this is private for the events_ops implementation */
void *additional_data;
};
struct event_context {
/* the specific events implementation */
const struct event_ops *ops;
/* this is private for the events_ops implementation */
void *additional_data;
};
const struct event_ops *event_standard_get_ops(void);

View File

@ -0,0 +1,284 @@
/*
Unix SMB/CIFS implementation.
main select loop and event handling
wrapper for http://liboop.org/
Copyright (C) Stefan Metzmacher 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/events/events.h"
#include "lib/events/events_internal.h"
#include <oop.h>
/*
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NOTE: this code compiles fine, but is completly *UNTESTED*
and is only commited as example
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
static int oop_event_context_destructor(struct event_context *ev)
{
oop_source_sys *oop_sys = ev->additional_data;
oop_sys_delete(oop_sys);
return 0;
}
/*
create a oop_event_context structure.
*/
static int oop_event_context_init(struct event_context *ev, void *private_data)
{
oop_source_sys *oop_sys = private_data;
if (!oop_sys) {
oop_sys = oop_sys_new();
if (!oop_sys) {
return -1;
}
talloc_set_destructor(ev, oop_event_context_destructor);
}
ev->additional_data = oop_sys;
return 0;
}
static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr)
{
struct fd_event *fde = ptr;
if (fd != fde->fd) return OOP_ERROR;
switch(oop_type) {
case OOP_READ:
fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data);
return OOP_CONTINUE;
case OOP_WRITE:
fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data);
return OOP_CONTINUE;
case OOP_EXCEPTION:
return OOP_ERROR;
case OOP_NUM_EVENTS:
return OOP_ERROR;
}
return OOP_ERROR;
}
/*
destroy an fd_event
*/
static int oop_event_fd_destructor(struct fd_event *fde)
{
struct event_context *ev = fde->event_ctx;
oop_source_sys *oop_sys = ev->additional_data;
oop_source *oop = oop_sys_source(oop_sys);
if (fde->flags & EVENT_FD_READ)
oop->cancel_fd(oop, fde->fd, OOP_READ);
if (fde->flags & EVENT_FD_WRITE)
oop->cancel_fd(oop, fde->fd, OOP_WRITE);
return 0;
}
/*
add a fd based event
return NULL on failure (memory allocation error)
*/
static struct fd_event *oop_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
event_fd_handler_t handler,
void *private_data)
{
struct fd_event *fde;
oop_source_sys *oop_sys = ev->additional_data;
oop_source *oop = oop_sys_source(oop_sys);
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
if (!fde) return NULL;
fde->event_ctx = ev;
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
fde->private_data = private_data;
fde->additional_flags = 0;
fde->additional_data = NULL;
if (fde->flags & EVENT_FD_READ)
oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
if (fde->flags & EVENT_FD_WRITE)
oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
talloc_set_destructor(fde, oop_event_fd_destructor);
return fde;
}
/*
return the fd event flags
*/
static uint16_t oop_event_get_fd_flags(struct fd_event *fde)
{
return fde->flags;
}
/*
set the fd event flags
*/
static void oop_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
{
oop_source_sys *oop_sys;
oop_source *oop;
oop_sys = fde->event_ctx->additional_data;
oop = oop_sys_source(oop_sys);
if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ)))
oop->cancel_fd(oop, fde->fd, OOP_READ);
if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ))
oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE)))
oop->cancel_fd(oop, fde->fd, OOP_WRITE);
if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE))
oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
fde->flags = flags;
}
static int oop_event_timed_destructor(struct timed_event *te);
static int oop_event_timed_deny_destructor(struct timed_event *te)
{
return -1;
}
static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr)
{
struct timed_event *te = ptr;
/* deny the handler to free the event */
talloc_set_destructor(te, oop_event_timed_deny_destructor);
te->handler(te->event_ctx, te, t, te->private_data);
talloc_set_destructor(te, oop_event_timed_destructor);
talloc_free(te);
return OOP_CONTINUE;
}
/*
destroy a timed event
*/
static int oop_event_timed_destructor(struct timed_event *te)
{
struct event_context *ev = te->event_ctx;
oop_source_sys *oop_sys = ev->additional_data;
oop_source *oop = oop_sys_source(oop_sys);
oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te);
return 0;
}
/*
add a timed event
return NULL on failure (memory allocation error)
*/
static struct timed_event *oop_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private_data)
{
oop_source_sys *oop_sys = ev->additional_data;
oop_source *oop = oop_sys_source(oop_sys);
struct timed_event *te;
te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
if (te == NULL) return NULL;
te->event_ctx = ev;
te->next_event = next_event;
te->handler = handler;
te->private_data = private_data;
te->additional_data = NULL;
oop->on_time(oop, te->next_event, oop_event_timed_handler, te);
talloc_set_destructor(te, oop_event_timed_destructor);
return te;
}
/*
do a single event loop using the events defined in ev
*/
static int oop_event_loop_once(struct event_context *ev)
{
void *oop_ret;
oop_source_sys *oop_sys = ev->additional_data;
oop_ret = oop_sys_run_once(oop_sys);
if (oop_ret == OOP_CONTINUE) {
return 0;
}
return -1;
}
/*
return on failure or (with 0) if all fd events are removed
*/
static int oop_event_loop_wait(struct event_context *ev)
{
void *oop_ret;
oop_source_sys *oop_sys = ev->additional_data;
oop_ret = oop_sys_run(oop_sys);
if (oop_ret == OOP_CONTINUE) {
return 0;
}
return -1;
}
static const struct event_ops event_oop_ops = {
.context_init = oop_event_context_init,
.add_fd = oop_event_add_fd,
.get_fd_flags = oop_event_get_fd_flags,
.set_fd_flags = oop_event_set_fd_flags,
.add_timed = oop_event_add_timed,
.loop_once = oop_event_loop_once,
.loop_wait = oop_event_loop_wait,
};
const struct event_ops *event_liboop_get_ops(void)
{
return &event_oop_ops;
}

View File

@ -0,0 +1,633 @@
/*
Unix SMB/CIFS implementation.
main select loop and event handling
Copyright (C) Andrew Tridgell 2003-2005
Copyright (C) Stefan Metzmacher 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
This is SAMBA's default event loop code
- we try to use epoll if configure detected support for it
otherwise we use select()
- if epoll is broken on the system or the kernel doesn't support it
at runtime we fallback to select()
*/
#include "includes.h"
#include "system/filesys.h"
#include "system/select.h" /* needed for WITH_EPOLL */
#include "lib/util/dlinklist.h"
#include "lib/events/events.h"
#include "lib/events/events_internal.h"
struct std_event_context {
/* a pointer back to the generic event_context */
struct event_context *ev;
/* list of filedescriptor events */
struct fd_event *fd_events;
/* list of timed events */
struct timed_event *timed_events;
/* the maximum file descriptor number in fd_events */
int maxfd;
/* information for exiting from the event loop */
int exit_code;
/* this is changed by the destructors for the fd event
type. It is used to detect event destruction by event
handlers, which means the code that is calling the event
handler needs to assume that the linked list is no longer
valid
*/
uint32_t destruction_count;
/* when using epoll this is the handle from epoll_create */
int epoll_fd;
};
static void std_event_loop_timer(struct std_event_context *std_ev);
/* use epoll if it is available */
#if WITH_EPOLL
/*
called when a epoll call fails, and we should fallback
to using select
*/
static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
{
DEBUG(0,("%s (%s) - falling back to select()\n", reason, strerror(errno)));
close(std_ev->epoll_fd);
std_ev->epoll_fd = -1;
talloc_set_destructor(std_ev, NULL);
}
/*
map from EVENT_FD_* to EPOLLIN/EPOLLOUT
*/
static uint32_t epoll_map_flags(uint16_t flags)
{
uint32_t ret = 0;
if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
return ret;
}
/*
free the epoll fd
*/
static int epoll_ctx_destructor(struct std_event_context *std_ev)
{
close(std_ev->epoll_fd);
std_ev->epoll_fd = -1;
return 0;
}
/*
init the epoll fd
*/
static void epoll_init_ctx(struct std_event_context *std_ev, BOOL try_epoll)
{
if (!try_epoll) return;
std_ev->epoll_fd = epoll_create(64);
talloc_set_destructor(std_ev, epoll_ctx_destructor);
}
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
/*
add the epoll event to the given fd_event
*/
static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde)
{
struct epoll_event event;
if (std_ev->epoll_fd == -1) return;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
/* if we don't want events yet, don't add an epoll_event */
if (fde->flags == 0) return;
ZERO_STRUCT(event);
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
}
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
/* only if we want to read we want to tell the event handler about errors */
if (fde->flags & EVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
/*
delete the epoll event for given fd_event
*/
static void epoll_del_event(struct std_event_context *std_ev, struct fd_event *fde)
{
struct epoll_event event;
if (std_ev->epoll_fd == -1) return;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
/* if there's no epoll_event, we don't need to delete it */
if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
ZERO_STRUCT(event);
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
}
/*
change the epoll event to the given fd_event
*/
static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *fde)
{
struct epoll_event event;
if (std_ev->epoll_fd == -1) return;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
ZERO_STRUCT(event);
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed");
}
/* only if we want to read we want to tell the event handler about errors */
if (fde->flags & EVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
static void epoll_change_event(struct std_event_context *std_ev, struct fd_event *fde)
{
BOOL got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
BOOL want_read = (fde->flags & EVENT_FD_READ);
BOOL want_write= (fde->flags & EVENT_FD_WRITE);
if (std_ev->epoll_fd == -1) return;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
/* there's already an event */
if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
if (want_read || (want_write && !got_error)) {
epoll_mod_event(std_ev, fde);
return;
}
/*
* if we want to match the select behavior, we need to remove the epoll_event
* when the caller isn't interested in events.
*
* this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
*/
epoll_del_event(std_ev, fde);
return;
}
/* there's no epoll_event attached to the fde */
if (want_read || (want_write && !got_error)) {
epoll_add_event(std_ev, fde);
return;
}
}
/*
event loop handling using epoll
*/
static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
{
int ret, i;
#define MAXEVENTS 8
struct epoll_event events[MAXEVENTS];
uint32_t destruction_count = std_ev->destruction_count;
int timeout = -1;
if (std_ev->epoll_fd == -1) return -1;
if (tvalp) {
/* it's better to trigger timed events a bit later than to early */
timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
}
ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
if (ret == -1 && errno != EINTR) {
epoll_fallback_to_select(std_ev, "epoll_wait() failed");
return -1;
}
if (ret == 0 && tvalp) {
std_event_loop_timer(std_ev);
return 0;
}
for (i=0;i<ret;i++) {
struct fd_event *fde = talloc_get_type(events[i].data.ptr,
struct fd_event);
uint16_t flags = 0;
if (fde == NULL) {
epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data");
return -1;
}
if (events[i].events & (EPOLLHUP|EPOLLERR)) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
/*
* if we only wait for EVENT_FD_WRITE, we should not tell the
* event handler about it, and remove the epoll_event,
* as we only report errors when waiting for read events,
* to match the select() behavior
*/
if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
epoll_del_event(std_ev, fde);
continue;
}
flags |= EVENT_FD_READ;
}
if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
if (flags) {
fde->handler(std_ev->ev, fde, flags, fde->private_data);
if (destruction_count != std_ev->destruction_count) {
break;
}
}
}
return 0;
}
#else
#define epoll_init_ctx(std_ev,try_epoll) if (try_epoll) {/* fix unused variable warning*/}
#define epoll_add_event(std_ev,fde)
#define epoll_del_event(std_ev,fde)
#define epoll_change_event(std_ev,fde)
#define epoll_event_loop(std_ev,tvalp) (-1)
#endif
/*
create a std_event_context structure.
*/
static int std_event_context_init(struct event_context *ev, void *private_data)
{
struct std_event_context *std_ev;
BOOL *_try_epoll = private_data;
BOOL try_epoll = (_try_epoll == NULL ? True : *_try_epoll);
std_ev = talloc_zero(ev, struct std_event_context);
if (!std_ev) return -1;
std_ev->ev = ev;
std_ev->epoll_fd = -1;
epoll_init_ctx(std_ev, try_epoll);
ev->additional_data = std_ev;
return 0;
}
/*
recalculate the maxfd
*/
static void calc_maxfd(struct std_event_context *std_ev)
{
struct fd_event *fde;
std_ev->maxfd = 0;
for (fde = std_ev->fd_events; fde; fde = fde->next) {
if (fde->fd > std_ev->maxfd) {
std_ev->maxfd = fde->fd;
}
}
}
/* to mark the ev->maxfd invalid
* this means we need to recalculate it
*/
#define EVENT_INVALID_MAXFD (-1)
/*
destroy an fd_event
*/
static int std_event_fd_destructor(struct fd_event *fde)
{
struct event_context *ev = fde->event_ctx;
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
if (std_ev->maxfd == fde->fd) {
std_ev->maxfd = EVENT_INVALID_MAXFD;
}
DLIST_REMOVE(std_ev->fd_events, fde);
std_ev->destruction_count++;
epoll_del_event(std_ev, fde);
return 0;
}
/*
add a fd based event
return NULL on failure (memory allocation error)
*/
static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
event_fd_handler_t handler,
void *private_data)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
struct fd_event *fde;
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
if (!fde) return NULL;
fde->event_ctx = ev;
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
fde->private_data = private_data;
fde->additional_flags = 0;
fde->additional_data = NULL;
DLIST_ADD(std_ev->fd_events, fde);
if (fde->fd > std_ev->maxfd) {
std_ev->maxfd = fde->fd;
}
talloc_set_destructor(fde, std_event_fd_destructor);
epoll_add_event(std_ev, fde);
return fde;
}
/*
return the fd event flags
*/
static uint16_t std_event_get_fd_flags(struct fd_event *fde)
{
return fde->flags;
}
/*
set the fd event flags
*/
static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
{
struct event_context *ev;
struct std_event_context *std_ev;
if (fde->flags == flags) return;
ev = fde->event_ctx;
std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
fde->flags = flags;
epoll_change_event(std_ev, fde);
}
/*
destroy a timed event
*/
static int std_event_timed_destructor(struct timed_event *te)
{
struct std_event_context *std_ev = talloc_get_type(te->event_ctx->additional_data,
struct std_event_context);
DLIST_REMOVE(std_ev->timed_events, te);
return 0;
}
static int std_event_timed_deny_destructor(struct timed_event *te)
{
return -1;
}
/*
add a timed event
return NULL on failure (memory allocation error)
*/
static struct timed_event *std_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private_data)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
struct timed_event *te, *last_te, *cur_te;
te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
if (te == NULL) return NULL;
te->event_ctx = ev;
te->next_event = next_event;
te->handler = handler;
te->private_data = private_data;
te->additional_data = NULL;
/* keep the list ordered */
last_te = NULL;
for (cur_te = std_ev->timed_events; cur_te; cur_te = cur_te->next) {
/* if the new event comes before the current one break */
if (!timeval_is_zero(&cur_te->next_event) &&
timeval_compare(&te->next_event,
&cur_te->next_event) < 0) {
break;
}
last_te = cur_te;
}
DLIST_ADD_AFTER(std_ev->timed_events, te, last_te);
talloc_set_destructor(te, std_event_timed_destructor);
return te;
}
/*
a timer has gone off - call it
*/
static void std_event_loop_timer(struct std_event_context *std_ev)
{
struct timeval t = timeval_current();
struct timed_event *te = std_ev->timed_events;
if (te == NULL) {
return;
}
/* deny the handler to free the event */
talloc_set_destructor(te, std_event_timed_deny_destructor);
/* We need to remove the timer from the list before calling the
* handler because in a semi-async inner event loop called from the
* handler we don't want to come across this event again -- vl */
DLIST_REMOVE(std_ev->timed_events, te);
te->handler(std_ev->ev, te, t, te->private_data);
/* The destructor isn't necessary anymore, we've already removed the
* event from the list. */
talloc_set_destructor(te, NULL);
talloc_free(te);
}
/*
event loop handling using select()
*/
static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
{
fd_set r_fds, w_fds;
struct fd_event *fde;
int selrtn;
uint32_t destruction_count = std_ev->destruction_count;
/* we maybe need to recalculate the maxfd */
if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
calc_maxfd(std_ev);
}
FD_ZERO(&r_fds);
FD_ZERO(&w_fds);
/* setup any fd events */
for (fde = std_ev->fd_events; fde; fde = fde->next) {
if (fde->flags & EVENT_FD_READ) {
FD_SET(fde->fd, &r_fds);
}
if (fde->flags & EVENT_FD_WRITE) {
FD_SET(fde->fd, &w_fds);
}
}
selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
if (selrtn == -1 && errno == EBADF) {
/* the socket is dead! this should never
happen as the socket should have first been
made readable and that should have removed
the event, so this must be a bug. This is a
fatal error. */
DEBUG(0,("ERROR: EBADF on std_event_loop_once\n"));
std_ev->exit_code = EBADF;
return -1;
}
if (selrtn == 0 && tvalp) {
std_event_loop_timer(std_ev);
return 0;
}
if (selrtn > 0) {
/* at least one file descriptor is ready - check
which ones and call the handler, being careful to allow
the handler to remove itself when called */
for (fde = std_ev->fd_events; fde; fde = fde->next) {
uint16_t flags = 0;
if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
if (flags) {
fde->handler(std_ev->ev, fde, flags, fde->private_data);
if (destruction_count != std_ev->destruction_count) {
break;
}
}
}
}
return 0;
}
/*
do a single event loop using the events defined in ev
*/
static int std_event_loop_once(struct event_context *ev)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
struct timeval tval;
/* work out the right timeout for all timed events */
if (std_ev->timed_events) {
struct timeval t = timeval_current();
tval = timeval_until(&t, &std_ev->timed_events->next_event);
if (timeval_is_zero(&tval)) {
std_event_loop_timer(std_ev);
return 0;
}
} else {
/* have a default tick time of 30 seconds. This guarantees
that code that uses its own timeout checking will be
able to proceeed eventually */
tval = timeval_set(30, 0);
}
if (epoll_event_loop(std_ev, &tval) == 0) {
return 0;
}
return std_event_loop_select(std_ev, &tval);
}
/*
return on failure or (with 0) if all fd events are removed
*/
static int std_event_loop_wait(struct event_context *ev)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
std_ev->exit_code = 0;
while (std_ev->fd_events && std_ev->exit_code == 0) {
if (std_event_loop_once(ev) != 0) {
break;
}
}
return std_ev->exit_code;
}
static const struct event_ops std_event_ops = {
.context_init = std_event_context_init,
.add_fd = std_event_add_fd,
.get_fd_flags = std_event_get_fd_flags,
.set_fd_flags = std_event_set_fd_flags,
.add_timed = std_event_add_timed,
.loop_once = std_event_loop_once,
.loop_wait = std_event_loop_wait,
};
const struct event_ops *event_standard_get_ops(void)
{
return &std_event_ops;
}

View File

@ -0,0 +1,2 @@
AC_CHECK_HEADERS(sys/epoll.h)
AC_CHECK_FUNCS(epoll_create)

View File

@ -0,0 +1,7 @@
##############################
# Start SUBSYSTEM LIBEVENTS
[SUBSYSTEM::LIBEVENTS]
OBJ_FILES = events.o events_standard.o
PUBLIC_DEPENDENCIES = LIBTALLOC
# End SUBSYSTEM LIBEVENTS
##############################

175
ctdb/lib/events/events.c Normal file
View File

@ -0,0 +1,175 @@
/*
Unix SMB/CIFS implementation.
main select loop and event handling
Copyright (C) Andrew Tridgell 2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
PLEASE READ THIS BEFORE MODIFYING!
This module is a general abstraction for the main select loop and
event handling. Do not ever put any localised hacks in here, instead
register one of the possible event types and implement that event
somewhere else.
There are 2 types of event handling that are handled in this module:
1) a file descriptor becoming readable or writeable. This is mostly
used for network sockets, but can be used for any type of file
descriptor. You may only register one handler for each file
descriptor/io combination or you will get unpredictable results
(this means that you can have a handler for read events, and a
separate handler for write events, but not two handlers that are
both handling read events)
2) a timed event. You can register an event that happens at a
specific time. You can register as many of these as you
like. They are single shot - add a new timed event in the event
handler to get another event.
To setup a set of events you first need to create a event_context
structure using the function event_context_init(); This returns a
'struct event_context' that you use in all subsequent calls.
After that you can add/remove events that you are interested in
using event_add_*() and talloc_free()
Finally, you call event_loop_wait_once() to block waiting for one of the
events to occor or event_loop_wait() which will loop
forever.
*/
#include "includes.h"
#include "lib/events/events.h"
#include "lib/events/events_internal.h"
/*
create a event_context structure for a specific implemementation.
This must be the first events call, and all subsequent calls pass
this event_context as the first element. Event handlers also
receive this as their first argument.
This function is for allowing third-party-applications to hook in gluecode
to their own event loop code, so that they can make async usage of our client libs
NOTE: use event_context_init() inside of samba!
*/
struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct event_ops *ops, void *private_data)
{
struct event_context *ev;
int ret;
ev = talloc_zero(mem_ctx, struct event_context);
if (!ev) return NULL;
ev->ops = ops;
ret = ev->ops->context_init(ev, private_data);
if (ret != 0) {
talloc_free(ev);
return NULL;
}
return ev;
}
/*
create a event_context structure. This must be the first events
call, and all subsequent calls pass this event_context as the first
element. Event handlers also receive this as their first argument.
*/
struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
{
const struct event_ops *ops = event_standard_get_ops();
return event_context_init_ops(mem_ctx, ops, NULL);
}
/*
add a fd based event
return NULL on failure (memory allocation error)
*/
struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
int fd, uint16_t flags, event_fd_handler_t handler,
void *private_data)
{
return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data);
}
/*
return the fd event flags
*/
uint16_t event_get_fd_flags(struct fd_event *fde)
{
if (!fde) return 0;
return fde->event_ctx->ops->get_fd_flags(fde);
}
/*
set the fd event flags
*/
void event_set_fd_flags(struct fd_event *fde, uint16_t flags)
{
if (!fde) return;
fde->event_ctx->ops->set_fd_flags(fde, flags);
}
/*
add a timed event
return NULL on failure
*/
struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private_data)
{
return ev->ops->add_timed(ev, mem_ctx, next_event, handler, private_data);
}
/*
do a single event loop using the events defined in ev
*/
_PUBLIC_ int event_loop_once(struct event_context *ev)
{
return ev->ops->loop_once(ev);
}
/*
return on failure or (with 0) if all fd events are removed
*/
int event_loop_wait(struct event_context *ev)
{
return ev->ops->loop_wait(ev);
}
/*
find an event context that is a parent of the given memory context,
or create a new event context as a child of the given context if
none is found
This should be used in preference to event_context_init() in places
where you would prefer to use the existing event context if possible
(which is most situations)
*/
struct event_context *event_context_find(TALLOC_CTX *mem_ctx)
{
struct event_context *ev = talloc_find_parent_bytype(mem_ctx, struct event_context);
if (ev == NULL) {
ev = event_context_init(mem_ctx);
}
return ev;
}

71
ctdb/lib/events/events.h Normal file
View File

@ -0,0 +1,71 @@
/*
Unix SMB/CIFS implementation.
generalised event loop handling
Copyright (C) Andrew Tridgell 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __EVENTS_H__
#define __EVENTS_H__
struct event_context;
struct event_ops;
struct fd_event;
struct timed_event;
/* event handler types */
typedef void (*event_fd_handler_t)(struct event_context *, struct fd_event *,
uint16_t , void *);
typedef void (*event_timed_handler_t)(struct event_context *, struct timed_event *,
struct timeval , void *);
struct event_context *event_context_init(TALLOC_CTX *mem_ctx);
struct event_context *event_context_init_ops(TALLOC_CTX *mem_ctx, const struct event_ops *ops, void *private_data);
struct fd_event *event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
int fd, uint16_t flags, event_fd_handler_t handler,
void *private);
struct timed_event *event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private);
int event_loop_once(struct event_context *ev);
int event_loop_wait(struct event_context *ev);
uint16_t event_get_fd_flags(struct fd_event *fde);
void event_set_fd_flags(struct fd_event *fde, uint16_t flags);
struct event_context *event_context_find(TALLOC_CTX *mem_ctx);
/* bits for file descriptor event flags */
#define EVENT_FD_READ 1
#define EVENT_FD_WRITE 2
#define EVENT_FD_WRITEABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
#define EVENT_FD_READABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ)
#define EVENT_FD_NOT_WRITEABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE)
#define EVENT_FD_NOT_READABLE(fde) \
event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ)
#endif /* __EVENTS_H__ */

View File

@ -0,0 +1,81 @@
/*
Unix SMB/CIFS implementation.
generalised event loop handling
Internal structs
Copyright (C) Stefan Metzmacher 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
struct event_ops {
/* conntext init */
int (*context_init)(struct event_context *ev, void *private_data);
/* fd_event functions */
struct fd_event *(*add_fd)(struct event_context *ev,
TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
event_fd_handler_t handler,
void *private_data);
uint16_t (*get_fd_flags)(struct fd_event *fde);
void (*set_fd_flags)(struct fd_event *fde, uint16_t flags);
/* timed_event functions */
struct timed_event *(*add_timed)(struct event_context *ev,
TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private_data);
/* loop functions */
int (*loop_once)(struct event_context *ev);
int (*loop_wait)(struct event_context *ev);
};
struct fd_event {
struct fd_event *prev, *next;
struct event_context *event_ctx;
int fd;
uint16_t flags; /* see EVENT_FD_* flags */
event_fd_handler_t handler;
/* this is private for the specific handler */
void *private_data;
/* this is private for the events_ops implementation */
uint16_t additional_flags;
void *additional_data;
};
struct timed_event {
struct timed_event *prev, *next;
struct event_context *event_ctx;
struct timeval next_event;
event_timed_handler_t handler;
/* this is private for the specific handler */
void *private_data;
/* this is private for the events_ops implementation */
void *additional_data;
};
struct event_context {
/* the specific events implementation */
const struct event_ops *ops;
/* this is private for the events_ops implementation */
void *additional_data;
};
const struct event_ops *event_standard_get_ops(void);

View File

@ -0,0 +1,284 @@
/*
Unix SMB/CIFS implementation.
main select loop and event handling
wrapper for http://liboop.org/
Copyright (C) Stefan Metzmacher 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "lib/events/events.h"
#include "lib/events/events_internal.h"
#include <oop.h>
/*
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NOTE: this code compiles fine, but is completly *UNTESTED*
and is only commited as example
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
static int oop_event_context_destructor(struct event_context *ev)
{
oop_source_sys *oop_sys = ev->additional_data;
oop_sys_delete(oop_sys);
return 0;
}
/*
create a oop_event_context structure.
*/
static int oop_event_context_init(struct event_context *ev, void *private_data)
{
oop_source_sys *oop_sys = private_data;
if (!oop_sys) {
oop_sys = oop_sys_new();
if (!oop_sys) {
return -1;
}
talloc_set_destructor(ev, oop_event_context_destructor);
}
ev->additional_data = oop_sys;
return 0;
}
static void *oop_event_fd_handler(oop_source *oop, int fd, oop_event oop_type, void *ptr)
{
struct fd_event *fde = ptr;
if (fd != fde->fd) return OOP_ERROR;
switch(oop_type) {
case OOP_READ:
fde->handler(fde->event_ctx, fde, EVENT_FD_READ, fde->private_data);
return OOP_CONTINUE;
case OOP_WRITE:
fde->handler(fde->event_ctx, fde, EVENT_FD_WRITE, fde->private_data);
return OOP_CONTINUE;
case OOP_EXCEPTION:
return OOP_ERROR;
case OOP_NUM_EVENTS:
return OOP_ERROR;
}
return OOP_ERROR;
}
/*
destroy an fd_event
*/
static int oop_event_fd_destructor(struct fd_event *fde)
{
struct event_context *ev = fde->event_ctx;
oop_source_sys *oop_sys = ev->additional_data;
oop_source *oop = oop_sys_source(oop_sys);
if (fde->flags & EVENT_FD_READ)
oop->cancel_fd(oop, fde->fd, OOP_READ);
if (fde->flags & EVENT_FD_WRITE)
oop->cancel_fd(oop, fde->fd, OOP_WRITE);
return 0;
}
/*
add a fd based event
return NULL on failure (memory allocation error)
*/
static struct fd_event *oop_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
event_fd_handler_t handler,
void *private_data)
{
struct fd_event *fde;
oop_source_sys *oop_sys = ev->additional_data;
oop_source *oop = oop_sys_source(oop_sys);
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
if (!fde) return NULL;
fde->event_ctx = ev;
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
fde->private_data = private_data;
fde->additional_flags = 0;
fde->additional_data = NULL;
if (fde->flags & EVENT_FD_READ)
oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
if (fde->flags & EVENT_FD_WRITE)
oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
talloc_set_destructor(fde, oop_event_fd_destructor);
return fde;
}
/*
return the fd event flags
*/
static uint16_t oop_event_get_fd_flags(struct fd_event *fde)
{
return fde->flags;
}
/*
set the fd event flags
*/
static void oop_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
{
oop_source_sys *oop_sys;
oop_source *oop;
oop_sys = fde->event_ctx->additional_data;
oop = oop_sys_source(oop_sys);
if ((fde->flags & EVENT_FD_READ)&&(!(flags & EVENT_FD_READ)))
oop->cancel_fd(oop, fde->fd, OOP_READ);
if ((!(fde->flags & EVENT_FD_READ))&&(flags & EVENT_FD_READ))
oop->on_fd(oop, fde->fd, OOP_READ, oop_event_fd_handler, fde);
if ((fde->flags & EVENT_FD_WRITE)&&(!(flags & EVENT_FD_WRITE)))
oop->cancel_fd(oop, fde->fd, OOP_WRITE);
if ((!(fde->flags & EVENT_FD_WRITE))&&(flags & EVENT_FD_WRITE))
oop->on_fd(oop, fde->fd, OOP_WRITE, oop_event_fd_handler, fde);
fde->flags = flags;
}
static int oop_event_timed_destructor(struct timed_event *te);
static int oop_event_timed_deny_destructor(struct timed_event *te)
{
return -1;
}
static void *oop_event_timed_handler(oop_source *oop, struct timeval t, void *ptr)
{
struct timed_event *te = ptr;
/* deny the handler to free the event */
talloc_set_destructor(te, oop_event_timed_deny_destructor);
te->handler(te->event_ctx, te, t, te->private_data);
talloc_set_destructor(te, oop_event_timed_destructor);
talloc_free(te);
return OOP_CONTINUE;
}
/*
destroy a timed event
*/
static int oop_event_timed_destructor(struct timed_event *te)
{
struct event_context *ev = te->event_ctx;
oop_source_sys *oop_sys = ev->additional_data;
oop_source *oop = oop_sys_source(oop_sys);
oop->cancel_time(oop, te->next_event, oop_event_timed_handler, te);
return 0;
}
/*
add a timed event
return NULL on failure (memory allocation error)
*/
static struct timed_event *oop_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private_data)
{
oop_source_sys *oop_sys = ev->additional_data;
oop_source *oop = oop_sys_source(oop_sys);
struct timed_event *te;
te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
if (te == NULL) return NULL;
te->event_ctx = ev;
te->next_event = next_event;
te->handler = handler;
te->private_data = private_data;
te->additional_data = NULL;
oop->on_time(oop, te->next_event, oop_event_timed_handler, te);
talloc_set_destructor(te, oop_event_timed_destructor);
return te;
}
/*
do a single event loop using the events defined in ev
*/
static int oop_event_loop_once(struct event_context *ev)
{
void *oop_ret;
oop_source_sys *oop_sys = ev->additional_data;
oop_ret = oop_sys_run_once(oop_sys);
if (oop_ret == OOP_CONTINUE) {
return 0;
}
return -1;
}
/*
return on failure or (with 0) if all fd events are removed
*/
static int oop_event_loop_wait(struct event_context *ev)
{
void *oop_ret;
oop_source_sys *oop_sys = ev->additional_data;
oop_ret = oop_sys_run(oop_sys);
if (oop_ret == OOP_CONTINUE) {
return 0;
}
return -1;
}
static const struct event_ops event_oop_ops = {
.context_init = oop_event_context_init,
.add_fd = oop_event_add_fd,
.get_fd_flags = oop_event_get_fd_flags,
.set_fd_flags = oop_event_set_fd_flags,
.add_timed = oop_event_add_timed,
.loop_once = oop_event_loop_once,
.loop_wait = oop_event_loop_wait,
};
const struct event_ops *event_liboop_get_ops(void)
{
return &event_oop_ops;
}

View File

@ -0,0 +1,633 @@
/*
Unix SMB/CIFS implementation.
main select loop and event handling
Copyright (C) Andrew Tridgell 2003-2005
Copyright (C) Stefan Metzmacher 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
This is SAMBA's default event loop code
- we try to use epoll if configure detected support for it
otherwise we use select()
- if epoll is broken on the system or the kernel doesn't support it
at runtime we fallback to select()
*/
#include "includes.h"
#include "system/filesys.h"
#include "system/select.h" /* needed for WITH_EPOLL */
#include "lib/util/dlinklist.h"
#include "lib/events/events.h"
#include "lib/events/events_internal.h"
struct std_event_context {
/* a pointer back to the generic event_context */
struct event_context *ev;
/* list of filedescriptor events */
struct fd_event *fd_events;
/* list of timed events */
struct timed_event *timed_events;
/* the maximum file descriptor number in fd_events */
int maxfd;
/* information for exiting from the event loop */
int exit_code;
/* this is changed by the destructors for the fd event
type. It is used to detect event destruction by event
handlers, which means the code that is calling the event
handler needs to assume that the linked list is no longer
valid
*/
uint32_t destruction_count;
/* when using epoll this is the handle from epoll_create */
int epoll_fd;
};
static void std_event_loop_timer(struct std_event_context *std_ev);
/* use epoll if it is available */
#if WITH_EPOLL
/*
called when a epoll call fails, and we should fallback
to using select
*/
static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
{
DEBUG(0,("%s (%s) - falling back to select()\n", reason, strerror(errno)));
close(std_ev->epoll_fd);
std_ev->epoll_fd = -1;
talloc_set_destructor(std_ev, NULL);
}
/*
map from EVENT_FD_* to EPOLLIN/EPOLLOUT
*/
static uint32_t epoll_map_flags(uint16_t flags)
{
uint32_t ret = 0;
if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
return ret;
}
/*
free the epoll fd
*/
static int epoll_ctx_destructor(struct std_event_context *std_ev)
{
close(std_ev->epoll_fd);
std_ev->epoll_fd = -1;
return 0;
}
/*
init the epoll fd
*/
static void epoll_init_ctx(struct std_event_context *std_ev, BOOL try_epoll)
{
if (!try_epoll) return;
std_ev->epoll_fd = epoll_create(64);
talloc_set_destructor(std_ev, epoll_ctx_destructor);
}
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
/*
add the epoll event to the given fd_event
*/
static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde)
{
struct epoll_event event;
if (std_ev->epoll_fd == -1) return;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
/* if we don't want events yet, don't add an epoll_event */
if (fde->flags == 0) return;
ZERO_STRUCT(event);
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
}
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
/* only if we want to read we want to tell the event handler about errors */
if (fde->flags & EVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
/*
delete the epoll event for given fd_event
*/
static void epoll_del_event(struct std_event_context *std_ev, struct fd_event *fde)
{
struct epoll_event event;
if (std_ev->epoll_fd == -1) return;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
/* if there's no epoll_event, we don't need to delete it */
if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
ZERO_STRUCT(event);
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
}
/*
change the epoll event to the given fd_event
*/
static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *fde)
{
struct epoll_event event;
if (std_ev->epoll_fd == -1) return;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
ZERO_STRUCT(event);
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed");
}
/* only if we want to read we want to tell the event handler about errors */
if (fde->flags & EVENT_FD_READ) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
}
}
static void epoll_change_event(struct std_event_context *std_ev, struct fd_event *fde)
{
BOOL got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
BOOL want_read = (fde->flags & EVENT_FD_READ);
BOOL want_write= (fde->flags & EVENT_FD_WRITE);
if (std_ev->epoll_fd == -1) return;
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
/* there's already an event */
if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
if (want_read || (want_write && !got_error)) {
epoll_mod_event(std_ev, fde);
return;
}
/*
* if we want to match the select behavior, we need to remove the epoll_event
* when the caller isn't interested in events.
*
* this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
*/
epoll_del_event(std_ev, fde);
return;
}
/* there's no epoll_event attached to the fde */
if (want_read || (want_write && !got_error)) {
epoll_add_event(std_ev, fde);
return;
}
}
/*
event loop handling using epoll
*/
static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
{
int ret, i;
#define MAXEVENTS 8
struct epoll_event events[MAXEVENTS];
uint32_t destruction_count = std_ev->destruction_count;
int timeout = -1;
if (std_ev->epoll_fd == -1) return -1;
if (tvalp) {
/* it's better to trigger timed events a bit later than to early */
timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
}
ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
if (ret == -1 && errno != EINTR) {
epoll_fallback_to_select(std_ev, "epoll_wait() failed");
return -1;
}
if (ret == 0 && tvalp) {
std_event_loop_timer(std_ev);
return 0;
}
for (i=0;i<ret;i++) {
struct fd_event *fde = talloc_get_type(events[i].data.ptr,
struct fd_event);
uint16_t flags = 0;
if (fde == NULL) {
epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data");
return -1;
}
if (events[i].events & (EPOLLHUP|EPOLLERR)) {
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
/*
* if we only wait for EVENT_FD_WRITE, we should not tell the
* event handler about it, and remove the epoll_event,
* as we only report errors when waiting for read events,
* to match the select() behavior
*/
if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
epoll_del_event(std_ev, fde);
continue;
}
flags |= EVENT_FD_READ;
}
if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
if (flags) {
fde->handler(std_ev->ev, fde, flags, fde->private_data);
if (destruction_count != std_ev->destruction_count) {
break;
}
}
}
return 0;
}
#else
#define epoll_init_ctx(std_ev,try_epoll) if (try_epoll) {/* fix unused variable warning*/}
#define epoll_add_event(std_ev,fde)
#define epoll_del_event(std_ev,fde)
#define epoll_change_event(std_ev,fde)
#define epoll_event_loop(std_ev,tvalp) (-1)
#endif
/*
create a std_event_context structure.
*/
static int std_event_context_init(struct event_context *ev, void *private_data)
{
struct std_event_context *std_ev;
BOOL *_try_epoll = private_data;
BOOL try_epoll = (_try_epoll == NULL ? True : *_try_epoll);
std_ev = talloc_zero(ev, struct std_event_context);
if (!std_ev) return -1;
std_ev->ev = ev;
std_ev->epoll_fd = -1;
epoll_init_ctx(std_ev, try_epoll);
ev->additional_data = std_ev;
return 0;
}
/*
recalculate the maxfd
*/
static void calc_maxfd(struct std_event_context *std_ev)
{
struct fd_event *fde;
std_ev->maxfd = 0;
for (fde = std_ev->fd_events; fde; fde = fde->next) {
if (fde->fd > std_ev->maxfd) {
std_ev->maxfd = fde->fd;
}
}
}
/* to mark the ev->maxfd invalid
* this means we need to recalculate it
*/
#define EVENT_INVALID_MAXFD (-1)
/*
destroy an fd_event
*/
static int std_event_fd_destructor(struct fd_event *fde)
{
struct event_context *ev = fde->event_ctx;
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
if (std_ev->maxfd == fde->fd) {
std_ev->maxfd = EVENT_INVALID_MAXFD;
}
DLIST_REMOVE(std_ev->fd_events, fde);
std_ev->destruction_count++;
epoll_del_event(std_ev, fde);
return 0;
}
/*
add a fd based event
return NULL on failure (memory allocation error)
*/
static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
int fd, uint16_t flags,
event_fd_handler_t handler,
void *private_data)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
struct fd_event *fde;
fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
if (!fde) return NULL;
fde->event_ctx = ev;
fde->fd = fd;
fde->flags = flags;
fde->handler = handler;
fde->private_data = private_data;
fde->additional_flags = 0;
fde->additional_data = NULL;
DLIST_ADD(std_ev->fd_events, fde);
if (fde->fd > std_ev->maxfd) {
std_ev->maxfd = fde->fd;
}
talloc_set_destructor(fde, std_event_fd_destructor);
epoll_add_event(std_ev, fde);
return fde;
}
/*
return the fd event flags
*/
static uint16_t std_event_get_fd_flags(struct fd_event *fde)
{
return fde->flags;
}
/*
set the fd event flags
*/
static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
{
struct event_context *ev;
struct std_event_context *std_ev;
if (fde->flags == flags) return;
ev = fde->event_ctx;
std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
fde->flags = flags;
epoll_change_event(std_ev, fde);
}
/*
destroy a timed event
*/
static int std_event_timed_destructor(struct timed_event *te)
{
struct std_event_context *std_ev = talloc_get_type(te->event_ctx->additional_data,
struct std_event_context);
DLIST_REMOVE(std_ev->timed_events, te);
return 0;
}
static int std_event_timed_deny_destructor(struct timed_event *te)
{
return -1;
}
/*
add a timed event
return NULL on failure (memory allocation error)
*/
static struct timed_event *std_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
struct timeval next_event,
event_timed_handler_t handler,
void *private_data)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
struct timed_event *te, *last_te, *cur_te;
te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
if (te == NULL) return NULL;
te->event_ctx = ev;
te->next_event = next_event;
te->handler = handler;
te->private_data = private_data;
te->additional_data = NULL;
/* keep the list ordered */
last_te = NULL;
for (cur_te = std_ev->timed_events; cur_te; cur_te = cur_te->next) {
/* if the new event comes before the current one break */
if (!timeval_is_zero(&cur_te->next_event) &&
timeval_compare(&te->next_event,
&cur_te->next_event) < 0) {
break;
}
last_te = cur_te;
}
DLIST_ADD_AFTER(std_ev->timed_events, te, last_te);
talloc_set_destructor(te, std_event_timed_destructor);
return te;
}
/*
a timer has gone off - call it
*/
static void std_event_loop_timer(struct std_event_context *std_ev)
{
struct timeval t = timeval_current();
struct timed_event *te = std_ev->timed_events;
if (te == NULL) {
return;
}
/* deny the handler to free the event */
talloc_set_destructor(te, std_event_timed_deny_destructor);
/* We need to remove the timer from the list before calling the
* handler because in a semi-async inner event loop called from the
* handler we don't want to come across this event again -- vl */
DLIST_REMOVE(std_ev->timed_events, te);
te->handler(std_ev->ev, te, t, te->private_data);
/* The destructor isn't necessary anymore, we've already removed the
* event from the list. */
talloc_set_destructor(te, NULL);
talloc_free(te);
}
/*
event loop handling using select()
*/
static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
{
fd_set r_fds, w_fds;
struct fd_event *fde;
int selrtn;
uint32_t destruction_count = std_ev->destruction_count;
/* we maybe need to recalculate the maxfd */
if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
calc_maxfd(std_ev);
}
FD_ZERO(&r_fds);
FD_ZERO(&w_fds);
/* setup any fd events */
for (fde = std_ev->fd_events; fde; fde = fde->next) {
if (fde->flags & EVENT_FD_READ) {
FD_SET(fde->fd, &r_fds);
}
if (fde->flags & EVENT_FD_WRITE) {
FD_SET(fde->fd, &w_fds);
}
}
selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
if (selrtn == -1 && errno == EBADF) {
/* the socket is dead! this should never
happen as the socket should have first been
made readable and that should have removed
the event, so this must be a bug. This is a
fatal error. */
DEBUG(0,("ERROR: EBADF on std_event_loop_once\n"));
std_ev->exit_code = EBADF;
return -1;
}
if (selrtn == 0 && tvalp) {
std_event_loop_timer(std_ev);
return 0;
}
if (selrtn > 0) {
/* at least one file descriptor is ready - check
which ones and call the handler, being careful to allow
the handler to remove itself when called */
for (fde = std_ev->fd_events; fde; fde = fde->next) {
uint16_t flags = 0;
if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
if (flags) {
fde->handler(std_ev->ev, fde, flags, fde->private_data);
if (destruction_count != std_ev->destruction_count) {
break;
}
}
}
}
return 0;
}
/*
do a single event loop using the events defined in ev
*/
static int std_event_loop_once(struct event_context *ev)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
struct timeval tval;
/* work out the right timeout for all timed events */
if (std_ev->timed_events) {
struct timeval t = timeval_current();
tval = timeval_until(&t, &std_ev->timed_events->next_event);
if (timeval_is_zero(&tval)) {
std_event_loop_timer(std_ev);
return 0;
}
} else {
/* have a default tick time of 30 seconds. This guarantees
that code that uses its own timeout checking will be
able to proceeed eventually */
tval = timeval_set(30, 0);
}
if (epoll_event_loop(std_ev, &tval) == 0) {
return 0;
}
return std_event_loop_select(std_ev, &tval);
}
/*
return on failure or (with 0) if all fd events are removed
*/
static int std_event_loop_wait(struct event_context *ev)
{
struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
struct std_event_context);
std_ev->exit_code = 0;
while (std_ev->fd_events && std_ev->exit_code == 0) {
if (std_event_loop_once(ev) != 0) {
break;
}
}
return std_ev->exit_code;
}
static const struct event_ops std_event_ops = {
.context_init = std_event_context_init,
.add_fd = std_event_add_fd,
.get_fd_flags = std_event_get_fd_flags,
.set_fd_flags = std_event_set_fd_flags,
.add_timed = std_event_add_timed,
.loop_once = std_event_loop_once,
.loop_wait = std_event_loop_wait,
};
const struct event_ops *event_standard_get_ops(void)
{
return &std_event_ops;
}

114
ctdb/lib/util/dlinklist.h Normal file
View File

@ -0,0 +1,114 @@
/*
Unix SMB/CIFS implementation.
some simple double linked list macros
Copyright (C) Andrew Tridgell 1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* To use these macros you must have a structure containing a next and
prev pointer */
#ifndef _DLINKLIST_H
#define _DLINKLIST_H
/* hook into the front of the list */
#define DLIST_ADD(list, p) \
do { \
if (!(list)) { \
(list) = (p); \
(p)->next = (p)->prev = NULL; \
} else { \
(list)->prev = (p); \
(p)->next = (list); \
(p)->prev = NULL; \
(list) = (p); \
}\
} while (0)
/* remove an element from a list - element doesn't have to be in list. */
#define DLIST_REMOVE(list, p) \
do { \
if ((p) == (list)) { \
(list) = (p)->next; \
if (list) (list)->prev = NULL; \
} else { \
if ((p)->prev) (p)->prev->next = (p)->next; \
if ((p)->next) (p)->next->prev = (p)->prev; \
} \
if ((p) != (list)) (p)->next = (p)->prev = NULL; \
} while (0)
/* promote an element to the top of the list */
#define DLIST_PROMOTE(list, p) \
do { \
DLIST_REMOVE(list, p); \
DLIST_ADD(list, p); \
} while (0)
/* hook into the end of the list - needs a tmp pointer */
#define DLIST_ADD_END(list, p, type) \
do { \
if (!(list)) { \
(list) = (p); \
(p)->next = (p)->prev = NULL; \
} else { \
type tmp; \
for (tmp = (list); tmp->next; tmp = tmp->next) ; \
tmp->next = (p); \
(p)->next = NULL; \
(p)->prev = tmp; \
} \
} while (0)
/* insert 'p' after the given element 'el' in a list. If el is NULL then
this is the same as a DLIST_ADD() */
#define DLIST_ADD_AFTER(list, p, el) \
do { \
if (!(list) || !(el)) { \
DLIST_ADD(list, p); \
} else { \
p->prev = el; \
p->next = el->next; \
el->next = p; \
if (p->next) p->next->prev = p; \
}\
} while (0)
/* demote an element to the end of the list, needs a tmp pointer */
#define DLIST_DEMOTE(list, p, tmp) \
do { \
DLIST_REMOVE(list, p); \
DLIST_ADD_END(list, p, tmp); \
} while (0)
/* concatenate two lists - putting all elements of the 2nd list at the
end of the first list */
#define DLIST_CONCATENATE(list1, list2, type) \
do { \
if (!(list1)) { \
(list1) = (list2); \
} else { \
type tmp; \
for (tmp = (list1); tmp->next; tmp = tmp->next) ; \
tmp->next = (list2); \
if (list2) { \
(list2)->prev = tmp; \
} \
} \
} while (0)
#endif /* _DLINKLIST_H */

189
ctdb/util.c Normal file
View File

@ -0,0 +1,189 @@
/*
functions taken from samba4 for quick prototyping of ctdb. These are
not intended to remain part of ctdb
*/
#include "includes.h"
#include "system/time.h"
#include "system/filesys.h"
/**
return a zero timeval
*/
struct timeval timeval_zero(void)
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
return tv;
}
/**
return True if a timeval is zero
*/
bool timeval_is_zero(const struct timeval *tv)
{
return tv->tv_sec == 0 && tv->tv_usec == 0;
}
/**
return a timeval for the current time
*/
struct timeval timeval_current(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv;
}
/**
return a timeval struct with the given elements
*/
struct timeval timeval_set(uint32_t secs, uint32_t usecs)
{
struct timeval tv;
tv.tv_sec = secs;
tv.tv_usec = usecs;
return tv;
}
int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
{
if (tv1->tv_sec > tv2->tv_sec) return 1;
if (tv1->tv_sec < tv2->tv_sec) return -1;
if (tv1->tv_usec > tv2->tv_usec) return 1;
if (tv1->tv_usec < tv2->tv_usec) return -1;
return 0;
}
struct timeval timeval_until(const struct timeval *tv1,
const struct timeval *tv2)
{
struct timeval t;
if (timeval_compare(tv1, tv2) >= 0) {
return timeval_zero();
}
t.tv_sec = tv2->tv_sec - tv1->tv_sec;
if (tv1->tv_usec > tv2->tv_usec) {
t.tv_sec--;
t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
} else {
t.tv_usec = tv2->tv_usec - tv1->tv_usec;
}
return t;
}
_PUBLIC_ struct timeval timeval_add(const struct timeval *tv,
uint32_t secs, uint32_t usecs)
{
struct timeval tv2 = *tv;
const unsigned int million = 1000000;
tv2.tv_sec += secs;
tv2.tv_usec += usecs;
tv2.tv_sec += tv2.tv_usec / million;
tv2.tv_usec = tv2.tv_usec % million;
return tv2;
}
_PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
{
struct timeval tv = timeval_current();
return timeval_add(&tv, secs, usecs);
}
_PUBLIC_ char *fd_load(int fd, size_t *size, TALLOC_CTX *mem_ctx)
{
struct stat sbuf;
char *p;
if (fstat(fd, &sbuf) != 0) return NULL;
p = (char *)talloc_size(mem_ctx, sbuf.st_size+1);
if (!p) return NULL;
if (read(fd, p, sbuf.st_size) != sbuf.st_size) {
talloc_free(p);
return NULL;
}
p[sbuf.st_size] = 0;
if (size) *size = sbuf.st_size;
return p;
}
_PUBLIC_ char *file_load(const char *fname, size_t *size, TALLOC_CTX *mem_ctx)
{
int fd;
char *p;
if (!fname || !*fname) return NULL;
fd = open(fname,O_RDONLY);
if (fd == -1) return NULL;
p = fd_load(fd, size, mem_ctx);
close(fd);
return p;
}
/**
parse a buffer into lines
'p' will be freed on error, and otherwise will be made a child of the returned array
**/
static char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
{
int i;
char *s, **ret;
if (!p) return NULL;
for (s = p, i=0; s < p+size; s++) {
if (s[0] == '\n') i++;
}
ret = talloc_array(mem_ctx, char *, i+2);
if (!ret) {
talloc_free(p);
return NULL;
}
talloc_steal(ret, p);
memset(ret, 0, sizeof(ret[0])*(i+2));
if (numlines) *numlines = i;
ret[0] = p;
for (s = p, i=0; s < p+size; s++) {
if (s[0] == '\n') {
s[0] = 0;
i++;
ret[i] = s+1;
}
if (s[0] == '\r') s[0] = 0;
}
return ret;
}
/**
load a file into memory and return an array of pointers to lines in the file
must be freed with talloc_free().
**/
_PUBLIC_ char **file_lines_load(const char *fname, int *numlines, TALLOC_CTX *mem_ctx)
{
char *p;
size_t size;
p = file_load(fname, &size, mem_ctx);
if (!p) return NULL;
return file_lines_parse(p, size, numlines, mem_ctx);
}