diff options
author | 1999-04-30 01:58:59 +0000 | |
---|---|---|
committer | 1999-04-30 01:58:59 +0000 | |
commit | e09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e (patch) | |
tree | bd2fe53f0944ae30b5bb7ce3422bedb4455e3f7d | |
parent | more cruft (diff) | |
download | wireguard-openbsd-e09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e.tar.xz wireguard-openbsd-e09bdadb1962e70cc6e11d77adfe7d6a2dbb2c7e.zip |
upgrade Arla to fresher code. Too many new features and bugfixes.
200 files changed, 28649 insertions, 5303 deletions
diff --git a/sys/conf/files b/sys/conf/files index e8c75ceeee8..23cbc85d874 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.115 1999/04/20 20:06:10 niklas Exp $ +# $OpenBSD: files,v 1.116 1999/04/30 01:58:59 art Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -570,14 +570,19 @@ file ufs/ext2fs/ext2fs_readwrite.c ext2fs file ufs/ext2fs/ext2fs_subr.c ext2fs file ufs/ext2fs/ext2fs_vfsops.c ext2fs file ufs/ext2fs/ext2fs_vnops.c ext2fs -file xfs/xfs_common.c xfs +file xfs/xfs_common-bsd.c xfs file xfs/xfs_deb.c xfs -file xfs/xfs_dev.c xfs +file xfs/xfs_dev-bsd.c xfs +file xfs/xfs_dev-common.c xfs file xfs/xfs_message.c xfs -file xfs/xfs_node.c xfs -file xfs/xfs_syscalls.c -file xfs/xfs_vfsops.c xfs -file xfs/xfs_vnodeops.c xfs +file xfs/xfs_node-bsd.c xfs +file xfs/xfs_syscalls-common.c xfs +file xfs/xfs_vfsops-bsd.c xfs +file xfs/xfs_vfsops-common.c xfs +file xfs/xfs_vfsops-openbsd.c xfs +file xfs/xfs_vnodeops-bsd.c xfs +file xfs/xfs_vnodeops-common.c xfs +file xfs/xfs_syscalls-dummy.c !xfs file vm/device_pager.c !uvm & devpager file vm/swap_pager.c !uvm & swappager file vm/vm_fault.c !uvm diff --git a/sys/xfs/nxfs.h b/sys/xfs/nxfs.h index 5a584697642..1083484d7c8 100644 --- a/sys/xfs/nxfs.h +++ b/sys/xfs/nxfs.h @@ -1,40 +1 @@ -/* $OpenBSD: nxfs.h,v 1.2 1998/08/30 17:35:41 art Exp $ */ -/* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#define NXFS 2 +#define NXFS 2 diff --git a/sys/xfs/xfs_attr.h b/sys/xfs/xfs_attr.h index de66a2ee837..a1a921ea7f8 100644 --- a/sys/xfs/xfs_attr.h +++ b/sys/xfs/xfs_attr.h @@ -1,4 +1,3 @@ -/* $OpenBSD: xfs_attr.h,v 1.1 1998/08/31 05:13:21 art Exp $ */ /* * Copyright (c) 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,10 +36,10 @@ * SUCH DAMAGE. */ -/* $KTH: xfs_attr.h,v 1.7 1998/07/12 15:29:09 map Exp $ */ +/* $Id: xfs_attr.h,v 1.2 1999/04/30 01:58:59 art Exp $ */ -#ifndef _SYS_XFS_ATTR_H_ -#define _SYS_XFS_ATTR_H_ +#ifndef _XFS_ATTR_H +#define _XFS_ATTR_H #define XA_V_NONE 0 #define XA_V_MODE (1 << 0) @@ -55,11 +54,11 @@ #define XA_V_TYPE (1 << 9) enum xfs_file_type { XFS_FILE_NON, XFS_FILE_REG, XFS_FILE_DIR, - XFS_FILE_BLK, XFS_FILE_CHR, XFS_FILE_LNK, - XFS_FILE_SOCK, XFS_FILE_FIFO, XFS_FILE_BAD }; + XFS_FILE_BLK, XFS_FILE_CHR, XFS_FILE_LNK, + XFS_FILE_SOCK, XFS_FILE_FIFO, XFS_FILE_BAD }; #define XA_CLEAR(xa_p) \ - ((xa_p)->valid = XA_V_NONE) + ((xa_p)->valid = XA_V_NONE) #define XA_SET_MODE(xa_p, value) \ (((xa_p)->valid) |= XA_V_MODE, ((xa_p)->xa_mode) = value) #define XA_SET_NLINK(xa_p, value) \ @@ -117,17 +116,17 @@ typedef gid_t __kernel_gid_t; #endif struct xfs_attr { - u_int32_t valid; - __kernel_mode_t xa_mode; - __kernel_nlink_t xa_nlink; - __kernel_off_t xa_size; - __kernel_uid_t xa_uid; - __kernel_gid_t xa_gid; - time_t xa_atime; - time_t xa_mtime; - time_t xa_ctime; - u_int32_t xa_fileid; - enum xfs_file_type xa_type; + u_int32_t valid; + __kernel_mode_t xa_mode; + __kernel_nlink_t xa_nlink; + __kernel_off_t xa_size; + __kernel_uid_t xa_uid; + __kernel_gid_t xa_gid; + time_t xa_atime; + time_t xa_mtime; + time_t xa_ctime; + u_int32_t xa_fileid; + enum xfs_file_type xa_type; }; #endif /* _XFS_ATTR_H */ diff --git a/sys/xfs/xfs_common-bsd.c b/sys/xfs/xfs_common-bsd.c new file mode 100644 index 00000000000..a157cbfd939 --- /dev/null +++ b/sys/xfs/xfs_common-bsd.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef XFS_DEBUG +#include <xfs/xfs_locl.h> +#include <xfs/xfs_common.h> +#include <xfs/xfs_deb.h> + +RCSID("$Id: xfs_common-bsd.c,v 1.1 1999/04/30 01:58:59 art Exp $"); + +static u_int xfs_allocs; +static u_int xfs_frees; + +void * +xfs_alloc(u_int size) +{ + xfs_allocs++; + XFSDEB(XDEBMEM, ("xfs_alloc: xfs_allocs - xfs_frees %d\n", + xfs_allocs - xfs_frees)); + + return malloc(size, M_TEMP, M_WAITOK); /* What kind? */ +} + +void +xfs_free(void *ptr, u_int size) +{ + xfs_frees++; + free(ptr, M_TEMP); +} +#endif diff --git a/sys/xfs/xfs_common.h b/sys/xfs/xfs_common.h index ea927f3858a..4193434a3e6 100644 --- a/sys/xfs/xfs_common.h +++ b/sys/xfs/xfs_common.h @@ -1,6 +1,5 @@ -/* $OpenBSD: xfs_common.h,v 1.2 1998/08/31 05:13:21 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,20 +36,21 @@ * SUCH DAMAGE. */ -/* $KTH: xfs_common.h,v 1.5 1998/07/13 20:36:36 art Exp $ */ +/* $Id: xfs_common.h,v 1.3 1999/04/30 01:58:59 art Exp $ */ -#ifndef _XFS_XFS_COMMON_H_ -#define _XFS_XFS_COMMON_H_ +#ifndef _xfs_common_h +#define _xfs_common_h -#include <sys/malloc.h> - -#ifdef DEBUG -void *xfs_alloc __P((u_int size)); -void xfs_free __P((void *, u_int size)); +#ifdef XFS_DEBUG +void *xfs_alloc(u_int size); +void xfs_free(void *, u_int size); +#else +#ifdef __osf__ +#define xfs_alloc(a) malloc((a), BUCKETINDEX(a), M_TEMP, M_WAITOK) #else -#define xfs_alloc(s) malloc((s), M_TEMP, M_WAITOK) /* XXX - what kind? */ -#define xfs_free(p, s) free((p), M_TEMP) +#define xfs_alloc(a) malloc((a), M_TEMP, M_WAITOK) #endif +#define xfs_free(a, size) free(a, M_TEMP) +#endif /* XFS_DEBUG */ -#define RCSID(x) -#endif +#endif /* _xfs_common_h */ diff --git a/sys/xfs/xfs_config.h b/sys/xfs/xfs_config.h new file mode 100644 index 00000000000..aa8a53346de --- /dev/null +++ b/sys/xfs/xfs_config.h @@ -0,0 +1,846 @@ +/* include/config.h. Generated automatically by configure. */ +/* include/config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you can safely include both <sys/time.h> and <time.h>. */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + +/* Define this if we can include both sys/dir.h and dirent.h */ +#define USE_SYS_DIR_H 1 + +/* Define this if RETSIGTYPE == void */ +/* #undef VOID_RETSIGTYPE */ + +/* Define this if struct winsize is declared in sys/termios.h */ +#define HAVE_STRUCT_WINSIZE 1 + +/* Define this if struct msghdr is declared in sys/socket.h */ +#define HAVE_STRUCT_MSGHDR 1 + +/* Define this if struct iovec is declared in sys/uio.h */ +#define HAVE_STRUCT_IOVEC 1 + +/* Define this if struct winsize have ws_xpixel */ +#define HAVE_WS_XPIXEL 1 + +/* Define this if struct winsize have ws_ypixel */ +#define HAVE_WS_YPIXEL 1 + +/* Define this if `struct sockaddr' includes sa_len */ +#define SOCKADDR_HAS_SA_LEN 1 + +/* define if the system is missing a prototype for strtok_r() */ +/* #undef NEED_STRTOK_R_PROTO */ + +/* define if you have h_errno */ +#define HAVE_H_ERRNO 1 + +/* define if you have h_errlist but not hstrerror */ +#define HAVE_H_ERRLIST 1 + +/* define if you have h_nerr but not hstrerror */ +#define HAVE_H_NERR 1 + +/* define if your system has a declaration for h_errlist */ +/* #undef HAVE_H_ERRLIST_DECLARATION */ + +/* define if your system has a declaration for h_nerr */ +/* #undef HAVE_H_NERR_DECLARATION */ + +/* define if your system has a declaration for h_errno */ +#define HAVE_H_ERRNO_DECLARATION 1 + +/* define if your system has optreset */ +#define HAVE_OPTRESET 1 + +/* define if your system has a declaration for optreset */ +#define HAVE_OPTRESET_DECLARATION 1 + +/* define if your compiler has __FUNCTION__ */ +#define HAVE___FUNCTION__ 1 + +/* define if your compiler has __attribute__ */ +#define HAVE___ATTRIBUTE__ 1 + +/* Check if select need a prototype */ +/* #undef NEED_SELECT_PROTO */ + +/* Define if you have the FOUR_ARGUMENT_VFS_BUSY function. */ +#define HAVE_FOUR_ARGUMENT_VFS_BUSY 1 + +/* Define if you have the FOUR_ARGUMENT_VFS_OBJECT_CREATE function. */ +/* #undef HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE */ + +/* Define if you have the ONE_ARGUMENT_VOP_LOCK function. */ +/* #undef HAVE_ONE_ARGUMENT_VOP_LOCK */ + +/* Define if you have the THREE_ARGUMENT_VFS_BUSY function. */ +/* #undef HAVE_THREE_ARGUMENT_VFS_BUSY */ + +/* Define if you have the THREE_ARGUMENT_VGET function. */ +#define HAVE_THREE_ARGUMENT_VGET 1 + +/* Define if you have the THREE_ARGUMENT_VOP_LOCK function. */ +#define HAVE_THREE_ARGUMENT_VOP_LOCK 1 + +/* Define if you have the TWO_ARGUMENT_VFS_GETNEWFSID function. */ +/* #undef HAVE_TWO_ARGUMENT_VFS_GETNEWFSID */ + +/* Define if you have the TWO_ARGUMENT_VGET function. */ +/* #undef HAVE_TWO_ARGUMENT_VGET */ + +/* Define if you have the TWO_ARGUMENT_VOP_LOCK function. */ +/* #undef HAVE_TWO_ARGUMENT_VOP_LOCK */ + +/* Define if you have the asnprintf function. */ +/* #undef HAVE_ASNPRINTF */ + +/* Define if you have the asprintf function. */ +#define HAVE_ASPRINTF 1 + +/* Define if you have the chown function. */ +#define HAVE_CHOWN 1 + +/* Define if you have the daemon function. */ +#define HAVE_DAEMON 1 + +/* Define if you have the dbm_firstkey function. */ +#define HAVE_DBM_FIRSTKEY 1 + +/* Define if you have the dn_expand function. */ +#define HAVE_DN_EXPAND 1 + +/* Define if you have the el_init function. */ +#define HAVE_EL_INIT 1 + +/* Define if you have the err function. */ +#define HAVE_ERR 1 + +/* Define if you have the errx function. */ +#define HAVE_ERRX 1 + +/* Define if you have the fchown function. */ +#define HAVE_FCHOWN 1 + +/* Define if you have the fcntl function. */ +#define HAVE_FCNTL 1 + +/* Define if you have the flock function. */ +#define HAVE_FLOCK 1 + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getdtablesize function. */ +#define HAVE_GETDTABLESIZE 1 + +/* Define if you have the gethostbyname function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define if you have the getopt function. */ +#define HAVE_GETOPT 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the getrlimit function. */ +#define HAVE_GETRLIMIT 1 + +/* Define if you have the getspnam function. */ +/* #undef HAVE_GETSPNAM */ + +/* Define if you have the getspuid function. */ +/* #undef HAVE_GETSPUID */ + +/* Define if you have the getusershell function. */ +#define HAVE_GETUSERSHELL 1 + +/* Define if you have the getvfsbyname function. */ +/* #undef HAVE_GETVFSBYNAME */ + +/* Define if you have the hstrerror function. */ +#define HAVE_HSTRERROR 1 + +/* Define if you have the inet_aton function. */ +#define HAVE_INET_ATON 1 + +/* Define if you have the initgroups function. */ +#define HAVE_INITGROUPS 1 + +/* Define if you have the kvm_nlist function. */ +#define HAVE_KVM_NLIST 1 + +/* Define if you have the kvm_open function. */ +#define HAVE_KVM_OPEN 1 + +/* Define if you have the lstat function. */ +#define HAVE_LSTAT 1 + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the mkstemp function. */ +#define HAVE_MKSTEMP 1 + +/* Define if you have the mktime function. */ +#define HAVE_MKTIME 1 + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the rcmd function. */ +#define HAVE_RCMD 1 + +/* Define if you have the readline function. */ +#define HAVE_READLINE 1 + +/* Define if you have the readv function. */ +#define HAVE_READV 1 + +/* Define if you have the recvmsg function. */ +#define HAVE_RECVMSG 1 + +/* Define if you have the res_search function. */ +#define HAVE_RES_SEARCH 1 + +/* Define if you have the sendmsg function. */ +#define HAVE_SENDMSG 1 + +/* Define if you have the setegid function. */ +#define HAVE_SETEGID 1 + +/* Define if you have the setenv function. */ +#define HAVE_SETENV 1 + +/* Define if you have the seteuid function. */ +#define HAVE_SETEUID 1 + +/* Define if you have the setregid function. */ +#define HAVE_SETREGID 1 + +/* Define if you have the setresuid function. */ +/* #undef HAVE_SETRESUID */ + +/* Define if you have the setreuid function. */ +#define HAVE_SETREUID 1 + +/* Define if you have the setsid function. */ +#define HAVE_SETSID 1 + +/* Define if you have the setsockopt function. */ +#define HAVE_SETSOCKOPT 1 + +/* Define if you have the snprintf function. */ +#define HAVE_SNPRINTF 1 + +/* Define if you have the socket function. */ +#define HAVE_SOCKET 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have the strlwr function. */ +/* #undef HAVE_STRLWR */ + +/* Define if you have the strnlen function. */ +/* #undef HAVE_STRNLEN */ + +/* Define if you have the strsep function. */ +#define HAVE_STRSEP 1 + +/* Define if you have the strtok_r function. */ +/* #undef HAVE_STRTOK_R */ + +/* Define if you have the strupr function. */ +/* #undef HAVE_STRUPR */ + +/* Define if you have the sysconf function. */ +#define HAVE_SYSCONF 1 + +/* Define if you have the sysctl function. */ +#define HAVE_SYSCTL 1 + +/* Define if you have the syslog function. */ +#define HAVE_SYSLOG 1 + +/* Define if you have the tgetent function. */ +#define HAVE_TGETENT 1 + +/* Define if you have the thr_yield function. */ +/* #undef HAVE_THR_YIELD */ + +/* Define if you have the unsetenv function. */ +#define HAVE_UNSETENV 1 + +/* Define if you have the vasnprintf function. */ +/* #undef HAVE_VASNPRINTF */ + +/* Define if you have the vasprintf function. */ +#define HAVE_VASPRINTF 1 + +/* Define if you have the verr function. */ +#define HAVE_VERR 1 + +/* Define if you have the verrx function. */ +#define HAVE_VERRX 1 + +/* Define if you have the vfsisloadable function. */ +/* #undef HAVE_VFSISLOADABLE */ + +/* Define if you have the vfsload function. */ +/* #undef HAVE_VFSLOAD */ + +/* Define if you have the vsnprintf function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the vsyslog function. */ +#define HAVE_VSYSLOG 1 + +/* Define if you have the vwarn function. */ +#define HAVE_VWARN 1 + +/* Define if you have the vwarnx function. */ +#define HAVE_VWARNX 1 + +/* Define if you have the warn function. */ +#define HAVE_WARN 1 + +/* Define if you have the warnx function. */ +#define HAVE_WARNX 1 + +/* Define if you have the writev function. */ +#define HAVE_WRITEV 1 + +/* Define if you have the <arpa/inet.h> header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define if you have the <arpa/nameser.h> header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define if you have the <asm/smp_lock.h> header file. */ +/* #undef HAVE_ASM_SMP_LOCK_H */ + +/* Define if you have the <asm/smplock.h> header file. */ +/* #undef HAVE_ASM_SMPLOCK_H */ + +/* Define if you have the <crypt.h> header file. */ +/* #undef HAVE_CRYPT_H */ + +/* Define if you have the <dbm.h> header file. */ +#define HAVE_DBM_H 1 + +/* Define if you have the <dirent.h> header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the <errno.h> header file. */ +#define HAVE_ERRNO_H 1 + +/* Define if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the <grp.h> header file. */ +#define HAVE_GRP_H 1 + +/* Define if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if you have the <ktypes.h> header file. */ +/* #undef HAVE_KTYPES_H */ + +/* Define if you have the <kvm.h> header file. */ +#define HAVE_KVM_H 1 + +/* Define if you have the <libelf/nlist.h> header file. */ +/* #undef HAVE_LIBELF_NLIST_H */ + +/* Define if you have the <linux/devfs_fs.h> header file. */ +/* #undef HAVE_LINUX_DEVFS_FS_H */ + +/* Define if you have the <linux/modversions.h> header file. */ +/* #undef HAVE_LINUX_MODVERSIONS_H */ + +/* Define if you have the <linux/types.h> header file. */ +/* #undef HAVE_LINUX_TYPES_H */ + +/* Define if you have the <machine/alpha/asm.h> header file. */ +/* #undef HAVE_MACHINE_ALPHA_ASM_H */ + +/* Define if you have the <machine/asm.h> header file. */ +#define HAVE_MACHINE_ASM_H 1 + +/* Define if you have the <machine/regdef.h> header file. */ +/* #undef HAVE_MACHINE_REGDEF_H */ + +/* Define if you have the <miscfs/genfs/genfs.h> header file. */ +/* #undef HAVE_MISCFS_GENFS_GENFS_H */ + +/* Define if you have the <ndbm.h> header file. */ +#define HAVE_NDBM_H 1 + +/* Define if you have the <netdb.h> header file. */ +#define HAVE_NETDB_H 1 + +/* Define if you have the <netinet/in.h> header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the <netinet/in6.h> header file. */ +/* #undef HAVE_NETINET_IN6_H */ + +/* Define if you have the <netinet/in6_machtypes.h> header file. */ +/* #undef HAVE_NETINET_IN6_MACHTYPES_H */ + +/* Define if you have the <netinet6/in6.h> header file. */ +/* #undef HAVE_NETINET6_IN6_H */ + +/* Define if you have the <nlist.h> header file. */ +#define HAVE_NLIST_H 1 + +/* Define if you have the <paths.h> header file. */ +#define HAVE_PATHS_H 1 + +/* Define if you have the <pwd.h> header file. */ +#define HAVE_PWD_H 1 + +/* Define if you have the <regdef.h> header file. */ +/* #undef HAVE_REGDEF_H */ + +/* Define if you have the <resolv.h> header file. */ +#define HAVE_RESOLV_H 1 + +/* Define if you have the <rpcsvc/dbm.h> header file. */ +/* #undef HAVE_RPCSVC_DBM_H */ + +/* Define if you have the <shadow.h> header file. */ +/* #undef HAVE_SHADOW_H */ + +/* Define if you have the <sys/bitypes.h> header file. */ +/* #undef HAVE_SYS_BITYPES_H */ + +/* Define if you have the <sys/cdefs.h> header file. */ +#define HAVE_SYS_CDEFS_H 1 + +/* Define if you have the <sys/filedesc.h> header file. */ +#define HAVE_SYS_FILEDESC_H 1 + +/* Define if you have the <sys/ioccom.h> header file. */ +#define HAVE_SYS_IOCCOM_H 1 + +/* Define if you have the <sys/ioctl.h> header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the <sys/lkm.h> header file. */ +#define HAVE_SYS_LKM_H 1 + +/* Define if you have the <sys/mman.h> header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define if you have the <sys/module.h> header file. */ +/* #undef HAVE_SYS_MODULE_H */ + +/* Define if you have the <sys/mount.h> header file. */ +#define HAVE_SYS_MOUNT_H 1 + +/* Define if you have the <sys/param.h> header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the <sys/poll.h> header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define if you have the <sys/proc.h> header file. */ +#define HAVE_SYS_PROC_H 1 + +/* Define if you have the <sys/queue.h> header file. */ +#define HAVE_SYS_QUEUE_H 1 + +/* Define if you have the <sys/resource.h> header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define if you have the <sys/select.h> header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define if you have the <sys/socket.h> header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the <sys/sockio.h> header file. */ +#define HAVE_SYS_SOCKIO_H 1 + +/* Define if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define if you have the <sys/syscallargs.h> header file. */ +#define HAVE_SYS_SYSCALLARGS_H 1 + +/* Define if you have the <sys/sysconfig.h> header file. */ +/* #undef HAVE_SYS_SYSCONFIG_H */ + +/* Define if you have the <sys/sysctl.h> header file. */ +#define HAVE_SYS_SYSCTL_H 1 + +/* Define if you have the <sys/sysent.h> header file. */ +/* #undef HAVE_SYS_SYSENT_H */ + +/* Define if you have the <sys/sysproto.h> header file. */ +/* #undef HAVE_SYS_SYSPROTO_H */ + +/* Define if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the <sys/tty.h> header file. */ +#define HAVE_SYS_TTY_H 1 + +/* Define if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define if you have the <sys/uio.h> header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the <sys/user.h> header file. */ +#define HAVE_SYS_USER_H 1 + +/* Define if you have the <sys/utsname.h> header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define if you have the <sys/vfs.h> header file. */ +/* #undef HAVE_SYS_VFS_H */ + +/* Define if you have the <syslog.h> header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the <termios.h> header file. */ +#define HAVE_TERMIOS_H 1 + +/* Define if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the <vm/vm.h> header file. */ +#define HAVE_VM_VM_H 1 + +/* Define if you have the <vm/vm_extern.h> header file. */ +#define HAVE_VM_VM_EXTERN_H 1 + +/* Define if you have the <vm/vm_object.h> header file. */ +#define HAVE_VM_VM_OBJECT_H 1 + +/* Define if you have the <vm/vm_pager.h> header file. */ +#define HAVE_VM_VM_PAGER_H 1 + +/* Define if you have the <vm/vm_zone.h> header file. */ +/* #undef HAVE_VM_VM_ZONE_H */ + +/* Define if you have the <vm/vnode_pager.h> header file. */ +#define HAVE_VM_VNODE_PAGER_H 1 + +/* Define if you have the curses library (-lcurses). */ +/* #undef HAVE_LIBCURSES */ + +/* Define if you have the db library (-ldb). */ +/* #undef HAVE_LIBDB */ + +/* Define if you have the edit library (-ledit). */ +#define HAVE_LIBEDIT 1 + +/* Define if you have the gdbm library (-lgdbm). */ +/* #undef HAVE_LIBGDBM */ + +/* Define if you have the kvm library (-lkvm). */ +#define HAVE_LIBKVM 1 + +/* Define if you have the ndbm library (-lndbm). */ +/* #undef HAVE_LIBNDBM */ + +/* Define if you have the nsl library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define if you have the readline library (-lreadline). */ +/* #undef HAVE_LIBREADLINE */ + +/* Define if you have the resolv library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define if you have the socket library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define if you have the syslog library (-lsyslog). */ +/* #undef HAVE_LIBSYSLOG */ + +/* Define if you have the termcap library (-ltermcap). */ +#define HAVE_LIBTERMCAP 1 + +#define HAVE_INT8_T 1 +#define HAVE_INT16_T 1 +#define HAVE_INT32_T 1 +#define HAVE_INT64_T 1 +#define HAVE_U_INT8_T 1 +#define HAVE_U_INT16_T 1 +#define HAVE_U_INT32_T 1 +#define HAVE_U_INT64_T 1 +/* #undef HAVE_BOOL */ +#define HAVE_SSIZE_T 1 +#define HAVE_REGISTER_T 1 +/* #undef HAVE_INT32 */ +/* #undef HAVE_U_INT32 */ +/* #undef HAVE_INTPTR_T */ + +#define EFF_NTOHL ntohl + +/* RCSID */ +#define RCSID(msg) \ +static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } + +#define VERSION "0.24pre" +#define PACKAGE "arla" + +/* Check for posix signals */ +#define HAVE_POSIX_SIGNALS 1 + +#define HAVE_READLINE 1 + +/* prefix for /dev/fd */ +/* #undef DEV_FD_PREFIX */ + +/* does the system have /dev/fd? */ +/* #undef HAVE_DEV_FD */ + +/* we always have stds.h */ +#define HAVE_STDS_H + +/* We have krb_principal from kth-krb ? */ +#define HAVE_KRB_PRINCIPAL 1 + +/* Define if you have a krb_get_err_text (otherwise, you should really + get more modern kerberos code) */ +#define HAVE_KRB_GET_ERR_TEXT 1 + +/* If we have _res */ +/* #undef HAVE__RES */ + +/* Define if you have kerberos */ +#define KERBEROS 1 + +/* Define if your kernel has a vop_nolock */ +/* #undef HAVE_KERNEL_VOP_NOLOCK */ + +/* Define if your kernel has a vop_nounlock */ +/* #undef HAVE_KERNEL_VOP_NOUNLOCK */ + +/* Define if your kernel has a vop_noislocked */ +/* #undef HAVE_KERNEL_VOP_NOISLOCKED */ + +/* Define if your kernel has a vop_stdnolock */ +/* #undef HAVE_KERNEL_VOP_STDLOCK */ + +/* Define if your kernel has a vop_stdnounlock */ +/* #undef HAVE_KERNEL_VOP_STDUNLOCK */ + +/* Define if your kernel has a vop_stdnoislocked */ +/* #undef HAVE_KERNEL_VOP_STDISLOCKED */ + +/* Define if your kernel has a vop_revoke */ +/* #undef HAVE_KERNEL_VOP_REVOKE */ + +/* Define if your kernel has a genfs_nolock */ +/* #undef HAVE_KERNEL_GENFS_NOLOCK */ + +/* Define if your kernel has a genfs_nounlock */ +/* #undef HAVE_KERNEL_GENFS_NOUNLOCK */ + +/* Define if your kernel has a genfs_noislocked */ +/* #undef HAVE_KERNEL_GENFS_NOISLOCKED */ + +/* Define if your kernel has a genfs_revoke */ +/* #undef HAVE_KERNEL_GENFS_REVOKE */ + +/* Define if your kernel has a vfs_opv_init */ +#define HAVE_KERNEL_VFS_OPV_INIT 1 + +/* Define if your kernel has a vfs_opv_init_default */ +#define HAVE_KERNEL_VFS_OPV_INIT_DEFAULT 1 + +/* Define if your kernel has a vfs_opv_init_explicit */ +#define HAVE_KERNEL_VFS_OPV_INIT_EXPLICIT 1 + +/* Define if your kernel has a vfs_add_vnodeops */ +/* #undef HAVE_KERNEL_VFS_ADD_VNODEOPS */ + +/* Define if your kernel has a vfs_attach */ +/* #undef HAVE_KERNEL_VFS_ATTACH */ + +/* Define if your kernel has a vfs_register */ +#define HAVE_KERNEL_VFS_REGISTER 1 + +/* Define if your kernel has a vfs_getnewfsid */ +#define HAVE_KERNEL_VFS_GETNEWFSID 1 + +/* Define if your kernel has a vfs_getvfs */ +#define HAVE_KERNEL_VFS_GETVFS 1 + +/* Define if your kernel has a vfs_object_create */ +/* #undef HAVE_KERNEL_VFS_OBJECT_CREATE */ + +/* Define if your kernel has a zfreei */ +/* #undef HAVE_KERNEL_ZFREEI */ + +/* Define if your kernel has a vfs_cache_lookup */ +/* #undef HAVE_KERNEL_VFS_CACHE_LOOKUP */ + +/* Define if your kernel has a vnode_pager_generic_putpages */ +/* #undef HAVE_KERNEL_VNODE_PAGER_GENERIC_PUTPAGES */ + +/* Define if your kernel has a vnode_pager_generic_getpages */ +/* #undef HAVE_KERNEL_VNODE_PAGER_GENERIC_GETPAGES */ + +/* Define if your kernel has a vnode_pager_setsize */ +#define HAVE_KERNEL_VNODE_PAGER_SETSIZE 1 + +/* Define if your kernel has a doforce */ +#define HAVE_KERNEL_DOFORCE 1 + +/* Define if your struct dirent has a field d_type */ +#define HAVE_STRUCT_DIRENT_D_TYPE 1 + +/* Define if your struct vfsconf has a field vfc_refcount */ +#define HAVE_STRUCT_VFSCONF_VFC_REFCOUNT 1 + +/* Define if your struct vfsconf has a field vfc_mountroot */ +/* #undef HAVE_STRUCT_VFSCONF_VFC_MOUNTROOT */ + +/* Define if your struct uio has a field uio_procp */ +#define HAVE_STRUCT_UIO_UIO_PROCP 1 + +/* Define if your struct vfsops has a field vfs_opv_descs */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_OPV_DESCS */ + +/* Define if your struct vfsops has a field vfs_name */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_NAME */ + +/* Define if your struct vfsops has a field vfs_oid */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_OID */ + +/* Define if your struct vfsops has a field vfs_checkexp */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */ + +/* Define if your struct vfsops has a field vfs_uninit */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_UNINIT */ + +/* Define if you want to use mmap:ed time */ +/* #undef USE_MMAPTIME */ + +/* Define if your hstrerror needs const like SunOS 5.6 */ +#define NEED_HSTRERROR_CONST 1 + +/* Define if your hstrerror need proto */ +/* #undef NEED_HSTRERROR_PROTO */ + +/* define if the system is missing a prototype for inet_aton() */ +/* #undef NEED_INET_ATON_PROTO */ + +/* Define if you have gnu libc */ +/* #undef HAVE_GLIBC */ + +/* Define this if `struct sockaddr' includes sa_len */ +#define SOCKADDR_HAS_SA_LEN 1 + +/* Define this if htnol is broken, but can be fixed with define magic */ +/* #undef HAVE_REPAIRABLE_HTONL */ + +/* Define this if struct ViceIoctl is defined by linux/fs.h */ +/* #undef HAVE_STRUCT_VICEIOCTL_IN */ + +/* Linux kernel types */ +/* #undef HAVE_LINUX_KERNEL_INT8_T */ +/* #undef HAVE_LINUX_KERNEL_INT16_T */ +/* #undef HAVE_LINUX_KERNEL_INT32_T */ +/* #undef HAVE_LINUX_KERNEL_INT64_T */ +/* #undef HAVE_LINUX_KERNEL_U_INT8_T */ +/* #undef HAVE_LINUX_KERNEL_U_INT16_T */ +/* #undef HAVE_LINUX_KERNEL_U_INT32_T */ +/* #undef HAVE_LINUX_KERNEL_U_INT64_T */ + +/* Define this if you have a struct new_stat */ +/* #undef HAVE_STRUCT_NEW_STAT */ + +/* Define this if you have a type vop_t */ +/* #undef HAVE_VOP_T */ + +/* Define this is you have a vfssw */ +/* #undef HAVE_VFSSW */ + +/* Define this if struct mount have mnt_syncer */ +#define HAVE_STRUCT_MOUNT_MNT_SYNCER 1 + +/* Define this if struct proc have p_sigmask */ +#define HAVE_STRUCT_PROC_P_SIGMASK 1 + +/* Define this if you have struct a_flags instead of a_waitfor in vop_fseek*/ +/* #undef HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS */ + +/* Define this if struct proc have p_retval */ +/* #undef HAVE_STRUCT_PROC_P_RETVAL */ + +/* Define this if struct file_operations has flush */ +/* #undef HAVE_STRUCT_FILE_OPERATIONS_FLUSH */ + +/* Define this if the read_super superoperation takes the dir_d argument */ +/* #undef HAVE_READ_SUPER_FOUR_ARGS */ + +/* Define this if the follow_link inode-operation takes the follow argument */ +/* #undef HAVE_FOLLOW_LINK_THREE_ARGS */ + +/* Define this if your full_name_hash works with 8bit characters */ +/* #undef HAVE_FULL_NAME_HASH_8BIT */ + +/* Define if your getvfsbyname takes two arguments */ +/* #undef HAVE_GETVFSBYNAME_TWO_ARGS */ + +/* Define if you have DIRSIZ in <dirent.h> */ +/* #undef DIRSIZ_IN_DIRENT_H */ + +/* Define if you have DIRSIZ in <sys/dir.h> */ +#define DIRSIZ_IN_SYS_DIR_H 1 + +/* Define if you have GENERIC_DIRENT in <sys/dirent.h> */ +/* #undef GENERIC_DIRSIZ_IN_SYS_DIRENT_H */ + +/* Define if running on Irix 6.4 or later */ +/* #undef IRIX_64 */ + +/* + * Defintions that are ugly but needed to get all the symbols used + */ + +/* + * Defining this enables lots of useful (and used) extensions on + * glibc-based systems such as Linux + */ + +#define _GNU_SOURCE + +/* + * Defining this enables us to get the definition of `sigset_t' and + * other importatnt definitions on Solaris. + */ + +#define __EXTENSIONS__ diff --git a/sys/xfs/xfs_deb.c b/sys/xfs/xfs_deb.c index f1f259404bb..2e838360af7 100644 --- a/sys/xfs/xfs_deb.c +++ b/sys/xfs/xfs_deb.c @@ -1,6 +1,5 @@ -/* $OpenBSD: xfs_deb.c,v 1.1 1998/08/30 16:47:20 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,15 +37,24 @@ */ #include <xfs/xfs_deb.h> +#include <xfs/xfs_debug.h> -/* $KTH: xfs_deb.c,v 1.3 1998/03/20 21:02:32 art Exp $ */ +/* $Id: xfs_deb.c,v 1.2 1999/04/30 01:59:00 art Exp $ */ /* X is on */ #define X(y) y /* and x is off */ #define x(y) 0 -int xfsdeb = (0 - | - x(XDEBANY) +unsigned int xfsdeb = (0 | + x(XDEBDEV) | + x(XDEBMSG) | + x(XDEBDNLC) | + x(XDEBNODE) | + x(XDEBVNOPS) | + x(XDEBVFOPS) | + x(XDEBLKM) | + x(XDEBSYS) | + x(XDEBMEM) | + 0 ); diff --git a/sys/xfs/xfs_deb.h b/sys/xfs/xfs_deb.h index cfec18d92af..dcfb21f97d9 100644 --- a/sys/xfs/xfs_deb.h +++ b/sys/xfs/xfs_deb.h @@ -1,4 +1,3 @@ -/* $OpenBSD: xfs_deb.h,v 1.2 1998/08/31 05:13:22 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,27 +36,30 @@ * SUCH DAMAGE. */ -#ifndef _XFS_XFS_DEB_H_ -#define _XFS_XFS_DEB_H_ +/* $Id: xfs_deb.h,v 1.3 1999/04/30 01:59:00 art Exp $ */ -/* masks */ -#define XDEBANY 0xffffffff -#define XDEBDEV 0x00000001 -#define XDEBMSG 0x00000002 -#define XDEBDNLC 0x00000004 -#define XDEBNODE 0x00000008 -#define XDEBVNOPS 0x00000010 -#define XDEBVFOPS 0x00000020 -#define XDEBLKM 0x00000040 -#define XDEBSYS 0x00000080 -#define XDEBMEM 0x00000100 +#ifndef _xfs_deb_h +#define _xfs_deb_h -extern int xfsdeb; +#include <xfs/xfs_debug.h> -#ifdef DEBUG +#define HAVE_XDEBDEV +#define HAVE_XDEBMSG +#define HAVE_XDEBDNLC +#define HAVE_XDEBNODE +#define HAVE_XDEBVNOPS +#define HAVE_XDEBVFOPS +#define HAVE_XDEBLKM +#define HAVE_XDEBSYS +#define HAVE_XDEBMEM +#define HAVE_XDEBSYS + +extern unsigned int xfsdeb; + +#ifdef XFS_DEBUG #define XFSDEB(mask, args) do { if (mask&xfsdeb) printf args; } while (0) #else #define XFSDEB(mask, args) do { ; } while (0) #endif -#endif +#endif /* _xfs_deb_h */ diff --git a/sys/xfs/xfs_debug.h b/sys/xfs/xfs_debug.h new file mode 100644 index 00000000000..04201a25b85 --- /dev/null +++ b/sys/xfs/xfs_debug.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: xfs_debug.h,v 1.1 1999/04/30 01:59:00 art Exp $ */ + +#ifndef __XFS_DEBUG_H +#define __XFS_DEBUG_H + +/* + * These are GLOBAL xfs debugging masks + * + * Define HAVE_XDEB in your local xfs_deb.h if + * you want your fs to handle the debugging flags. + */ + +/* Masks for the debug macro */ +#define XDEBDEV 0x00000001 /* device handling */ +#define XDEBMSG 0x00000002 /* message sending */ +#define XDEBDNLC 0x00000004 /* name cache */ +#define XDEBNODE 0x00000008 /* xfs nodes */ +#define XDEBVNOPS 0x00000010 /* vnode operations */ +#define XDEBVFOPS 0x00000020 /* vfs operations */ +#define XDEBLKM 0x00000040 /* LKM handling */ +#define XDEBSYS 0x00000080 /* syscalls */ +#define XDEBMEM 0x00000100 /* memory allocation */ +#define XDEBREADDIR 0x00000200 /* readdir (linux) */ +#define XDEBLOCK 0x00000400 /* locking (linux) */ +#define XDEBCACHE 0x00000800 /* Cache handeling (linux) */ + +#endif diff --git a/sys/xfs/xfs_dev-bsd.c b/sys/xfs/xfs_dev-bsd.c new file mode 100644 index 00000000000..b7c7ddf9f1d --- /dev/null +++ b/sys/xfs/xfs_dev-bsd.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <xfs/xfs_locl.h> +#include <xfs/xfs_message.h> +#include <xfs/xfs_msg_locl.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_dev.h> +#include <xfs/xfs_deb.h> + +RCSID("$Id: xfs_dev-bsd.c,v 1.1 1999/04/30 01:59:00 art Exp $"); + +int +xfs_devopen(dev_t dev, int flag, int devtype, struct proc *proc) +{ + XFSDEB(XDEBDEV, ("xfsopen dev = %d.%d, flag = %d, devtype = %d\n", + major(dev), minor(dev), flag, devtype)); + return xfs_devopen_common(dev); +} + +/* XXX ugly function so we can keep xfs_devopen static */ +int +xfs_func_is_devopen(void *func) +{ + return func == (void*)&xfs_devopen; +} + +int +xfs_devclose(dev_t dev, int flag, int devtype, struct proc *p) +{ + XFSDEB(XDEBDEV, ("xfs_devclose dev = %d, flag = %d\n", dev, flag)); + return xfs_devclose_common(dev, p); +} + +/* + * Not used. + */ + +int +xfs_devioctl(dev_t dev, +#if defined(__NetBSD__) || defined(__OpenBSD__) + u_long cmd, +#elif defined(__FreeBSD__) + int cmd, +#endif + caddr_t data, int flags, struct proc *p) +{ + XFSDEB(XDEBDEV, ("xfs_devioctl dev = %d.%d, cmd = %lu, " + "data = %p, flags = %x\n", + major(dev), minor(dev), (unsigned long)cmd, data, flags)); + return ENOTTY; +} + +static int +xfs_realselect(dev_t dev, struct proc *p) +{ + struct xfs_channel *chan = &xfs_channel[minor(dev)]; + + if (!xfs_emptyq(&chan->messageq)) + return 1; /* Something to read */ + + selrecord (p, &chan->selinfo); + return 0; +} + + +#ifdef HAVE_VOP_POLL +static int +xfs_devpoll(dev_t dev, int events, struct proc * p) +{ + XFSDEB(XDEBDEV, ("xfs_devpoll dev = %d, events = %d\n", dev, events)); + + if (!(events & POLLRDNORM)) + return 0; + + return xfs_realselect(dev, p); +} + +#endif + +#ifdef HAVE_VOP_SELECT +int +xfs_devselect(dev_t dev, int which, struct proc * p) +{ + XFSDEB(XDEBDEV, ("xfs_devselect dev = %d, which = %d\n", dev, which)); + + if (which != FREAD) + return 0; + + return xfs_realselect(dev, p); +} + +#endif + +void +xfs_select_wakeup(struct xfs_channel *chan) +{ + selwakeup (&chan->selinfo); +} + +/* + * Install and uninstall device. + */ + +#if defined(__NetBSD__) +struct cdevsw xfs_dev = { + xfs_devopen, + xfs_devclose, + xfs_devread, + xfs_devwrite, + xfs_devioctl, + (dev_type_stop((*))) enodev, + 0, + xfs_devpoll, + (dev_type_mmap((*))) enodev, + 0 +}; + +#elif defined(__OpenBSD__) +struct cdevsw xfs_dev = { + xfs_devopen, + xfs_devclose, + xfs_devread, + xfs_devwrite, + xfs_devioctl, + (dev_type_stop((*))) enodev, + 0, + xfs_devselect, + (dev_type_mmap((*))) enodev, + 0 +}; + +#elif defined(__FreeBSD__) +struct cdevsw xfs_dev = { + xfs_devopen, + xfs_devclose, + xfs_devread, + xfs_devwrite, + xfs_devioctl, + nostop, + noreset, + nodevtotty, +#if defined(HAVE_VOP_SELECT) + xfs_devselect, +#elif defined(HAVE_VOP_POLL) + xfs_devpoll, +#else +#error select or poll: that is the question +#endif + nommap, + nostrategy, + NULL, + 0 +}; + +#endif /* FreeBSD */ + +int +xfs_install_device(void) +{ + int i; + + for (i = 0; i < NXFS; i++) { + XFSDEB(XDEBDEV, ("before initq(messageq and sleepq)\n")); + xfs_initq(&xfs_channel[i].messageq); + xfs_initq(&xfs_channel[i].sleepq); + } + + return 0; +} + +int +xfs_uninstall_device(void) +{ + int i; + struct xfs_channel *chan; + + for (i = 0; i < NXFS; i++) { + chan = &xfs_channel[i]; + if (chan->status & CHANNEL_OPENED) + xfs_devclose(makedev(0, i), 0, 0, NULL); + } + + return 0; +} + +int +xfs_stat_device(void) +{ + return xfs_uprintf_device(); +} diff --git a/sys/xfs/xfs_dev-common.c b/sys/xfs/xfs_dev-common.c new file mode 100644 index 00000000000..d1ab98d67d8 --- /dev/null +++ b/sys/xfs/xfs_dev-common.c @@ -0,0 +1,564 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + +#include <xfs/xfs_locl.h> +#include <xfs/xfs_message.h> +#include <xfs/xfs_msg_locl.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_dev.h> +#include <xfs/xfs_deb.h> + +RCSID("$Id: xfs_dev-common.c,v 1.1 1999/04/30 01:59:00 art Exp $"); + +struct xfs_channel xfs_channel[NXFS]; + +void +xfs_initq(struct xfs_link *q) +{ + q->next = q; + q->prev = q; +} + +/* Is this queue empty? */ +int +xfs_emptyq(struct xfs_link *q) +{ + return q->next == q; +} + +/* Is this link on any queue? Link *must* be inited! */ +int +xfs_onq(struct xfs_link *link) +{ + return link->next != NULL || link->prev != NULL; +} + +/* Append q with p */ +void +xfs_appendq(struct xfs_link *q, struct xfs_link *p) +{ + p->next = q; + p->prev = q->prev; + p->prev->next = p; + q->prev = p; +} + +void +xfs_outq(struct xfs_link *p) +{ + p->next->prev = p->prev; + p->prev->next = p->next; + p->next = p->prev = 0; +} + +/* + * Only allow one open. + */ +int +xfs_devopen_common(dev_t dev) +{ + struct xfs_channel *chan; + + if (minor(dev) < 0 || minor(dev) >= NXFS) + return ENXIO; + + chan = &xfs_channel[minor(dev)]; + + /* Only allow one reader/writer */ + if (chan->status & CHANNEL_OPENED) { + XFSDEB(XDEBDEV, ("xfs_devopen: already open\n")); + return EBUSY; + } else + chan->status |= CHANNEL_OPENED; + + chan->message_buffer = xfs_alloc(MAX_XMSG_SIZE); + + /* initalize the queues if they have not been initialized before */ + xfs_initq(&chan->sleepq); + xfs_initq(&chan->messageq); + + return 0; +} + +#if defined(HAVE_THREE_ARGUMENT_VFS_BUSY) +#define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags), (lock)) +#define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp)) +#elif defined(HAVE_FOUR_ARGUMENT_VFS_BUSY) +#define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp), (flags), (lock), (proc)) +#define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp), (proc)) +#elif defined(__osf__) +#define xfs_vfs_busy(mp, flags, lock, proc) (0) +#define xfs_vfs_unbusy(mp, proc) (0) +#else +#define xfs_vfs_busy(mp, flags, lock, proc) vfs_busy((mp)) +#define xfs_vfs_unbusy(mp, proc) vfs_unbusy((mp)) +#endif + +/* + * Wakeup all sleepers and cleanup. + */ +int +xfs_devclose_common(dev_t dev, struct proc *proc) +{ + struct xfs_channel *chan = &xfs_channel[minor(dev)]; + struct xfs_link *first; + + /* Sanity check, paranoia? */ + if (!(chan->status & CHANNEL_OPENED)) + panic("xfs_devclose never opened?"); + + chan->status &= ~CHANNEL_OPENED; + + /* No one is going to read those messages so empty queue! */ + while (!xfs_emptyq(&chan->messageq)) { + XFSDEB(XDEBDEV, ("before outq(messageq)\n")); + + first = chan->messageq.next; + xfs_outq(first); + if (first->error_or_size != 0) + xfs_free(first, first->error_or_size); + + XFSDEB(XDEBDEV, ("after outq(messageq)\n")); + } + + /* Wakeup those waiting for replies that will never arrive. */ + while (!xfs_emptyq(&chan->sleepq)) { + XFSDEB(XDEBDEV, ("before outq(sleepq)\n")); + first = chan->sleepq.next; + xfs_outq(first); + first->error_or_size = ENODEV; + wakeup((caddr_t) first); + XFSDEB(XDEBDEV, ("after outq(sleepq)\n")); + } + + if (chan->status & CHANNEL_WAITING) + wakeup((caddr_t) chan); + + if (chan->message_buffer) { + xfs_free(chan->message_buffer, MAX_XMSG_SIZE); + chan->message_buffer = NULL; + } + + /* + * Free all xfs nodes. + */ + + if (xfs[minor(dev)].mp != NULL) { + if (xfs_vfs_busy(xfs[minor(dev)].mp, 0, NULL, proc)) { + XFSDEB(XDEBNODE, ("xfs_dev_close: vfs_busy() --> BUSY\n")); + return EBUSY; + } + free_all_xfs_nodes(&xfs[minor(dev)], FORCECLOSE, 0); + + xfs_vfs_unbusy(xfs[minor(dev)].mp, proc); + } + + return 0; +} + +/* + * Move messages from kernel to user space. + */ +int +xfs_devread(dev_t dev, struct uio * uiop, int ioflag) +{ + struct xfs_channel *chan = &xfs_channel[minor(dev)]; + struct xfs_link *first; + int error = 0; + + XFSDEB(XDEBDEV, ("xfs_devread dev = %d\n", dev)); + + XFSDEB(XDEBDEV, ("xfs_devread: m = %p, m->prev = %p, m->next = %p\n", + &chan->messageq, chan->messageq.prev, chan->messageq.next)); + + again: + + if (!xfs_emptyq (&chan->messageq)) { + while (!xfs_emptyq (&chan->messageq)) { + /* Remove message */ + first = chan->messageq.next; + XFSDEB(XDEBDEV, ("xfs_devread: first = %p, " + "first->prev = %p, first->next = %p\n", + first, first->prev, first->next)); + + XFSDEB(XDEBDEV, ("xfs_devread: message->size = %u\n", + first->message->size)); + + error = uiomove((caddr_t) first->message, first->message->size, + uiop); + if (error) + break; + + xfs_outq(first); + + if (first->error_or_size != 0) + xfs_free(first, first->error_or_size); + } + } else { + chan->status |= CHANNEL_WAITING; + if (tsleep((caddr_t) chan, (PZERO + 1) | PCATCH, "xfsr", 0)) { + XFSDEB(XDEBMSG, ("caught signal xfs_devread\n")); + error = EINTR; + } else if ((chan->status & CHANNEL_WAITING) == 0) { + goto again; + } else + error = EIO; + } + + + XFSDEB(XDEBDEV, ("xfs_devread done error = %d\n", error)); + + return error; +} + +/* + * Move messages from user space to kernel space, + * wakeup sleepers, insert new data in VFS. + */ +int +xfs_devwrite(dev_t dev, struct uio *uiop, int ioflag) +{ + struct xfs_channel *chan = &xfs_channel[minor(dev)]; + char *p; + int error; + u_int cnt; + struct xfs_message_header *msg_buf; + + XFSDEB(XDEBDEV, ("xfs_devwrite dev = %d\n", dev)); + + cnt = uiop->uio_resid; + error = uiomove((caddr_t) chan->message_buffer, MAX_XMSG_SIZE, uiop); + if (error != 0) + return error; + + cnt -= uiop->uio_resid; + + /* + * This thread handles the received message. + */ + for (p = (char *)chan->message_buffer; + cnt > 0; + p += msg_buf->size, cnt -= msg_buf->size) { + struct proc *pp = xfs_uio_to_proc(uiop); + + msg_buf = (struct xfs_message_header *)p; + error = xfs_message_receive (minor(dev), + msg_buf, + msg_buf->size, + pp); + } + XFSDEB(XDEBDEV, ("xfs_devwrite error = %d\n", error)); + return error; +} + +/* + * Send a message to user space. + */ +int +xfs_message_send(int fd, struct xfs_message_header * message, u_int size) +{ + struct xfs_channel *chan = &xfs_channel[fd]; + struct { + struct xfs_link this_message; + struct xfs_message_header msg; + } *t; + + XFSDEB(XDEBMSG, ("xfs_message_send opcode = %d\n", message->opcode)); + + if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */ + return ENODEV; + + /* Prepare message and copy it later */ + message->size = size; + message->sequence_num = chan->nsequence++; + + t = xfs_alloc(sizeof(t->this_message) + size); + t->this_message.error_or_size = sizeof(t->this_message) + size; + bcopy(message, &t->msg, size); + + t->this_message.message = &t->msg; + xfs_appendq(&chan->messageq, &t->this_message); + if (chan->status & CHANNEL_WAITING) { + chan->status &= ~CHANNEL_WAITING; + wakeup((caddr_t) chan); + } + xfs_select_wakeup(chan); + + return 0; +} + +/* + * Send a message to user space and wait for reply. + */ +int +xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size) +{ + int ret; + struct xfs_channel *chan = &xfs_channel[fd]; + struct xfs_link *this_message; + struct xfs_link *this_process; + struct xfs_message_header *msg; +#if defined(HAVE_STRUCT_PROC_P_SIGMASK) + sigset_t oldsigmask; +#endif /* HAVE_STRUCT_PROC_P_SIGMASK */ + + XFSDEB(XDEBMSG, ("xfs_message_rpc opcode = %d\n", message->opcode)); + + if (!(chan->status & CHANNEL_OPENED)) /* No receiver? */ + return ENODEV; + + if (size < sizeof(struct xfs_message_wakeup)) { + printf("XFS PANIC Error: Message to small to receive wakeup, opcode = %d\n", message->opcode); + return ENOMEM; + } + this_message = xfs_alloc(sizeof(struct xfs_link)); + this_process = xfs_alloc(sizeof(struct xfs_link)); + msg = xfs_alloc(size); + bcopy(message, msg, size); + + msg->size = size; + msg->sequence_num = chan->nsequence++; + this_message->error_or_size = 0; + this_message->message = msg; + this_process->message = msg; + xfs_appendq(&chan->messageq, this_message); + xfs_appendq(&chan->sleepq, this_process); + xfs_select_wakeup(chan); + this_process->error_or_size = 0; + + if (chan->status & CHANNEL_WAITING) { + chan->status &= ~CHANNEL_WAITING; + wakeup((caddr_t) chan); + } + + /* + * Remove SIGIO from the sigmask so no IO will + * wake us up from tsleep() + */ + +#ifdef HAVE_STRUCT_PROC_P_SIGMASK + oldsigmask = xfs_curproc()->p_sigmask; +#ifdef __sigaddset + __sigaddset(&xfs_curproc()->p_sigmask, SIGIO); +#else + xfs_curproc()->p_sigmask |= sigmask(SIGIO); +#endif /* __sigaddset */ +#elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK) + oldsigmask = xfs_curproc()->p_sigwaitmask; + sigaddset(&xfs_curproc()->p_sigwaitmask, SIGIO); +#endif + /* + * We have to check if we have a receiver here too because the + * daemon could have terminated before we sleep. This seems to + * happen sometimes when rebooting. + */ + if (!(chan->status & CHANNEL_OPENED) || + tsleep((caddr_t) this_process, (PZERO + 1) | PCATCH, "xfs", 0)) { + XFSDEB(XDEBMSG, ("caught signal\n")); + this_process->error_or_size = EINTR; + } + +#ifdef HAVE_STRUCT_PROC_P_SIGMASK + xfs_curproc()->p_sigmask = oldsigmask; +#elif defined(HAVE_STRUCT_PROC_P_SIGWAITMASK) + xfs_curproc()->p_sigwaitmask = oldsigmask; +#endif + + /* + * Caught signal, got reply message or device was closed. + * Need to clean up both messageq and sleepq. + */ + if (xfs_onq(this_message)) { + xfs_outq(this_message); + } + if (xfs_onq(this_process)) { + xfs_outq(this_process); + } + ret = this_process->error_or_size; + + XFSDEB(XDEBMSG, ("xfs_message_rpc this_process->error_or_size = %d\n", + this_process->error_or_size)); + XFSDEB(XDEBMSG, ("xfs_message_rpc opcode ((xfs_message_wakeup*)(this_process->message))->error = %d\n", ((struct xfs_message_wakeup *) (this_process->message))->error)); + + bcopy(msg, message, size); + + xfs_free(this_message, sizeof(*this_message)); + xfs_free(this_process, sizeof(*this_process)); + xfs_free(msg, size); + + return ret; +} + +/* + * For each message type there is a message handler + * that implements its action, xfs_message_receive + * invokes the correct function. + */ +int +xfs_message_receive(int fd, + struct xfs_message_header *message, + u_int size, + struct proc *p) +{ + XFSDEB(XDEBMSG, ("xfs_message_receive opcode = %d\n", message->opcode)); + + /* Dispatch and coerce message type */ + switch (message->opcode) { + case XFS_MSG_WAKEUP: + return xfs_message_wakeup(fd, + (struct xfs_message_wakeup *) message, + message->size, + p); + case XFS_MSG_WAKEUP_DATA: + return xfs_message_wakeup_data(fd, + (struct xfs_message_wakeup_data *) message, + message->size, + p); + case XFS_MSG_INSTALLROOT: + return xfs_message_installroot(fd, + (struct xfs_message_installroot *) message, + message->size, + p); + case XFS_MSG_INSTALLNODE: + return xfs_message_installnode(fd, + (struct xfs_message_installnode *) message, + message->size, + p); + case XFS_MSG_INSTALLATTR: + return xfs_message_installattr(fd, + (struct xfs_message_installattr *) message, + message->size, + p); + case XFS_MSG_INSTALLDATA: + return xfs_message_installdata(fd, + (struct xfs_message_installdata *) message, + message->size, + p); + case XFS_MSG_INVALIDNODE: + return xfs_message_invalidnode(fd, + (struct xfs_message_invalidnode *) message, + message->size, + p); + case XFS_MSG_UPDATEFID: + return xfs_message_updatefid(fd, + (struct xfs_message_updatefid *)message, + message->size, + p); + default: + printf("XFS PANIC Warning xfs_dev: Unknown message opcode == %d\n", + message->opcode); + return EINVAL; + } +} + +int +xfs_message_wakeup(int fd, + struct xfs_message_wakeup *message, + u_int size, + struct proc *p) +{ + struct xfs_channel *chan = &xfs_channel[fd]; + struct xfs_link *sleepq = &chan->sleepq; + struct xfs_link *t = chan->sleepq.next; /* Really first in q */ + + XFSDEB(XDEBMSG, ("xfs_message_wakeup error: %d\n", message->error)); + + for (; t != sleepq; t = t->next) + if (t->message->sequence_num == message->sleepers_sequence_num) { + if (t->message->size < size) { + printf("XFS PANIC Error: Could not wakeup requestor with opcode = %d properly, to small receive buffer.\n", t->message->opcode); + t->error_or_size = ENOMEM; + } else + bcopy(message, t->message, size); + + wakeup((caddr_t) t); + break; + } + + return 0; +} + +int +xfs_message_wakeup_data(int fd, + struct xfs_message_wakeup_data * message, + u_int size, + struct proc *p) +{ + struct xfs_channel *chan = &xfs_channel[fd]; + struct xfs_link *sleepq = &chan->sleepq; + struct xfs_link *t = chan->sleepq.next; /* Really first in q */ + + XFSDEB(XDEBMSG, ("xfs_message_wakeup_data error: %d\n", message->error)); + + for (; t != sleepq; t = t->next) + if (t->message->sequence_num == message->sleepers_sequence_num) { + if (t->message->size < size) { + printf("XFS PANIC Error: Could not wakeup requestor with opcode = %d properly, to small receive buffer.\n", t->message->opcode); + t->error_or_size = ENOMEM; + } else + bcopy(message, t->message, size); + wakeup((caddr_t) t); + break; + } + return 0; +} + +/* + * + */ +int +xfs_uprintf_device(void) +{ +#if 0 + int i; + + for (i = 0; i < NXFS; i++) { + uprintf("xfs_channel[%d] = {\n", i); + uprintf("messageq.next = %p ", xfs_channel[i].messageq.next); + uprintf("messageq.prev = %p ", xfs_channel[i].messageq.prev); + uprintf("sleepq.next = %p ", xfs_channel[i].sleepq.next); + uprintf("sleepq.prev = %p ", xfs_channel[i].sleepq.prev); + uprintf("nsequence = %d status = %d\n", + xfs_channel[i].nsequence, + xfs_channel[i].status); + uprintf("}\n"); + } +#endif + return 0; +} diff --git a/sys/xfs/xfs_dev.h b/sys/xfs/xfs_dev.h index 4b95a68959c..095d004976d 100644 --- a/sys/xfs/xfs_dev.h +++ b/sys/xfs/xfs_dev.h @@ -1,4 +1,3 @@ -/* $OpenBSD: xfs_dev.h,v 1.2 1998/08/31 05:13:23 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,34 +36,128 @@ * SUCH DAMAGE. */ -/* $KTH: xfs_dev.h,v 1.4 1998/04/05 18:19:50 art Exp $ */ +/* $Id: xfs_dev.h,v 1.3 1999/04/30 01:59:00 art Exp $ */ -#ifndef _XFS_XFS_DEV_H_ -#define _XFS_XFS_DEV_H_ +#ifndef _xfs_dev_h +#define _xfs_dev_h -int xfs_devopen __P((dev_t dev, int flags, int devtype, struct proc * p)); +/* + * Queues of xfs_links hold outbound messages and processes sleeping + * for replies. The last field is used to return error to sleepers and + * to keep record of memory to be deallocated when messages have been + * delivered or dropped. + */ + +struct xfs_link { + struct xfs_link *prev, *next; + struct xfs_message_header *message; + u_int error_or_size; /* error on sleepq and size on + * messageq */ +}; + +struct xfs_channel { + struct xfs_link messageq; /* Messages not yet read */ + struct xfs_link sleepq; /* Waiting for reply message */ + u_int nsequence; +#ifdef __osf__ + sel_queue_t sel_q; +#else + struct selinfo selinfo; +#endif + struct xfs_message_header *message_buffer; + int status; +#define CHANNEL_OPENED 0x1 +#define CHANNEL_WAITING 0x2 +}; + +extern struct xfs_channel xfs_channel[NXFS]; + +/* + * These are variant dependent + */ + +int xfs_func_is_devopen(void*); +void xfs_select_wakeup(struct xfs_channel *); + +int xfs_install_device(void); +int xfs_uninstall_device(void); -int xfs_install_device __P((void)); -int xfs_uninstall_device __P((void)); +int xfs_install_filesys(void); +int xfs_may_uninstall_filesys(void); +int xfs_uninstall_filesys(void); -int xfs_install_filesys __P((void)); -int xfs_uninstall_filesys __P((void)); +int xfs_stat_filesys(void); +int xfs_stat_device(void); + +/* + * And these should be generic + */ -int xfs_stat_filesys __P((void)); -int xfs_stat_device __P((void)); +void +xfs_initq(struct xfs_link *q); -int xfs_message_send __P((int fd, struct xfs_message_header *message, - u_int size)); -int xfs_message_rpc __P((int fd, struct xfs_message_header *message, - u_int size)); -int xfs_message_receive __P((int fd,struct xfs_message_header *message, - u_int size,struct proc *p)); -int xfs_message_wakeup __P((int fd, struct xfs_message_wakeup *message, - u_int size, struct proc *p)); -int xfs_message_wakeup_data __P((int fd, - struct xfs_message_wakeup_data *message, - u_int size, struct proc *p)); -#define USE_SELECT +int +xfs_emptyq(struct xfs_link *q); +int +xfs_onq(struct xfs_link *link); + +void +xfs_appendq(struct xfs_link *q, struct xfs_link *p); + +void +xfs_outq(struct xfs_link *p); + +int +xfs_devopen_common(dev_t dev); + +#ifndef __osf__ /* XXX - we should do the same for osf */ +int xfs_devopen(dev_t dev, int flag, int devtype, struct proc *proc); +int xfs_devclose(dev_t dev, int flag, int devtype, struct proc *proc); +int xfs_devioctl(dev_t dev, +#if defined(__NetBSD__) || defined(__OpenBSD__) + u_long cmd, +#else /* if defined(__FreeBSD__) */ + int cmd, #endif + caddr_t data, int flags, struct proc *p); +int xfs_devselect(dev_t dev, int which, struct proc *p); +#endif /* ! __osf__ */ + +int +xfs_devclose_common(dev_t dev, struct proc *p); + +int +xfs_devread(dev_t dev, struct uio * uiop, int ioflag); + +int +xfs_devwrite(dev_t dev, struct uio *uiop, int ioflag); + +int +xfs_message_send(int fd, struct xfs_message_header * message, u_int size); + +int +xfs_message_rpc(int fd, struct xfs_message_header * message, u_int size); + +int +xfs_message_receive(int fd, + struct xfs_message_header *message, + u_int size, + struct proc *p); + +int +xfs_message_wakeup(int fd, + struct xfs_message_wakeup *message, + u_int size, + struct proc *p); + +int +xfs_message_wakeup_data(int fd, + struct xfs_message_wakeup_data * message, + u_int size, + struct proc *p); + +int +xfs_uprintf_device(void); +#endif /* _xfs_dev_h */ diff --git a/sys/xfs/xfs_fs.h b/sys/xfs/xfs_fs.h index 007c32e706f..51f9bb4dbcd 100644 --- a/sys/xfs/xfs_fs.h +++ b/sys/xfs/xfs_fs.h @@ -1,4 +1,3 @@ -/* $OpenBSD: xfs_fs.h,v 1.2 1998/08/31 05:13:26 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,30 +36,36 @@ * SUCH DAMAGE. */ -/* $KTH: xfs_fs.h,v 1.8 1998/04/04 01:17:26 art Exp $ */ +/* $Id: xfs_fs.h,v 1.3 1999/04/30 01:59:00 art Exp $ */ -#ifndef _XFS_XFS_H_ -#define _XFS_XFS_H_ +#ifndef _xfs_h +#define _xfs_h #include <sys/types.h> +#include <xfs/xfs_common.h> #include <xfs/xfs_node.h> #include <xfs/xfs_attr.h> -#include <xfs/nxfs.h> + +#define NXFS 2 /* maximal number of filesystems on a single device */ /* * Filesystem struct. */ struct xfs { - u_int status; /* Inited, opened or mounted */ + u_int status; /* Inited, opened or mounted */ #define XFS_MOUNTED 0x1 - struct mount *mp; - struct xfs_node *root; - u_int nnodes; - int fd; + struct mount *mp; + struct xfs_node *root; + u_int nnodes; + int fd; }; +#ifdef __osf__ +#define VFS_TO_XFS(v) ((struct xfs *) ((v)->m_data)) +#else #define VFS_TO_XFS(v) ((struct xfs *) ((v)->mnt_data)) +#endif #define XFS_TO_VFS(x) ((x)->mp) #define XFS_FROM_VNODE(vp) VFS_TO_XFS((vp)->v_mount) @@ -70,20 +75,31 @@ extern struct xfs xfs[]; extern struct vnodeops xfs_vnodeops; -struct xfs_node *xfs_node_find __P((struct xfs *, struct xfs_handle *)); -int new_xfs_node __P((struct xfs *, struct xfs_msg_node *, struct xfs_node **, - struct proc *)); -void free_xfs_node __P((struct xfs_node *)); -int free_all_xfs_nodes __P((struct xfs *, int)); +struct xfs_node *xfs_node_find(struct xfs *, struct xfs_handle *); +int new_xfs_node(struct xfs *, struct xfs_msg_node *, struct xfs_node **, + struct proc *); +void free_xfs_node(struct xfs_node *); +int free_all_xfs_nodes(struct xfs *, int, int); -int xfs_dnlc_enter __P((struct vnode *, char *, struct vnode *)); -void xfs_dnlc_purge __P((struct mount *)); -int xfs_dnlc_lookup __P((struct vnode *, struct componentname *, - struct vnode **)); +int xfs_dnlc_enter(struct vnode *, xfs_componentname *, struct vnode *); +int xfs_dnlc_enter_name(struct vnode *, const char *, struct vnode *); +void xfs_dnlc_purge_mp(struct mount *); +void xfs_dnlc_purge(struct vnode *); +int xfs_dnlc_lookup(struct vnode *, xfs_componentname *, struct vnode **); +int xfs_dnlc_lookup_name(struct vnode *, const char *, struct vnode **); -void vattr2xfs_attr __P((const struct vattr * va, struct xfs_attr *xa)); -void xfs_attr2vattr __P((const struct xfs_attr *xa, struct vattr * va)); +void +xfs_cnp_init (xfs_componentname *ndp, + const char *name, + struct vnode *vp, + struct vnode *dvp, + struct proc *proc, + struct ucred *cred, + int nameiop); -int xfs_has_pag __P((const struct xfs_node *xn, pag_t pag)); +void vattr2xfs_attr(const struct vattr *, struct xfs_attr *); +void xfs_attr2vattr(const struct xfs_attr *, struct vattr *); -#endif +int xfs_has_pag(const struct xfs_node *, pag_t); + +#endif /* _xfs_h */ diff --git a/sys/xfs/xfs_global.h b/sys/xfs/xfs_global.h new file mode 100644 index 00000000000..b23c1d20f08 --- /dev/null +++ b/sys/xfs/xfs_global.h @@ -0,0 +1,9 @@ +#ifndef __XFS_GLOBAL_H +#define __XFS_GLOBAL_H + +#ifndef RCSID +#define RCSID(msg) \ +static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } +#endif /* RCSID */ + +#endif /* __XFS_GLOBAL_H */ diff --git a/sys/xfs/xfs_locl.h b/sys/xfs/xfs_locl.h new file mode 100644 index 00000000000..c87c4c92b9c --- /dev/null +++ b/sys/xfs/xfs_locl.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: xfs_locl.h,v 1.1 1999/04/30 01:59:00 art Exp $ */ + +#if 1 /* XXX - ugly hack */ +#include <xfs/xfs_config.h> +#endif + +#ifndef RCSID +#define RCSID(x) +#endif + +#ifdef __osf__ + +#ifdef __GNUC__ +#define asm __foo_asm +#endif +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/uio.h> +#include <machine/cpu.h> +#include <sys/conf.h> +#include <sys/sysconfig.h> +#include <sys/file.h> +#include <sys/malloc.h> +#include <sys/poll.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> +#include <sys/vfs_proto.h> +#include <io/common/devdriver.h> +#include <vm/vm_page.h> +#include <vm/vm_vppage.h> +#include <vm/vm_ubc.h> + +typedef short int16_t; +typedef int int32_t; +typedef unsigned int u_int32_t; + +#define VT_AFS VT_ADDON +#define MOUNT_XFS MOUNT_PC + +typedef struct nameidata xfs_componentname; + +/* XXX this is gross, but makes the code considerably more readable */ +#if 0 +#define componentname nameidata +#endif + +#define cn_nameptr ni_ptr +#define cn_namelen ni_namelen +#define cn_hash ni_hash +#define cn_cred ni_cred +#define cn_nameiop ni_nameiop +#define cn_flags ni_flags + +#define mnt_stat m_stat +#define mnt_flag m_flag + +#define NDINIT(ndp, op, flags, segflg, namep, p) \ + (ndp)->ni_nameiop = (op) | (flags); \ + (ndp)->ni_segflg = segflg; \ + (ndp)->ni_dirp = namep; + +#define LOCKLEAF 0 + +#define FFLAGS(mode) ((mode) - FOPEN) + +/* 4.4BSD vput does VOP_UNLOCK + vrele, but it seems as if we only + should do a vrele here */ +#define vput(VP) vrele(VP) + +#define xfs_uio_to_proc(uiop) (u.u_procp) +#define xfs_cnp_to_proc(cnp) (u.u_procp) +#define xfs_proc_to_cred(p) ((p)->p_rcred) + +#define xfs_curproc() (u.u_procp) + +#else /* __osf__ */ + +typedef struct componentname xfs_componentname; + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/filedesc.h> +#include <sys/kernel.h> +#ifdef HAVE_SYS_MODULE_H +#include <sys/module.h> +#endif +#include <sys/systm.h> +#include <sys/fcntl.h> +#ifdef HAVE_SYS_SYSPROTO_H +#include <sys/sysproto.h> +#endif +#include <sys/conf.h> +#include <sys/mount.h> +#include <sys/exec.h> +#ifdef HAVE_SYS_SYSENT_H +#include <sys/sysent.h> +#endif +#include <sys/lkm.h> +#include <sys/errno.h> +#include <sys/file.h> +#include <sys/namei.h> +#include <sys/dirent.h> +#include <sys/ucred.h> +#include <sys/select.h> +#include <sys/uio.h> +#ifdef HAVE_SYS_POLL_H +#include <sys/poll.h> +#endif +#include <sys/syscall.h> +#include <sys/queue.h> +#include <sys/malloc.h> +#ifdef HAVE_MISCFS_GENFS_GENFS_H +#include <miscfs/genfs/genfs.h> +#endif +#ifdef HAVE_VM_VM_H +#include <vm/vm.h> +#endif +#ifdef HAVE_VM_VM_EXTERN_H +#include <vm/vm_extern.h> +#endif +#ifdef HAVE_VM_VM_ZONE_H +#include <vm/vm_zone.h> +#endif + +#define xfs_uio_to_proc(uiop) ((uiop)->uio_procp) +#define xfs_cnp_to_proc(cnp) ((cnp)->cn_proc) +#define xfs_proc_to_cred(p) ((p)->p_ucred) + +#define xfs_curproc() (curproc) + +#endif /* __osf__ */ + +/* + * The VOP table + * + * What VOPs do we have today ? + */ + +#include "xfs/xfs_vopdefs.h" diff --git a/sys/xfs/xfs_message.c b/sys/xfs/xfs_message.c index 2a3086611d9..beb951376b3 100644 --- a/sys/xfs/xfs_message.c +++ b/sys/xfs/xfs_message.c @@ -1,4 +1,3 @@ -/* $OpenBSD: xfs_message.c,v 1.3 1998/09/06 01:48:58 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,181 +36,234 @@ * SUCH DAMAGE. */ -#include <sys/types.h> -#include <sys/uio.h> -#include <sys/namei.h> -#include <sys/systm.h> -#include <sys/time.h> -#include <sys/vnode.h> - -#include <xfs/xfs_common.h> +#include <xfs/xfs_locl.h> #include <xfs/xfs_deb.h> #include <xfs/xfs_fs.h> #include <xfs/xfs_message.h> #include <xfs/xfs_msg_locl.h> +#include <xfs/xfs_syscalls.h> +#include <xfs/xfs_vfsops.h> +#include <xfs/xfs_vnodeops.h> -RCSID("$KTH: xfs_message.c,v 1.16 1998/07/19 00:19:54 art Exp $"); +RCSID("$Id: xfs_message.c,v 1.4 1999/04/30 01:59:00 art Exp $"); int xfs_message_installroot(int fd, - struct xfs_message_installroot *message, + struct xfs_message_installroot * message, u_int size, struct proc *p) { - int error = 0; + int error = 0; - XFSDEB(XDEBMSG, ("xfs_message_installroot\n")); + XFSDEB(XDEBMSG, ("xfs_message_installroot\n")); - if (xfs[fd].root != NULL) { - printf("XFS WARNING! xfs_message_installroot: again!\n"); - error = EBUSY; - } else { - error = new_xfs_node(&xfs[fd], &message->node, &xfs[fd].root, - p); - if (error) - return error; - xfs[fd].root->vn->v_flag |= VROOT; - } - - return error; + if (xfs[fd].root != NULL) { + printf("XFS PANIC WARNING! xfs_message_installroot: called again!\n"); + error = EBUSY; + } else { + error = new_xfs_node(&xfs[fd], &message->node, &xfs[fd].root, p); + if (error) + return error; + xfs[fd].root->vn->v_flag |= VROOT; + } + return error; } int xfs_message_installnode(int fd, - struct xfs_message_installnode *message, + struct xfs_message_installnode * message, u_int size, struct proc *p) { - int error = 0; - struct xfs_node *n, *dp; - - XFSDEB(XDEBMSG, ("xfs_message_installnode\n")); - - dp = xfs_node_find(&xfs[fd], &message->parent_handle); - if (dp) { - error = new_xfs_node(&xfs[fd], &message->node, &n, p); - if (error) - return error; - cache_purge (XNODE_TO_VNODE(dp)); - xfs_dnlc_enter(XNODE_TO_VNODE(dp), message->name, - XNODE_TO_VNODE(n)); - vrele(XNODE_TO_VNODE(n)); - } else { - printf("XFS WARNING! xfs_message_installnode: no parent\n"); - error = ENOENT; + int error = 0; + struct xfs_node *n, *dp; + + XFSDEB(XDEBMSG, ("xfs_message_installnode\n")); + + dp = xfs_node_find(&xfs[fd], &message->parent_handle); + if (dp) { + struct vnode *t_vnode = XNODE_TO_VNODE(dp); + + xfs_do_vget (t_vnode, LK_INTERLOCK|LK_SHARED, p); + + error = new_xfs_node(&xfs[fd], &message->node, &n, p); + if (error) { + vrele (t_vnode); + return error; } - XFSDEB(XDEBMSG, ("return: xfs_message_installnode: %d\n", error)); - return error; + xfs_dnlc_enter_name(t_vnode, + message->name, + XNODE_TO_VNODE(n)); + vrele(XNODE_TO_VNODE(n)); + vput (t_vnode); + } else { + printf("XFS PANIC WARNING! xfs_message_installnode: no parent\n"); + error = ENOENT; + } + XFSDEB(XDEBMSG, ("return: xfs_message_installnode: %d\n", error)); + + return error; } int xfs_message_installattr(int fd, - struct xfs_message_installattr *message, + struct xfs_message_installattr * message, u_int size, struct proc *p) { - int error = 0; - struct xfs_node *t; - - t = xfs_node_find(&xfs[fd], &message->node.handle); - if (t != 0) { - t->tokens = message->node.tokens; - xfs_attr2vattr(&message->node.attr, &t->attr); - bcopy(message->node.id, t->id, sizeof(t->id)); - bcopy(message->node.rights, t->rights, sizeof(t->rights)); - t->anonrights = message->node.anonrights; - } else { - printf("XFS WARNING! xfs_message_installattr: no node!\n"); - error = ENOENT; - } + int error = 0; + struct xfs_node *t; + + t = xfs_node_find(&xfs[fd], &message->node.handle); + if (t != 0) { + t->tokens = message->node.tokens; + xfs_attr2vattr(&message->node.attr, &t->attr); +#ifdef HAVE_KERNEL_VNODE_PAGER_SETSIZE + vnode_pager_setsize(XNODE_TO_VNODE(t), t->attr.va_size); +#endif + bcopy(message->node.id, t->id, sizeof(t->id)); + bcopy(message->node.rights, t->rights, sizeof(t->rights)); + t->anonrights = message->node.anonrights; + } else { + printf("XFS PANIC WARNING! xfs_message_installattr: no node!\n"); + error = ENOENT; + } - return error; + return error; } int xfs_message_installdata(int fd, - struct xfs_message_installdata *message, + struct xfs_message_installdata * message, u_int size, struct proc *p) { - struct xfs_node *t; - int error = 0; - - XFSDEB(XDEBMSG, ("xfs_message_installdata\n")); - - t = xfs_node_find(&xfs[fd], &message->node.handle); - if (t != NULL) { - struct nameidata nd; - char tmp[CACHEHANDLESIZE + 1]; - struct vnode *vp; - - bcopy((char *) &message->cache_handle.data, tmp, sizeof(tmp)); - tmp[CACHEHANDLESIZE] = '\0'; - - XFSDEB(XDEBMSG, ("cache_handle = '%s'\n", tmp)); - - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, tmp, p); - error = namei(&nd); - vp = nd.ni_vp; - if (error == 0) { - if (DATA_FROM_XNODE(t)) - vrele(DATA_FROM_XNODE(t)); - VOP_UNLOCK(vp, 0, p); - DATA_FROM_XNODE(t) = vp; - XFSDEB(XDEBMSG, - ("xfs_message_installdata: t= %p tokens= %x\n", - t, message->node.tokens)); - - t->tokens = message->node.tokens; - xfs_attr2vattr(&message->node.attr, &t->attr); - if (XNODE_TO_VNODE(t)->v_type == VDIR) - cache_purge (XNODE_TO_VNODE(t)); - - bcopy(message->node.id, t->id, sizeof(t->id)); - bcopy(message->node.rights, t->rights, - sizeof(t->rights)); - t->anonrights = message->node.anonrights; - } else { - printf("XFS WARNING! xfs_message_installdata fail!\n"); - printf("Reason: lookup failed on cache file '%s', " - "error = %d\n", tmp, error); - } + struct xfs_node *t; + int error = 0; + + XFSDEB(XDEBMSG, ("xfs_message_installdata\n")); + + t = xfs_node_find(&xfs[fd], &message->node.handle); + + if (t != NULL) { + struct xfs_fh_args *fh_args = (struct xfs_fh_args *)&message->cache_handle; + struct vnode *vp; + struct vnode *t_vnode = XNODE_TO_VNODE(t); + + XFSDEB(XDEBMSG, ("cache_name = '%s'\n", message->cache_name)); + XFSDEB(XDEBMSG, ("fileno = %ld, gen = %ld\n", + SCARG(fh_args, fileid), + SCARG(fh_args, gen))); + + xfs_do_vget (t_vnode, LK_INTERLOCK|LK_SHARED, p); + + error = xfs_fhlookup (p, + SCARG(fh_args,fsid), + SCARG(fh_args,fileid), + SCARG(fh_args,gen), + &vp); + + if (error != 0) { +#ifdef __osf__ + struct nameidata *ndp = &u.u_nd; +#else + struct nameidata nd; + struct nameidata *ndp = &nd; +#endif + + XFSDEB(XDEBMSG, + ("xfs_message_installdata: fhlookup failed: %d, " + "opening by name\n", error)); + + NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, + message->cache_name, p); + error = namei(ndp); + vp = ndp->ni_vp; + } + + if (error == 0) { + xfs_vfs_unlock(vp, p); + if (DATA_FROM_XNODE(t)) + vrele(DATA_FROM_XNODE(t)); + DATA_FROM_XNODE(t) = vp; + + XFSDEB(XDEBMSG, ("xfs_message_installdata: t = %p;" + " tokens = %x\n", + t, message->node.tokens)); + + t->tokens = message->node.tokens; + xfs_attr2vattr(&message->node.attr, &t->attr); +#ifdef HAVE_KERNEL_VNODE_PAGER_SETSIZE + vnode_pager_setsize(XNODE_TO_VNODE(t), t->attr.va_size); +#endif + if (XNODE_TO_VNODE(t)->v_type == VDIR + && (message->flag & XFS_INVALID_DNLC)) + cache_purge (XNODE_TO_VNODE(t)); + bcopy(message->node.id, t->id, sizeof(t->id)); + bcopy(message->node.rights, t->rights, sizeof(t->rights)); + t->anonrights = message->node.anonrights; } else { - printf("XFS WARNING! xfs_message_installdata failed\n"); - printf("Reason: No node to install the data into!\n"); - error = ENOENT; + printf("XFS PANIC WARNING! xfs_message_installdata failed!\n"); + printf("Reason: lookup failed on cache file '%s', error = %d\n", + message->cache_name, error); } + vput (t_vnode); + } else { + printf("XFS PANIC WARNING! xfs_message_installdata failed\n"); + printf("Reason: No node to install the data into!\n"); + error = ENOENT; + } - return error; + return error; } int xfs_message_invalidnode(int fd, - struct xfs_message_invalidnode *message, + struct xfs_message_invalidnode * message, u_int size, struct proc *p) { - int error = 0; - struct xfs_node *t; - - XFSDEB(XDEBMSG, ("xfs_message_invalidnode\n")); - - t = xfs_node_find(&xfs[fd], &message->handle); - if (t != 0) { - /* XXX Really need to put back dirty data first. */ - if (DATA_FROM_XNODE(t)) { - vrele(DATA_FROM_XNODE(t)); - DATA_FROM_XNODE(t) = (struct vnode *) 0; - } - XFS_TOKEN_CLEAR(t, ~0, - XFS_OPEN_MASK | XFS_ATTR_MASK | - XFS_DATA_MASK | XFS_LOCK_MASK); - cache_purge(XNODE_TO_VNODE(t)); - } else { - printf("XFS WARNING! xfs_message_invalidnode: no node!\n"); - error = ENOENT; + int error = 0; + struct xfs_node *t; + + XFSDEB(XDEBMSG, ("xfs_message_invalidnode\n")); + + t = xfs_node_find(&xfs[fd], &message->handle); + if (t != 0) { + /* XXX Really need to put back dirty data first. */ + if (DATA_FROM_XNODE(t)) { + vrele(DATA_FROM_XNODE(t)); + DATA_FROM_XNODE(t) = (struct vnode *) 0; } + XFS_TOKEN_CLEAR(t, ~0, + XFS_OPEN_MASK | XFS_ATTR_MASK | + XFS_DATA_MASK | XFS_LOCK_MASK); + cache_purge(XNODE_TO_VNODE(t)); + } else { + printf("XFS PANIC WARNING! xfs_message_invalidnode: no node!\n"); + error = ENOENT; + } + + return error; +} + +int +xfs_message_updatefid(int fd, + struct xfs_message_updatefid * message, + u_int size, + struct proc *p) +{ + int error = 0; + struct xfs_node *t; - return error; + XFSDEB(XDEBMSG, ("xfs_message_updatefid\n")); + t = xfs_node_find (&xfs[fd], &message->old_handle); + if (t != NULL) { + t->handle = message->new_handle; + } else { + printf ("XFS PANIC WARNING! xfs_message_updatefid: no node!\n"); + error = ENOENT; + } + return error; } diff --git a/sys/xfs/xfs_message.h b/sys/xfs/xfs_message.h index 1e30b1f217c..d3741a1d3bd 100644 --- a/sys/xfs/xfs_message.h +++ b/sys/xfs/xfs_message.h @@ -1,6 +1,5 @@ -/* $OpenBSD: xfs_message.h,v 1.1 1998/08/31 05:13:27 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,16 +36,22 @@ * SUCH DAMAGE. */ -/* $KTH: xfs_message.h,v 1.21 1998/06/27 11:05:24 assar Exp $ */ +/* $Id: xfs_message.h,v 1.2 1999/04/30 01:59:00 art Exp $ */ -#ifndef _SYS_XFS_MESSAGE_H_ -#define _SYS_XFS_MESSAGE_H_ +#ifndef _xmsg_h +#define _xmsg_h +#if !defined(__LINUX__) && !defined(HAVE_GLIBC) #include <sys/types.h> #include <sys/param.h> +#else +#include <linux/types.h> +#include <linux/param.h> +#endif #include <xfs/xfs_attr.h> +/* Temporary hack? */ #define MAX_XMSG_SIZE (1024*64) typedef u_int32_t pag_t; @@ -54,29 +59,36 @@ typedef u_int32_t pag_t; /* * The xfs_cred, if pag == 0, use uid */ -struct xfs_cred { - __kernel_uid_t uid; - pag_t pag; -}; +typedef struct xfs_cred { + __kernel_uid_t uid; + pag_t pag; +} xfs_cred; + +typedef unsigned long xfs_locktype_t; +typedef unsigned long xfs_lockid_t; -typedef struct xfs_cred xfs_cred; -#define MAXHANDLE (4*4) -#define MAXRIGHTS 8 +#define MAXHANDLE (4*4) +#define MAXRIGHTS 8 + +#define XFS_ANONYMOUSID 32766 -#define XFS_ANONYMOUSID 32766 typedef struct xfs_handle { - u_int a, b, c, d; + u_int a, b, c, d; } xfs_handle; + #define xfs_handle_eq(p, q) \ ((p)->a == (q)->a && (p)->b == (q)->b && (p)->c == (q)->c && (p)->d == (q)->d) +/* + * This should be the maximum size of any `file handle' + */ -#define CACHEHANDLESIZE 4 -struct xfs_cache_handle { - u_char data[CACHEHANDLESIZE]; -}; -typedef struct xfs_cache_handle xfs_cache_handle; +#define CACHEHANDLESIZE 80 + +typedef struct xfs_cache_handle { + u_char data[CACHEHANDLESIZE]; +} xfs_cache_handle; /* * Tokens that apply to nodes, open modes and attributes. Shared @@ -99,11 +111,11 @@ typedef struct xfs_cache_handle xfs_cache_handle; #define XFS_DATA_R 0x0040 /* Data valid */ #define XFS_DATA_W 0x0080 /* Data valid and modifiable */ #define XFS_LOCK_MASK 0x0300 -#define XFS_LOCK_R 0x0100 /* Data Shared locks? */ -#define XFS_LOCK_W 0x0200 /* Data Exclusive locks? */ +#define XFS_LOCK_R 0x0100 /* Data Shared locks */ +#define XFS_LOCK_W 0x0200 /* Data Exclusive locks */ -#define XFS_ATTR_VALID XFS_ATTR_R -#define XFS_DATA_VALID XFS_DATA_W +#define XFS_ATTR_VALID XFS_ATTR_R +#define XFS_DATA_VALID XFS_DATA_W /* xfs_node.flags */ #define XFS_DATA_DIRTY 0x0001 @@ -120,21 +132,21 @@ typedef struct xfs_cache_handle xfs_cache_handle; #define XFS_RIGHT_X 0x04 /* may execute? */ struct xfs_msg_node { - xfs_handle handle; - u_int tokens; - struct xfs_attr attr; - pag_t id[MAXRIGHTS]; - u_char rights[MAXRIGHTS]; - u_char anonrights; + xfs_handle handle; + u_int tokens; + struct xfs_attr attr; + pag_t id[MAXRIGHTS]; + u_char rights[MAXRIGHTS]; + u_char anonrights; }; /* * Messages passed through the xfs_dev. */ struct xfs_message_header { - u_int size; - u_int opcode; - u_int sequence_num; /* Private */ + u_int size; + u_int opcode; + u_int sequence_num; /* Private */ }; /* @@ -148,6 +160,12 @@ enum { XFS_READ = 1, XFS_WRITE = 2, XFS_NONBLOCK = 4, XFS_APPEND = 8}; enum { XFS_NOREFS = 1, XFS_DELETE = 2 }; /* + * Flags for installdata + */ + +enum { XFS_INVALID_DNLC = 1 }; + +/* * Defined message types and their opcodes. */ #define XFS_MSG_VERSION 0 @@ -188,195 +206,218 @@ enum { XFS_NOREFS = 1, XFS_DELETE = 2 }; #define XFS_MSG_PIOCTL 22 #define XFS_MSG_WAKEUP_DATA 23 -#define XFS_MSG_COUNT 24 +#define XFS_MSG_UPDATEFID 24 + +#define XFS_MSG_ADVLOCK 25 + +#define XFS_MSG_COUNT 26 /* XFS_MESSAGE_WAKEUP */ struct xfs_message_wakeup { - struct xfs_message_header header; - int sleepers_sequence_num; /* Where to send wakeup */ - int error; /* Return value */ + struct xfs_message_header header; + int sleepers_sequence_num; /* Where to send wakeup */ + int error; /* Return value */ }; /* XFS_MESSAGE_GETROOT */ struct xfs_message_getroot { - struct xfs_message_header header; - struct xfs_cred cred; + struct xfs_message_header header; + struct xfs_cred cred; }; /* XFS_MESSAGE_INSTALLROOT */ struct xfs_message_installroot { - struct xfs_message_header header; - struct xfs_msg_node node; + struct xfs_message_header header; + struct xfs_msg_node node; }; /* XFS_MESSAGE_GETNODE */ struct xfs_message_getnode { - struct xfs_message_header header; - struct xfs_cred cred; - xfs_handle parent_handle; - char name[256]; /* XXX */ + struct xfs_message_header header; + struct xfs_cred cred; + xfs_handle parent_handle; + char name[256]; /* XXX */ }; /* XFS_MESSAGE_INSTALLNODE */ struct xfs_message_installnode { - struct xfs_message_header header; - xfs_handle parent_handle; - char name[256]; /* XXX */ - struct xfs_msg_node node; + struct xfs_message_header header; + xfs_handle parent_handle; + char name[256]; /* XXX */ + struct xfs_msg_node node; }; /* XFS_MESSAGE_GETATTR */ struct xfs_message_getattr { - struct xfs_message_header header; - struct xfs_cred cred; - xfs_handle handle; + struct xfs_message_header header; + struct xfs_cred cred; + xfs_handle handle; }; /* XFS_MESSAGE_INSTALLATTR */ struct xfs_message_installattr { - struct xfs_message_header header; - struct xfs_msg_node node; + struct xfs_message_header header; + struct xfs_msg_node node; }; /* XFS_MESSAGE_GETDATA */ struct xfs_message_getdata { - struct xfs_message_header header; - struct xfs_cred cred; - xfs_handle handle; - u_int tokens; + struct xfs_message_header header; + struct xfs_cred cred; + xfs_handle handle; + u_int tokens; }; /* XFS_MESSAGE_INSTALLDATA */ struct xfs_message_installdata { - struct xfs_message_header header; - struct xfs_msg_node node; - struct xfs_cache_handle cache_handle; + struct xfs_message_header header; + struct xfs_msg_node node; + char cache_name[256]; /* XXX */ + struct xfs_cache_handle cache_handle; + u_int flag; }; /* XFS_MSG_INACTIVENODE */ struct xfs_message_inactivenode { - struct xfs_message_header header; - xfs_handle handle; - u_int flag; + struct xfs_message_header header; + xfs_handle handle; + u_int flag; }; /* XFS_MSG_INVALIDNODE */ struct xfs_message_invalidnode { - struct xfs_message_header header; - xfs_handle handle; + struct xfs_message_header header; + xfs_handle handle; }; /* XFS_MSG_OPEN */ struct xfs_message_open { - struct xfs_message_header header; - struct xfs_cred cred; - xfs_handle handle; - u_int tokens; + struct xfs_message_header header; + struct xfs_cred cred; + xfs_handle handle; + u_int tokens; }; /* XFS_MSG_PUTDATA */ struct xfs_message_putdata { - struct xfs_message_header header; - xfs_handle handle; - struct xfs_attr attr; - struct xfs_cred cred; - u_int flag; + struct xfs_message_header header; + xfs_handle handle; + struct xfs_attr attr; /* XXX ??? */ + struct xfs_cred cred; + u_int flag; }; /* XFS_MSG_PUTATTR */ struct xfs_message_putattr { - struct xfs_message_header header; - xfs_handle handle; - struct xfs_attr attr; - struct xfs_cred cred; + struct xfs_message_header header; + xfs_handle handle; + struct xfs_attr attr; + struct xfs_cred cred; }; /* XFS_MSG_CREATE */ struct xfs_message_create { - struct xfs_message_header header; - xfs_handle parent_handle; - char name[256]; /* XXX */ - struct xfs_attr attr; -#if 0 /* XXX ??? */ - enum vcexcl exclusive; -#endif - int mode; - struct xfs_cred cred; + struct xfs_message_header header; + xfs_handle parent_handle; + char name[256]; /* XXX */ + struct xfs_attr attr; + int mode; + struct xfs_cred cred; }; /* XFS_MSG_MKDIR */ struct xfs_message_mkdir { - struct xfs_message_header header; - xfs_handle parent_handle; - char name[256]; /* XXX */ - struct xfs_attr attr; - struct xfs_cred cred; + struct xfs_message_header header; + xfs_handle parent_handle; + char name[256]; /* XXX */ + struct xfs_attr attr; + struct xfs_cred cred; }; /* XFS_MSG_LINK */ struct xfs_message_link { - struct xfs_message_header header; - xfs_handle parent_handle; - char name[256]; /* XXX */ - xfs_handle from_handle; - struct xfs_cred cred; + struct xfs_message_header header; + xfs_handle parent_handle; + char name[256]; /* XXX */ + xfs_handle from_handle; + struct xfs_cred cred; }; /* XFS_MSG_SYMLINK */ struct xfs_message_symlink { - struct xfs_message_header header; - xfs_handle parent_handle; - char name[256]; /* XXX */ - char contents[2048]; /* XXX */ - struct xfs_attr attr; - struct xfs_cred cred; + struct xfs_message_header header; + xfs_handle parent_handle; + char name[256]; /* XXX */ + char contents[2048]; /* XXX */ + struct xfs_attr attr; + struct xfs_cred cred; }; /* XFS_MSG_REMOVE */ struct xfs_message_remove { - struct xfs_message_header header; - xfs_handle parent_handle; - char name[256]; /* XXX */ - struct xfs_cred cred; + struct xfs_message_header header; + xfs_handle parent_handle; + char name[256]; /* XXX */ + struct xfs_cred cred; }; /* XFS_MSG_RMDIR */ struct xfs_message_rmdir { - struct xfs_message_header header; - xfs_handle parent_handle; - char name[256]; /* XXX */ - struct xfs_cred cred; + struct xfs_message_header header; + xfs_handle parent_handle; + char name[256]; /* XXX */ + struct xfs_cred cred; }; /* XFS_MSG_RENAME */ struct xfs_message_rename { - struct xfs_message_header header; - xfs_handle old_parent_handle; - char old_name[256]; /* XXX */ - xfs_handle new_parent_handle; - char new_name[256]; /* XXX */ - struct xfs_cred cred; + struct xfs_message_header header; + xfs_handle old_parent_handle; + char old_name[256]; /* XXX */ + xfs_handle new_parent_handle; + char new_name[256]; /* XXX */ + struct xfs_cred cred; }; /* XFS_MSG_PIOCTL */ struct xfs_message_pioctl { - struct xfs_message_header header; - int opcode ; - xfs_cred cred; - int insize; - int outsize; - char msg[2048]; /* XXX */ - xfs_handle handle; + struct xfs_message_header header; + int opcode ; + xfs_cred cred; + int insize; + int outsize; + char msg[2048] ; /* XXX */ + xfs_handle handle; }; /* XFS_MESSAGE_WAKEUP_DATA */ struct xfs_message_wakeup_data { - struct xfs_message_header header; - int sleepers_sequence_num; /* Where to send wakeup */ - int error; /* Return value */ - int len; - char msg[2048]; /* XXX */ + struct xfs_message_header header; + int sleepers_sequence_num; /* Where to send wakeup */ + int error; /* Return value */ + int len; + char msg[2048] ; /* XXX */ +}; + +/* XFS_MESSAGE_UPDATEFID */ +struct xfs_message_updatefid { + struct xfs_message_header header; + xfs_handle old_handle; + xfs_handle new_handle; +}; + +/* XFS_MESSAGE_ADVLOCK */ +struct xfs_message_advlock { + struct xfs_message_header header; + xfs_handle handle; + struct xfs_cred cred; + xfs_locktype_t locktype; +#define XFS_WR_LOCK 1 /* Write lock */ +#define XFS_RD_LOCK 2 /* Read lock */ +#define XFS_UN_LOCK 3 /* Unlock */ +#define XFS_BR_LOCK 4 /* Break lock (inform that we don't want the lock) */ + xfs_lockid_t lockid; }; #endif /* _xmsg_h */ diff --git a/sys/xfs/xfs_msg_locl.h b/sys/xfs/xfs_msg_locl.h index 18fe0613a93..b552e8c148f 100644 --- a/sys/xfs/xfs_msg_locl.h +++ b/sys/xfs/xfs_msg_locl.h @@ -1,4 +1,3 @@ -/* $OpenBSD: xfs_msg_locl.h,v 1.2 1998/08/31 05:13:27 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,25 +36,45 @@ * SUCH DAMAGE. */ -/* $KTH: xfs_msg_locl.h,v 1.1 1998/03/26 02:25:53 assar Exp $ */ - -#ifndef _XFS_XFS_MSG_LOCL_H_ -#define _XFS_XFS_MSG_LOCL_H_ - -int xfs_message_installroot __P((int fd, - struct xfs_message_installroot *message, - u_int size, struct proc *p)); -int xfs_message_installnode __P((int fd, - struct xfs_message_installnode *message, - u_int size,struct proc *p)); -int xfs_message_installattr __P((int fd, - struct xfs_message_installattr *message, - u_int size,struct proc *p)); -int xfs_message_installdata __P((int fd, - struct xfs_message_installdata *message, - u_int size, struct proc *p)); -int xfs_message_invalidnode __P((int fd, - struct xfs_message_invalidnode *message, - u_int size, struct proc *p)); - -#endif +/* $Id: xfs_msg_locl.h,v 1.3 1999/04/30 01:59:00 art Exp $ */ + +#ifndef _xfs_msg_locl_h +#define _xfs_msg_locl_h + +int +xfs_message_installroot(int fd, + struct xfs_message_installroot * message, + u_int size, + struct proc *p); + +int +xfs_message_installnode(int fd, + struct xfs_message_installnode * message, + u_int size, + struct proc *p); + +int +xfs_message_installattr(int fd, + struct xfs_message_installattr * message, + u_int size, + struct proc *p); + +int +xfs_message_installdata(int fd, + struct xfs_message_installdata * message, + u_int size, + struct proc *p); + +int +xfs_message_invalidnode(int fd, + struct xfs_message_invalidnode * message, + u_int size, + struct proc *p); + +int +xfs_message_updatefid(int fd, + struct xfs_message_updatefid * message, + u_int size, + struct proc *p); + +#endif /* _xfs_msg_locl_h */ diff --git a/sys/xfs/xfs_node-bsd.c b/sys/xfs/xfs_node-bsd.c new file mode 100644 index 00000000000..71d1b8faae1 --- /dev/null +++ b/sys/xfs/xfs_node-bsd.c @@ -0,0 +1,590 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <xfs/xfs_locl.h> +#include <xfs/xfs_common.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_deb.h> + +RCSID("$Id: xfs_node-bsd.c,v 1.1 1999/04/30 01:59:00 art Exp $"); + +extern vop_t **xfs_vnodeop_p; + +/* + * Allocate a new vnode with handle `handle' in `mp' and return it in + * `vpp'. Return 0 or error. + */ + +int +xfs_getnewvnode(struct mount *mp, struct vnode **vpp, + struct xfs_handle *handle) +{ + struct xfs_node *result; + int error; + + error = getnewvnode(VT_AFS, mp, xfs_vnodeop_p, vpp); + if (error) + return error; + + result = xfs_alloc(sizeof(*result)); + bzero(result, sizeof(*result)); + + (*vpp)->v_data = result; + result->vn = *vpp; + + result->handle = *handle; + result->flags = 0; + result->tokens = 0; + result->vnlocks = 0; + + result->anonrights = 0; + + return 0; +} + +/* + * Create a new xfs_node and make a vget + * + * Also prevents creation of duplicates. This happens + * whenever there are more than one name to a file, + * "." and ".." are common cases. */ + +int +new_xfs_node(struct xfs *xfsp, + struct xfs_msg_node *node, + struct xfs_node **xpp, + struct proc *p) +{ + int do_vget = 0; + struct xfs_node *result; + + XFSDEB(XDEBNODE, ("new_xfs_node %d.%d.%d.%d\n", + node->handle.a, + node->handle.b, + node->handle.c, + node->handle.d)); + again: + /* Does not allow duplicates */ + result = xfs_node_find(xfsp, &node->handle); + + if (result == 0) { + int error; + struct vnode *v; + + error = xfs_getnewvnode(XFS_TO_VFS(xfsp), &v, &node->handle); + if (error) + return error; + + result = VNODE_TO_XNODE(v); + result->anonrights = node->anonrights; + + xfsp->nnodes++; + } else { + /* Node is already cached */ +#ifdef HAVE_LK_INTERLOCK + simple_lock(&(XNODE_TO_VNODE(result)->v_interlock)); +#endif + do_vget = 1; + } + + /* Init other fields */ + xfs_attr2vattr(&node->attr, &result->attr); + result->vn->v_type = result->attr.va_type; + XFS_TOKEN_SET(result, XFS_ATTR_R, XFS_ATTR_MASK); + bcopy(node->id, result->id, sizeof(result->id)); + bcopy(node->rights, result->rights, sizeof(result->rights)); + + /* + * We need to postpone this until here because (on FreeBSD) vget + * tries to install a pager on the vnode and for that it wants to + * retrieve the size with getattr. + */ + + if (do_vget) { + if (xfs_do_vget(XNODE_TO_VNODE(result), LK_INTERLOCK, p)) + goto again; + } + + *xpp = result; + XFSDEB(XDEBNODE, ("return: new_xfs_node\n")); + return 0; +} + +void +free_xfs_node(struct xfs_node *node) +{ + struct xfs *xfsp = XFS_FROM_XNODE(node); + + XFSDEB(XDEBNODE, ("free_xfs_node starting: node = %p\n", node)); + + /* XXX Really need to put back dirty data first. */ + + if (DATA_FROM_XNODE(node)) { + vrele(DATA_FROM_XNODE(node)); + DATA_FROM_XNODE(node) = NULL; + } + xfsp->nnodes--; + XNODE_TO_VNODE(node)->v_data = NULL; + xfs_free(node, sizeof(*node)); + + XFSDEB(XDEBNODE, ("free_xfs_node done\n")); +} + +int +free_all_xfs_nodes(struct xfs *xfsp, int flags, int unmountp) +{ + int error = 0; + struct mount *mp = XFS_TO_VFS(xfsp); + + if (mp == NULL) { + XFSDEB(XDEBNODE, ("free_all_xfs_nodes already freed\n")); + return 0; + } + + XFSDEB(XDEBNODE, ("free_all_xfs_nodes starting\n")); + + xfs_dnlc_purge_mp(mp); + + if (xfsp->root) { + XFSDEB(XDEBNODE, ("free_all_xfs_nodes now removing root\n")); + + vgone(XNODE_TO_VNODE(xfsp->root)); + xfsp->root = 0; + } + + XFSDEB(XDEBNODE, ("free_all_xfs_nodes root removed\n")); + XFSDEB(XDEBNODE, ("free_all_xfs_nodes now killing all remaining nodes\n")); + +#ifdef HAVE_STRUCT_MOUNT_MNT_SYNCER + if (!unmountp) { + XFSDEB(XDEBNODE, ("free_all_xfs_nodes not flushing syncer vnode\n")); + error = vflush(mp, mp->mnt_syncer, flags); + } else +#endif + { + error = vflush(mp, NULL, flags); + } + + if (error) { + XFSDEB(XDEBNODE, ("xfree_all_xfs_nodes: vflush() error == %d\n", + error)); + return error; + } + + XFSDEB(XDEBNODE, ("free_all_xfs_nodes done\n")); + return error; +} + +struct xfs_node * +xfs_node_find(struct xfs *xfsp, xfs_handle *handlep) +{ + struct vnode *t; + struct xfs_node *xn = NULL; + + XFSDEB(XDEBNODE, ("xfs_node_find: xfsp = %p handlep = %p\n", + xfsp, handlep)); + + for(t = XFS_TO_VFS(xfsp)->mnt_vnodelist.lh_first; + t != NULL; + t = t->v_mntvnodes.le_next) { + xn = VNODE_TO_XNODE(t); + if (xn && xfs_handle_eq(&xn->handle, handlep)) + break; + } + + if (t != NULL) + return xn; + else + return NULL; +} + +void +vattr2xfs_attr(const struct vattr *va, struct xfs_attr *xa) +{ + bzero(xa, sizeof(*xa)); + if (va->va_mode != (mode_t)VNOVAL) + XA_SET_MODE(xa, va->va_mode); + if (va->va_nlink != VNOVAL) + XA_SET_NLINK(xa, va->va_nlink); + if (va->va_size != VNOVAL) + XA_SET_SIZE(xa, va->va_size); + if (va->va_uid != VNOVAL) + XA_SET_UID(xa, va->va_uid); + if (va->va_gid != VNOVAL) + XA_SET_GID(xa, va->va_gid); + if (va->va_atime.tv_sec != VNOVAL) + XA_SET_ATIME(xa, va->va_atime.tv_sec); + if (va->va_mtime.tv_sec != VNOVAL) + XA_SET_MTIME(xa, va->va_mtime.tv_sec); + if (va->va_ctime.tv_sec != VNOVAL) + XA_SET_CTIME(xa, va->va_ctime.tv_sec); + if (va->va_fileid != VNOVAL) + XA_SET_FILEID(xa, va->va_fileid); + switch (va->va_type) { + case VNON: + xa->xa_type = XFS_FILE_NON; + break; + case VREG: + xa->xa_type = XFS_FILE_REG; + break; + case VDIR: + xa->xa_type = XFS_FILE_DIR; + break; + case VBLK: + xa->xa_type = XFS_FILE_BLK; + break; + case VCHR: + xa->xa_type = XFS_FILE_CHR; + break; + case VLNK: + xa->xa_type = XFS_FILE_LNK; + break; + case VSOCK: + xa->xa_type = XFS_FILE_SOCK; + break; + case VFIFO: + xa->xa_type = XFS_FILE_FIFO; + break; + case VBAD: + xa->xa_type = XFS_FILE_BAD; + break; + default: + panic("xfs_attr2attr: bad value"); + } +} + +#define SET_TIMEVAL(X, S, N) do { (X)->tv_sec = (S); (X)->tv_nsec = (N); } while(0) + +void +xfs_attr2vattr(const struct xfs_attr *xa, struct vattr *va) +{ + VATTR_NULL(va); + if (XA_VALID_MODE(xa)) + va->va_mode = xa->xa_mode; + if (XA_VALID_NLINK(xa)) + va->va_nlink = xa->xa_nlink; + if (XA_VALID_SIZE(xa)) + va->va_size = xa->xa_size; + if (XA_VALID_UID(xa)) + va->va_uid = xa->xa_uid; + if (XA_VALID_GID(xa)) + va->va_gid = xa->xa_gid; + if (XA_VALID_ATIME(xa)) { + SET_TIMEVAL(&va->va_atime, xa->xa_atime, 0); + } + if (XA_VALID_MTIME(xa)) { + SET_TIMEVAL(&va->va_mtime, xa->xa_mtime, 0); + } + if (XA_VALID_CTIME(xa)) { + SET_TIMEVAL(&va->va_ctime, xa->xa_ctime, 0); + } + if (XA_VALID_FILEID(xa)) { + va->va_fileid = xa->xa_fileid; + } + if (XA_VALID_TYPE(xa)) { + switch (xa->xa_type) { + case XFS_FILE_NON: + va->va_type = VNON; + break; + case XFS_FILE_REG: + va->va_type = VREG; + break; + case XFS_FILE_DIR: + va->va_type = VDIR; + break; + case XFS_FILE_BLK: + va->va_type = VBLK; + break; + case XFS_FILE_CHR: + va->va_type = VCHR; + break; + case XFS_FILE_LNK: + va->va_type = VLNK; + break; + case XFS_FILE_SOCK: + va->va_type = VSOCK; + break; + case XFS_FILE_FIFO: + va->va_type = VFIFO; + break; + case XFS_FILE_BAD: + va->va_type = VBAD; + break; + default: + panic("xfs_attr2vattr: bad value"); + } + } + va->va_flags = 0; + va->va_blocksize = 8192; + va->va_bytes = va->va_size; +} + +/* + * A single entry DNLC for systems for handling long names that don't + * get put into the system DNLC. + */ + +struct long_entry { + struct vnode *dvp, *vp; + char name[MAXNAMLEN + 1]; + size_t len; + u_long dvpid, vpid; +}; + +static struct long_entry tbl; + +/* + * Nuke the `tbl' + */ + +static void +tbl_clear (void) +{ + tbl.dvp = tbl.vp = NULL; + tbl.name[0] = '\0'; + tbl.len = 0; + tbl.dvpid = tbl.vpid = 0; +} + +/* + * Set the entry in the `tbl' + */ + +static void +tbl_enter (size_t len, const char *name, struct vnode *dvp, struct vnode *vp) +{ + tbl.len = len; + bcopy(name, tbl.name, len); + tbl.dvp = dvp; + tbl.vp = vp; + tbl.dvpid = dvp->v_id; + tbl.vpid = vp->v_id; +} + +/* + * Lookup in tbl + */ + +static int +tbl_lookup (size_t len, const char *name, struct vnode *dvp, struct vnode **res) +{ + if (tbl.dvp == dvp + && tbl.len == len + && strncmp(tbl.name, name, len) == 0 + && tbl.dvpid == tbl.dvp->v_id + && tbl.vpid == tbl.vp->v_id) { + *res = tbl.vp; + return -1; + } else + return 0; +} + +/* + * Store a componentname in the DNLC + */ + +int +xfs_dnlc_enter(struct vnode *dvp, + xfs_componentname *cnp, + struct vnode *vp) +{ + XFSDEB(XDEBDNLC, ("xfs_dnlc_enter_cnp(%p, %p, %p)\n", dvp, cnp, vp)); + XFSDEB(XDEBDNLC, ("xfs_dnlc_enter: v_id = %ld\n", dvp->v_id)); + + XFSDEB(XDEBDNLC, ("xfs_dnlc_enter: calling cache_enter:" + "dvp = %p, vp = %p, cnp = (%s, %ld, %lu), " + "nameiop = %lu, flags = %lx\n", + dvp, vp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash, + cnp->cn_nameiop, cnp->cn_flags)); + +#ifdef NCHNAMLEN + if (cnp->cn_namelen <= NCHNAMLEN) +#endif + { + /* + * This is to make sure there's no negative entry already in the dnlc + */ + u_long save_nameiop; + struct vnode *dummy; + + save_nameiop = cnp->cn_nameiop; + cnp->cn_nameiop = CREATE; + + if (cache_lookup(dvp, &dummy, cnp) != 0) { + printf ("XFS PANIC WARNING! xfs_dnlc_enter: %s already in cache\n", + cnp->cn_nameptr); + } + + cnp->cn_nameiop = save_nameiop; + cache_enter(dvp, vp, cnp); + } + + if (vp != NULL) + tbl_enter (cnp->cn_namelen, cnp->cn_nameptr, dvp, vp); + + return 0; +} + + +void +xfs_cnp_init (struct componentname *cn, + const char *name, struct vnode *vp, struct vnode *dvp, + struct proc *proc, struct ucred *cred, + int nameiop) +{ + char *p ; + + bzero(cn, sizeof(*cn)); + cn->cn_nameptr = (char *)name; + cn->cn_namelen = strlen(name); + cn->cn_flags = 0; + cn->cn_hash = 0; + for (p = cn->cn_nameptr; *p; ++p) + cn->cn_hash += *p; + cn->cn_nameiop = nameiop; + cn->cn_proc = proc; + cn->cn_cred = cred; +} + + +/* + * Store (dvp, name, vp) in the DNLC + */ + +int +xfs_dnlc_enter_name(struct vnode *dvp, + const char *name, + struct vnode *vp) +{ + struct componentname cn; + const char *p; + + XFSDEB(XDEBDNLC, ("xfs_dnlc_enter_name(%p, \"%s\", %p)\n", dvp, name, vp)); + + cn.cn_nameiop = LOOKUP; + cn.cn_flags = 0; + cn.cn_namelen = strlen(name); + cn.cn_nameptr = (char *)name; + cn.cn_hash = 0; + for (p = cn.cn_nameptr; *p; ++p) + cn.cn_hash += *p; + + return xfs_dnlc_enter (dvp, &cn, vp); +} + +/* + * Lookup (dvp, cnp) in the DNLC and return the result in `res'. + * Return -1 if succesful, 0 if not and ENOENT if we're sure it doesn't exist. + */ + +int +xfs_dnlc_lookup(struct vnode *dvp, + xfs_componentname *cnp, + struct vnode **res) +{ + int error; + u_long saved_flags; + + XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup(%p, \"%s\")\n", dvp, cnp->cn_nameptr)); + + XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: v_id = %ld\n", dvp->v_id)); + + XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: calling cache_lookup:" + "dvp = %p, cnp = (%s, %ld, %lu), flags = %lx\n", + dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash, + cnp->cn_flags)); + + saved_flags = cnp->cn_flags; + cnp->cn_flags |= MAKEENTRY; + + error = cache_lookup(dvp, res, cnp); + + cnp->cn_flags = saved_flags; + + XFSDEB(XDEBDNLC, ("xfs_dnlc_lookup: cache_lookup returned. " + "error = %d, *res = %p\n", error, *res)); + + if (error == -1 || error == ENOENT) + return error; + + return tbl_lookup (cnp->cn_namelen, cnp->cn_nameptr, dvp, res); +} + +/* + * Remove one entry from the DNLC + */ + +void +xfs_dnlc_purge (struct vnode *vp) +{ + XFSDEB(XDEBDNLC, ("xfs_dnlc_purge\n")); + + if (tbl.dvp == vp || tbl.vp == vp) + tbl_clear (); + + cache_purge(vp); +} + +/* + * Remove all entries belong to `mp' from the DNLC + */ + +void +xfs_dnlc_purge_mp(struct mount *mp) +{ + XFSDEB(XDEBDNLC, ("xfs_dnlc_purge_mp()\n")); + + tbl_clear (); + cache_purgevfs(mp); +} + +/* + * Returns 1 if pag has any rights set in the node + */ + +int +xfs_has_pag(const struct xfs_node *xn, pag_t pag) +{ + int i; + + for (i = 0; i < MAXRIGHTS; i++) + if (xn->id[i] == pag) + return 1; + + return 0; +} diff --git a/sys/xfs/xfs_node.h b/sys/xfs/xfs_node.h index 6e64c14b657..a77ab61d993 100644 --- a/sys/xfs/xfs_node.h +++ b/sys/xfs/xfs_node.h @@ -1,4 +1,3 @@ -/* $OpenBSD: xfs_node.h,v 1.3 1998/09/06 01:48:58 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,36 +36,90 @@ * SUCH DAMAGE. */ -/* $KTH: xfs_node.h,v 1.3 1998/07/13 20:36:37 art Exp $ */ +/* $Id: xfs_node.h,v 1.4 1999/04/30 01:59:01 art Exp $ */ -#ifndef _XFS_XFS_NODE_H_ -#define _XFS_XFS_NODE_H_ +#ifndef _xfs_xnode_h +#define _xfs_xnode_h -#if 0 #include <sys/types.h> #include <sys/time.h> +#if defined(_KERNEL) || !defined(__OpenBSD__) #include <sys/vnode.h> #endif +#ifdef __NetBSD__ +#include <sys/lockf.h> +#endif /* __NetBSD__ */ #include <xfs/xfs_attr.h> #include <xfs/xfs_message.h> struct xfs_node { - struct vnode *vn; - struct vnode *data; - struct vattr attr; - u_int flags; - u_int tokens; - xfs_handle handle; - pag_t id[MAXRIGHTS]; - u_char rights[MAXRIGHTS]; - u_char anonrights; + struct vnode *vn; + struct vnode *data; + struct vattr attr; + u_int flags; + u_int tokens; + xfs_handle handle; + pag_t id[MAXRIGHTS]; + u_char rights[MAXRIGHTS]; + u_char anonrights; + int vnlocks; +#ifdef __NetBSD__ + struct lockf *i_lockf; +#endif }; +int xfs_getnewvnode(struct mount *mp, struct vnode **vpp, + struct xfs_handle *handle); + + #define DATA_FROM_VNODE(vp) DATA_FROM_XNODE(VNODE_TO_XNODE(vp)) + #define DATA_FROM_XNODE(xp) ((xp)->data) #define XNODE_TO_VNODE(xp) ((xp)->vn) #define VNODE_TO_XNODE(vp) ((struct xfs_node *) (vp)->v_data) +#if defined(HAVE_THREE_ARGUMENT_VGET) +#define xfs_do_vget(vp, lockflag, proc) vget((vp), (lockflag), (proc)) +#elif !defined(__osf__) +#define xfs_do_vget(vp, lockflag, proc) vget((vp), (lockflag)) +#else +#define xfs_do_vget(vp, lockflag, proc) vget((vp)) +#endif + +#ifndef HAVE_VOP_T +typedef int vop_t (void *); +#endif + +#ifdef LK_INTERLOCK +#define HAVE_LK_INTERLOCK +#else +#define LK_INTERLOCK 0 +#endif + +#ifdef LK_RETRY +#define HAVE_LK_RETRY +#else +#define LK_RETRY 0 #endif + +/* + * This is compat code for older vfs that have a + * vget that only take a integer (really boolean) argument + * that the the returned vnode will be returned locked + */ + +#ifdef LK_EXCLUSIVE +#define HAVE_LK_EXCLUSIVE 1 +#else +#define LK_EXCLUSIVE 1 +#endif + +#ifdef LK_SHARED +#define HAVE_LK_SHARED 1 +#else +#define LK_SHARED 1 +#endif + +#endif /* _xfs_xnode_h */ diff --git a/sys/xfs/xfs_pioctl.h b/sys/xfs/xfs_pioctl.h index 76ab12cf8a0..ee2d499df0b 100644 --- a/sys/xfs/xfs_pioctl.h +++ b/sys/xfs/xfs_pioctl.h @@ -1,6 +1,6 @@ -/* $OpenBSD: xfs_pioctl.h,v 1.2 1998/09/17 20:47:15 art Exp $ */ +/* $OpenBSD: xfs_pioctl.h,v 1.3 1999/04/30 01:59:01 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -18,7 +18,7 @@ * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Kungliga Tekniska - * Högskolan and its contributors. + * Högskolan and its contributors. * * 4. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software @@ -37,8 +37,8 @@ * SUCH DAMAGE. */ -#ifndef _SYS_PIOCTL_H_ -#define _SYS_PIOCTL_H_ +#ifndef _XFS_XFS_PIOCTL_H_ +#define _XFS_XFS_PIOCTL_H_ /* */ @@ -111,9 +111,28 @@ #define VIOC_TWIDDLE _VICEIOCTL(45) #define VIOC_SETSPREFS _VICEIOCTL(46) #define VIOC_STORBEHIND _VICEIOCTL(47) -#define VIOC_GETRXKCRYPT _VICEIOCTL(48) -#define VIOC_SETRXKCRYPT _VICEIOCTL(49) -#define VIOC_FPRIOSTATUS _VICEIOCTL(50) +#define VIOC_GCPAGS _VICEIOCTL(48) +#define VIOC_GETRXKCRYPT _VICEIOCTL(49) +#define VIOC_SETRXKCRYPT _VICEIOCTL(50) +#define VIOC_FPRIOSTATUS _VICEIOCTL(51) + +#define VIOC_FHGET _VICEIOCTL(52) +#define VIOC_FHOPEN _VICEIOCTL(53) + +#define VIOC_XFSDEBUG _VICEIOCTL(54) +#define VIOC_ARLADEBUG _VICEIOCTL(55) + +#define VIOC_AVIATOR _VICEIOCTL(56) + +#define VIOC_XFSDEBUG_PRINT _VICEIOCTL(57) + +/* + * GETCELLSTATUS flags + */ + +#define CELLSTATUS_PRIMARY 0x01 /* this is the `primary' cell */ +#define CELLSTATUS_SETUID 0x02 /* setuid honored for this cell */ +#define CELLSTATUS_OBSOLETE_VL 0x04 /* uses obsolete VL servers */ /* * VIOCCONNECTMODE arguments @@ -123,6 +142,7 @@ #define CONNMODE_CONN 1 #define CONNMODE_FETCH 2 #define CONNMODE_DISCONN 3 +#define CONNMODE_PARCONNECTED 4 /* * The struct for VIOC_FPRIOSTATUS @@ -146,6 +166,16 @@ struct vioc_fprio { int32_t Unique; }; +/* + * Flags for VIOCCKSERV + */ + +#define CKSERV_DONTPING 1 +#define CKSERV_FSONLY 2 + +#define CKSERV_MAXSERVERS 16 /* limitation of VIOCCKSERV number of + returned servers */ + struct ViceIoctl { caddr_t in, out; short in_size; diff --git a/sys/xfs/xfs_syscalls-common.c b/sys/xfs/xfs_syscalls-common.c new file mode 100644 index 00000000000..6dc34eb611e --- /dev/null +++ b/sys/xfs/xfs_syscalls-common.c @@ -0,0 +1,477 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <xfs/xfs_locl.h> + +RCSID("$Id: xfs_syscalls-common.c,v 1.1 1999/04/30 01:59:01 art Exp $"); + +/* + * XFS system calls. + */ + +#include <xfs/xfs_syscalls.h> +#include <xfs/xfs_message.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_dev.h> +#include <xfs/xfs_node.h> +#include <xfs/xfs_vfsops.h> +#include <xfs/xfs_deb.h> + +/* Misc syscalls */ +#ifdef HAVE_SYS_IOCCOM_H +#include <sys/ioccom.h> +#elif defined(HAVE_SYS_IOCTL_H) +#include <sys/ioctl.h> +#endif +#include <xfs/xfs_pioctl.h> + +/* + * the syscall entry point + */ + +int +sys_xfspioctl(struct proc *proc, void *varg, register_t *return_value) +{ + struct sys_pioctl_args *arg = (struct sys_pioctl_args *) varg; + int error = EINVAL; + + switch (SCARG(arg, operation)) { + case AFSCALL_PIOCTL: + error = xfs_pioctl_call(proc, varg, return_value); + break; + case AFSCALL_SETPAG: + error = xfs_setpag_call(&xfs_proc_to_cred(proc)); + break; + default: + XFSDEB(XDEBSYS, ("Unimplemeted xfspioctl: %d\n", + SCARG(arg, operation))); + error = EINVAL; + break; + } + + return error; +} + +/* + * Def pag: + * 33536 <= g0 <= 34560 + * 32512 <= g1 <= 48896 + */ + +#define XFS_PAG1_LLIM 33536 +#define XFS_PAG1_ULIM 34560 +#define XFS_PAG2_LLIM 32512 +#define XFS_PAG2_ULIM 48896 + +static gid_t pag_part_one = XFS_PAG1_LLIM; +static gid_t pag_part_two = XFS_PAG2_LLIM; + +/* + * Is `cred' member of a PAG? + */ + +static int +xfs_is_pag(struct ucred *cred) +{ + /* The first group is the gid of the user ? */ + + if (cred->cr_ngroups >= 3 && + cred->cr_groups[1] >= XFS_PAG1_LLIM && + cred->cr_groups[1] <= XFS_PAG1_ULIM && + cred->cr_groups[2] >= XFS_PAG2_LLIM && + cred->cr_groups[2] <= XFS_PAG2_ULIM) + return 1; + else + return 0; +} + +/* + * Return the pag used by `cred' + */ + +pag_t +xfs_get_pag(struct ucred *cred) +{ + if (xfs_is_pag(cred)) { + + return (((cred->cr_groups[1] << 16) & 0xFFFF0000) | + ((cred->cr_groups[2] & 0x0000FFFF))); + + } else + return cred->cr_uid; /* XXX */ +} + +/* + * Acquire a new pag in `ret_cred' + */ + +int +xfs_setpag_call(struct ucred **ret_cred) +{ + struct ucred *cred = *ret_cred; + int i; + + if (!xfs_is_pag(cred)) { + + /* Check if it fits */ + if (cred->cr_ngroups + 2 >= NGROUPS) + return E2BIG; /* XXX Hmmm, better error ? */ + + cred = crcopy (cred); + + /* Copy the groups */ + for (i = cred->cr_ngroups - 1; i > 0; i--) { + cred->cr_groups[i + 2] = cred->cr_groups[i]; + } + cred->cr_ngroups += 2; + + } else + cred = crcopy(cred); + + cred->cr_groups[1] = pag_part_one; + cred->cr_groups[2] = pag_part_two++; + + if (pag_part_two > XFS_PAG2_ULIM) { + pag_part_one++; + pag_part_two = XFS_PAG2_LLIM; + } + *ret_cred = cred; + return 0; +} + +/* + * Return the vnode corresponding to `pathptr' + */ + +static int +lookup_node (const char *pathptr, + int follow_links_p, + struct vnode **res, + struct proc *proc) +{ + int error; + char path[MAXPATHLEN]; +#ifdef __osf__ + struct nameidata *ndp = &u.u_nd; +#else + struct nameidata nd, *ndp = &nd; +#endif + struct vnode *vp; + size_t done; + + XFSDEB(XDEBSYS, ("xfs_syscall: looking up: %p\n", pathptr)); + + error = copyinstr(pathptr, path, MAXPATHLEN, &done); + + XFSDEB(XDEBSYS, ("xfs_syscall: looking up: %s len: %lu error: %d\n", + path, (unsigned long)done, error)); + + if (error) + return error; + + NDINIT(ndp, LOOKUP, + follow_links_p ? FOLLOW : 0, + UIO_SYSSPACE, path, proc); + + error = namei(ndp); + + if (error != 0) { + XFSDEB(XDEBSYS, ("xfs_syscall: error during namei: %d\n", error)); + return EINVAL; + } + + vp = ndp->ni_vp; + + *res = vp; + return 0; +} + +/* + * return file handle of `vp' in vice_ioctl->out + */ + +static int +fhget_call (struct proc *p, + struct ViceIoctl *vice_ioctl, + struct vnode *vp) +{ + int error; + struct mount *mnt; + struct vattr vattr; + size_t len; + struct xfs_fh_args fh_args; + + XFSDEB(XDEBSYS, ("fhget_call\n")); + + if (vp == NULL) + return EBADF; + + error = suser (xfs_proc_to_cred(p), NULL); + if (error) + return error; + +#ifdef __osf__ + VOP_GETATTR(vp, &vattr, p->p_rcred, error); +#else + error = VOP_GETATTR(vp, &vattr, p->p_ucred, p); +#endif + if (error) + goto out; + + mnt = vp->v_mount; + + SCARG(&fh_args, fsid) = mnt->mnt_stat.f_fsid; + SCARG(&fh_args, fileid) = vattr.va_fileid; + SCARG(&fh_args, gen) = vattr.va_gen; + + len = sizeof(fh_args); + + if (vice_ioctl->out_size < len) { + error = EINVAL; + goto out; + } + + error = copyout (&fh_args, vice_ioctl->out, len); + if (error) { + XFSDEB(XDEBSYS, ("fhget_call: copyout failed: %d\n", error)); + } + +out: + vrele (vp); + return error; +} + +/* + * open the file specified in `vice_ioctl->in' + */ + +static int +fhopen_call (struct proc *p, + struct ViceIoctl *vice_ioctl, + struct vnode *vp, + int flags, + register_t *retval) +{ + int error; + struct xfs_fh_args fh_args; + + XFSDEB(XDEBSYS, ("fhopen_call: flags = %d\n", flags)); + + if (vp != NULL) { + vrele (vp); + return EINVAL; + } + + if (vice_ioctl->in_size < sizeof(fh_args)) + return EINVAL; + + error = copyin (vice_ioctl->in, + &fh_args, + sizeof(fh_args)); + if (error) + return error; + + return xfs_fhopen (p, + SCARG(&fh_args, fsid), + SCARG(&fh_args, fileid), + SCARG(&fh_args, gen), + flags, + retval); +} + +/* + * Send the pioctl to arlad + */ + +static int +remote_pioctl (struct proc *p, + struct sys_pioctl_args *arg, + struct ViceIoctl *vice_ioctl, + struct vnode *vp) +{ + int error; + struct xfs_message_pioctl msg; + struct xfs_message_wakeup_data *msg2; + + if (vp != NULL) { + struct xfs_node *xn; + + if (vp->v_tag != VT_AFS) { + XFSDEB(XDEBSYS, ("xfs_syscall: file is not in afs\n")); + vrele(vp); + return EINVAL; + } + + xn = VNODE_TO_XNODE(vp); + + msg.handle = xn->handle; + vrele(vp); + } + + if (vice_ioctl->in_size > 2048) { + printf("xfs_pioctl_call: got a humongous in packet: opcode: %d", + SCARG(arg, a_opcode)); + return EINVAL; + } + if (vice_ioctl->in_size != 0) { + error = copyin(vice_ioctl->in, + &msg.msg, + vice_ioctl->in_size); + + if (error) + return error; + } + + msg.header.opcode = XFS_MSG_PIOCTL; + msg.opcode = SCARG(arg, a_opcode); + + msg.insize = vice_ioctl->in_size; + msg.outsize = vice_ioctl->out_size; +#ifdef __osf__ + msg.cred.uid = p->p_ruid; + msg.cred.pag = xfs_get_pag(p->p_rcred); +#else + msg.cred.uid = p->p_cred->p_ruid; + msg.cred.pag = xfs_get_pag(p->p_ucred); +#endif + + error = xfs_message_rpc(0, &msg.header, sizeof(msg)); /* XXX */ + msg2 = (struct xfs_message_wakeup_data *) &msg; + + if (error == 0) + error = msg2->error; + else + error = EINVAL; /* return EINVAL to not confuse applications */ + + if (error == 0 && msg2->header.opcode == XFS_MSG_WAKEUP_DATA) + error = copyout(msg2->msg, vice_ioctl->out, + min(msg2->len, vice_ioctl->out_size)); + return error; +} + +static int +xfs_debug (struct proc *p, + struct ViceIoctl *vice_ioctl) +{ + int32_t flags; + int error; + + if (vice_ioctl->in_size != 0) { + if (vice_ioctl->in_size < sizeof(int32_t)) + return EINVAL; + + error = suser (xfs_proc_to_cred(p), NULL); + if (error) + return error; + + error = copyin (vice_ioctl->in, + &flags, + sizeof(flags)); + if (error) + return error; + + xfsdeb = flags; + } + + if (vice_ioctl->out_size != 0) { + if (vice_ioctl->out_size < sizeof(int32_t)) + return EINVAL; + + error = copyout (&xfsdeb, + vice_ioctl->out, + sizeof(int32_t)); + if (error) + return error; + } + + return 0; +} + + +/* + * Handle `pioctl' + */ + +int +xfs_pioctl_call(struct proc *proc, + struct sys_pioctl_args *arg, + register_t *return_value) +{ + int error; + struct ViceIoctl vice_ioctl; + char *pathptr; + struct vnode *vp = NULL; + + XFSDEB(XDEBSYS, ("xfs_syscall(%d, %p, %d, %p, %d)\n", + SCARG(arg, operation), + SCARG(arg, a_pathP), + SCARG(arg, a_opcode), + SCARG(arg, a_paramsP), + SCARG(arg, a_followSymlinks))); + + /* Copy in the data structure for us */ + + error = copyin(SCARG(arg, a_paramsP), + &vice_ioctl, + sizeof(vice_ioctl)); + + if (error) + return error; + + pathptr = SCARG(arg, a_pathP); + + if (pathptr != NULL) { + error = lookup_node (pathptr, SCARG(arg, a_followSymlinks), &vp, + proc); + if(error) + return error; + } + + switch (SCARG(arg, a_opcode)) { + case VIOC_FHGET : + return fhget_call (proc, &vice_ioctl, vp); + case VIOC_FHOPEN : + return fhopen_call (proc, &vice_ioctl, vp, + SCARG(arg, a_followSymlinks), return_value); + case VIOC_XFSDEBUG: + return xfs_debug (proc, &vice_ioctl); + default : + XFSDEB(XDEBSYS, ("a_opcode = %x\n", SCARG(arg, a_opcode))); + return remote_pioctl (proc, arg, &vice_ioctl, vp); + } +} diff --git a/sys/xfs/xfs_syscalls-dummy.c b/sys/xfs/xfs_syscalls-dummy.c new file mode 100644 index 00000000000..656a34a3471 --- /dev/null +++ b/sys/xfs/xfs_syscalls-dummy.c @@ -0,0 +1,11 @@ +/* + * This code released into public domain by Artur Grabowski <art@openbsd.org> + */ +#include <xfs/xfs_locl.h> +#include <sys/syscallargs.h> + +int +sys_xfspioctl(struct proc *proc, void *varg, register_t *retval) +{ + return ENOSYS; +} diff --git a/sys/xfs/xfs_syscalls.h b/sys/xfs/xfs_syscalls.h index 4a8d1bfaadf..2ebdaa17674 100644 --- a/sys/xfs/xfs_syscalls.h +++ b/sys/xfs/xfs_syscalls.h @@ -1,6 +1,5 @@ -/* $OpenBSD: xfs_syscalls.h,v 1.2 1998/08/31 05:13:29 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,14 +36,58 @@ * SUCH DAMAGE. */ -/* $KTH: xfs_syscalls.h,v 1.2 1998/01/21 01:03:57 mho Exp $ */ +/* $Id: xfs_syscalls.h,v 1.3 1999/04/30 01:59:01 art Exp $ */ -#ifndef _XFS_XFS_SYSCALLS_H_ -#define _XFS_XFS_SYSCALLS_H_ +#ifndef __xfs_syscalls +#define __xfs_syscalls -int xfs_install_syscalls __P((void)); -int xfs_uninstall_syscalls __P((void)); -int xfs_stat_syscalls __P((void)); -pag_t xfs_get_pag __P((struct ucred *)); +#include <xfs/xfs_common.h> +#include <xfs/xfs_message.h> +#ifdef HAVE_SYS_SYSCALLARGS_H +#include <sys/syscallargs.h> +#endif + +/* + * XXX + */ + +#ifndef SCARG +#define SCARG(a, b) ((a)->b.datum) +#define syscallarg(x) union { x datum; register_t pad; } +#endif + +#ifndef syscallarg +#define syscallarg(x) x +#endif +#ifndef HAVE_REGISTER_T +typedef int register_t; #endif + +struct sys_pioctl_args { + syscallarg(int) operation; + syscallarg(char *) a_pathP; + syscallarg(int) a_opcode; + syscallarg(struct ViceIoctl *) a_paramsP; + syscallarg(int) a_followSymlinks; +}; + +struct xfs_fh_args { + syscallarg(fsid_t) fsid; + syscallarg(long) fileid; + syscallarg(long) gen; +}; + +int xfs_install_syscalls(void); +int xfs_uninstall_syscalls(void); +int xfs_stat_syscalls(void); +pag_t xfs_get_pag(struct ucred *); + +int xfs_setpag_call(struct ucred **ret_cred); +int xfs_pioctl_call(struct proc *proc, + struct sys_pioctl_args *args, + register_t *return_value); + +int sys_xfspioctl(struct proc *proc, void *varg, register_t *retval); + +#endif /* __xfs_syscalls */ diff --git a/sys/xfs/xfs_vfsops-bsd.c b/sys/xfs/xfs_vfsops-bsd.c new file mode 100644 index 00000000000..723cb1aa1d8 --- /dev/null +++ b/sys/xfs/xfs_vfsops-bsd.c @@ -0,0 +1,381 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <xfs/xfs_locl.h> + +RCSID("$Id: xfs_vfsops-bsd.c,v 1.1 1999/04/30 01:59:01 art Exp $"); + +/* + * XFS vfs operations. + */ + +#include <xfs/xfs_common.h> +#include <xfs/xfs_message.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_dev.h> +#include <xfs/xfs_deb.h> +#include <xfs/xfs_vfsops.h> +#include <xfs/xfs_vfsops-bsd.h> +#include <xfs/xfs_vnodeops.h> + +int +xfs_mount(struct mount *mp, + const char *user_path, + caddr_t user_data, + struct nameidata *ndp, + struct proc *p) +{ + return xfs_mount_common(mp, user_path, user_data, ndp, p); +} + +int +xfs_start(struct mount * mp, int flags, struct proc * p) +{ + XFSDEB(XDEBVFOPS, ("xfs_start mp = %p, flags = %d, proc = %p\n", + mp, flags, p)); + return 0; +} + + +int +xfs_unmount(struct mount * mp, int mntflags, struct proc *p) +{ + XFSDEB(XDEBVFOPS, ("xfs_umount: mp = %p, mntflags = %d, proc = %p\n", + mp, mntflags, p)); + return xfs_unmount_common(mp, mntflags); +} + +int +xfs_root(struct mount *mp, struct vnode **vpp) +{ + XFSDEB(XDEBVFOPS, ("xfs_root mp = %p\n", mp)); + return xfs_root_common(mp, vpp, curproc, curproc->p_ucred); +} + +int +xfs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg, struct proc *p) +{ + XFSDEB(XDEBVFOPS, ("xfs_quotactl: mp = %p, cmd = %d, uid = %u, " + "arg = %p, proc = %p\n", + mp, cmd, uid, arg, p)); + return EOPNOTSUPP; +} + +int +xfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p) +{ + XFSDEB(XDEBVFOPS, ("xfs_statfs: mp = %p, sbp = %p, proc = %p\n", + mp, sbp, p)); + bcopy(&mp->mnt_stat, sbp, sizeof(*sbp)); + return 0; +} + +int +xfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p) +{ + XFSDEB(XDEBVFOPS, ("xfs_sync: mp = %p, waitfor = %d, " + "cred = %p, proc = %p\n", + mp, waitfor, cred, p)); + return 0; +} + +int +xfs_vget(struct mount * mp, + ino_t ino, + struct vnode ** vpp) +{ + XFSDEB(XDEBVFOPS, ("xfs_vget\n")); + return EOPNOTSUPP; +} + +int +xfs_fhtovp(struct mount * mp, + struct fid * fhp, + struct mbuf * nam, + struct vnode ** vpp, + int *exflagsp, + struct ucred ** credanonp) +{ +#ifdef ARLA_KNFS + static struct ucred fhtovpcred; + struct netcred *np = NULL; + struct xfs_node *xn; + struct vnode *vp; + xfs_handle handle; + int error; + + XFSDEB(XDEBVFOPS, ("xfs_fhtovp\n")); + + if (fhp->fid_len != 16) { + printf("xfs_fhtovp: *PANIC* got a invalid length of a fid\n"); + return EINVAL; + } + + /* XXX: Should see if we is exported to this client */ +#if 0 + np = vfs_export_lookup(mp, &ump->um_export, nam); + if (np == NULL) + return EACCES; +#endif + + memcpy(&handle, fhp->fid_data, sizeof(handle)); + XFSDEB(XDEBVFOPS, ("xfs_fhtovp: fid: %d.%d.%d.%d\n", + handle.a, handle.d, handle.c, handle.d)); + + XFSDEB(XDEBVFOPS, ("xfs_fhtovp: xfs_vnode_find\n")); + xn = xfs_node_find(&xfs[0], &handle); /* XXX: 0 */ + + if (xn == NULL) { + struct xfs_message_getattr msg; + + error = xfs_getnewvnode(xfs[0].mp, &vp, &handle); + if (error) + return error; + + xfs_do_vget(vp, 0, current); + + } else { + /* XXX access ? */ + vp = XNODE_TO_VNODE(xn); + + /* XXX wrong ? (we tell arla below) */ + if (vp->v_usecount <= 0) + xfs_do_vget(vp, 0, current); + else + VREF(vp); + error = 0; + } + + if (error == 0) { + fhtovpcred.cr_uid = 0; + fhtovpcred.cr_gid = 0; + fhtovpcred.cr_ngroups = 0; + + *vpp = vp; +#ifdef MNT_EXPUBLIC + *exflagsp = MNT_EXPUBLIC; +#else + *exflagsp = 0; +#endif + *credanonp = &fhtovpcred; + + XFSDEB(XDEBVFOPS, ("xfs_fhtovp done\n")); + + /* + * XXX tell arla about this node is hold by nfsd. + * There need to be code in xfs_write too. + */ + } else + XFSDEB(XDEBVFOPS, ("xfs_fhtovp failed (%d);", error)); + + return error; +#else + return EOPNOTSUPP; +#endif +} + +int +xfs_vptofh(struct vnode * vp, + struct fid * fhp) +{ +#ifdef ARLA_KNFS + struct xfs_node *xn; + XFSDEB(XDEBVFOPS, ("xfs_vptofh\n")); + + if (MAXFIDSZ < 16) + return EOPNOTSUPP; + + xn = VNODE_TO_XNODE(vp); + + if (xn == NULL) + return EINVAL; + + fhp->fid_len = 16; + memcpy(fhp->fid_data, &xn->handle, 16); + + return 0; +#else + XFSDEB(XDEBVFOPS, ("xfs_vptofh\n")); + return EOPNOTSUPP; +#endif +} + +/* + * xfs complete dead vnodes implementation. + * + * this is because the dead_vnodeops_p is _not_ filesystem, but rather + * a part of the vfs-layer. + */ + +int +xfs_dead_lookup(struct vop_lookup_args * ap) + /* struct vop_lookup_args { + struct vnodeop_desc *a_desc; + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; +}; */ +{ + *ap->a_vpp = NULL; + return ENOTDIR; +} + +/* + * Given `fsid', `fileid', and `gen', return in `vpp' a locked and + * ref'ed vnode from that file system with that id and generation. + * All is done in the context of `proc'. Returns 0 if succesful, and + * error otherwise. + */ + +int +xfs_fhlookup (struct proc *proc, + fsid_t fsid, + long fileid, + long gen, + struct vnode **vpp) +{ + int error; + struct mount *mp; + struct ucred *cred = proc->p_ucred; + struct vattr vattr; + + XFSDEB(XDEBVFOPS, ("xfs_fhlookup: fileid = %ld\n", + fileid)); + + error = suser (cred, NULL); + if (error) + return EPERM; + +#ifdef HAVE_KERNEL_VFS_GETVFS + mp = vfs_getvfs (&fsid); +#else + mp = getvfs (&fsid); +#endif + if (mp == NULL) + return ENXIO; + + error = VFS_VGET(mp, fileid, vpp); + + if (error) + return error; + + error = VOP_GETATTR(*vpp, &vattr, cred, proc); + if (error) { + vput(*vpp); + return error; + } + + if (vattr.va_gen != gen) { + vput(*vpp); + return ENOENT; + } + +#ifdef HAVE_KERNEL_VFS_OBJECT_CREATE + if ((*vpp)->v_type == VREG && (*vpp)->v_object == NULL) +#if HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE + vfs_object_create (*vpp, proc, proc->p_ucred, TRUE); +#else + vfs_object_create (*vpp, proc, proc->p_ucred); +#endif +#endif + return 0; +} + +/* + * Perform an open operation on the vnode identified by (fsid, fileid, + * gen) (see xfs_fhlookup) with flags `user_flags'. Returns 0 or + * error. If succsesful, the file descriptor is returned in `retval'. + */ + +int +xfs_fhopen (struct proc *proc, + fsid_t fsid, + long fileid, + long gen, + int user_flags, + register_t *retval) +{ + int error; + struct vnode *vp; + struct ucred *cred = proc->p_ucred; + int flags = FFLAGS(user_flags); + int index; + struct file *fp; + extern struct fileops vnops; + + XFSDEB(XDEBVFOPS, ("xfs_fhopen: fileid = %ld, flags = %d\n", + fileid, user_flags)); + + error = xfs_fhlookup (proc, fsid, fileid, gen, &vp); + if (error) + return error; + + error = VOP_OPEN(vp, flags, cred, proc); + if (error) + goto out; + + error = falloc(proc, &fp, &index); + if (error) + goto out; + + if (flags & FWRITE) + vp->v_writecount++; + +#if __FreeBSD_version >= 300000 + if (vp->v_type == VREG) { +#if HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE + error = vfs_object_create(vp, proc, proc->p_cred->pc_ucred, 1); +#else + error = vfs_object_create(vp, proc, proc->p_cred->pc_ucred); +#endif + if (error) + goto out; + } +#endif + + fp->f_flag = flags & FMASK; + fp->f_type = DTYPE_VNODE; + fp->f_ops = &vnops; + fp->f_data = (caddr_t)vp; + xfs_vfs_unlock(vp, proc); + *retval = index; + return 0; +out: + vput(vp); + return error; +} diff --git a/sys/xfs/xfs_vfsops-bsd.h b/sys/xfs/xfs_vfsops-bsd.h new file mode 100644 index 00000000000..5cb767f8eb0 --- /dev/null +++ b/sys/xfs/xfs_vfsops-bsd.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: xfs_vfsops-bsd.h,v 1.1 1999/04/30 01:59:01 art Exp $ */ + +#ifndef _xfs_vfsops_bsd_h +#define _xfs_vfsops_bsd_h + +int +xfs_mount(struct mount * mp, + const char *user_path, + caddr_t user_data, + struct nameidata * ndp, + struct proc * p); + +int +xfs_start(struct mount * mp, int flags, struct proc * p); + +int +xfs_unmount(struct mount * mp, int mntflags, struct proc *p); + +int +xfs_root(struct mount *mp, struct vnode **vpp); + +int +xfs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg, struct proc *p); + +int +xfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p); + +int +xfs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p); + +int +xfs_vget(struct mount * mp, + ino_t ino, + struct vnode ** vpp); + +int +xfs_fhtovp(struct mount * mp, + struct fid * fhp, + struct mbuf * nam, + struct vnode ** vpp, + int *exflagsp, + struct ucred ** credanonp); + +int +xfs_vptofh(struct vnode * vp, + struct fid * fhp); + +int +xfs_dead_lookup(struct vop_lookup_args * ap); + +#endif /* _xfs_vfsops_bsd_h */ diff --git a/sys/xfs/xfs_vfsops-common.c b/sys/xfs/xfs_vfsops-common.c new file mode 100644 index 00000000000..8f1210cbc9c --- /dev/null +++ b/sys/xfs/xfs_vfsops-common.c @@ -0,0 +1,269 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <xfs/xfs_locl.h> + +RCSID("$Id: xfs_vfsops-common.c,v 1.1 1999/04/30 01:59:01 art Exp $"); + +/* + * XFS vfs operations. + */ + +#include <xfs/xfs_common.h> +#include <xfs/xfs_message.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_dev.h> +#include <xfs/xfs_deb.h> +#include <xfs/xfs_syscalls.h> +#include <xfs/xfs_vfsops.h> + +struct xfs xfs[NXFS]; + +int +xfs_mount_common(struct mount *mp, + const char *user_path, + caddr_t user_data, + struct nameidata *ndp, + struct proc *p) +{ + struct vnode *devvp; + dev_t dev; + int error; + struct vattr vat; + char path[MAXPATHLEN]; + char data[MAXPATHLEN]; + size_t len; + + error = copyinstr(user_path, path, MAXPATHLEN, &len); + if (error) + return error; + + error = copyinstr(user_data, data, MAXPATHLEN, &len); + if (error) + return error; + + XFSDEB(XDEBVFOPS, ("xfs_mount: " + "struct mount mp = %p path = '%s' data = '%s'\n", + mp, path, data)); + +#ifdef ARLA_KNFS + XFSDEB(XDEBVFOPS, ("xfs_mount: mount flags = %x\n", mp->mnt_flag)); + + /* + * mountd(8) flushes all export entries when it starts + * right now we ignore it (but should not) + */ + + if (mp->mnt_flag & MNT_UPDATE || + mp->mnt_flag & MNT_DELEXPORT) { + + XFSDEB(XDEBVFOPS, + ("xfs_mount: ignoreing MNT_UPDATE or MNT_DELEXPORT\n")); + return 0; + } +#endif + + NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, data, p); + error = namei(ndp); + if (error) { + XFSDEB(XDEBVFOPS, ("namei failed, errno = %d\n", error)); + return error; + } + + devvp = ndp->ni_vp; + + if (devvp->v_type != VCHR) { + vput(devvp); + XFSDEB(XDEBVFOPS, ("not VCHR (%d)\n", devvp->v_type)); + return ENXIO; + } +#ifdef __osf__ + VOP_GETATTR(devvp, &vat, ndp->ni_cred, error); +#else + error = VOP_GETATTR(devvp, &vat, p->p_ucred, p); +#endif + vput(devvp); + if (error) { + XFSDEB(XDEBVFOPS, ("VOP_GETATTR failed, error = %d\n", error)); + return error; + } + dev = vat.va_rdev; + XFSDEB(XDEBVFOPS, ("dev = %d.%d\n", major(dev), minor(dev))); + + /* Check that this device really is an xfs_dev */ + if (major(dev) < 0 || major(dev) > nchrdev) { + XFSDEB(XDEBVFOPS, ("major out of range (0 < %d < %d)\n", + major(dev), nchrdev)); + return ENXIO; + } + if (minor(dev) < 0 || NXFS < minor(dev)) { + XFSDEB(XDEBVFOPS, ("minor out of range (0 < %d < %d)\n", + minor(dev), NXFS)); + return ENXIO; + } +#if defined(__NetBSD__) || defined(__OpenBSD__) + if(!xfs_func_is_devopen(cdevsw[major(dev)].d_open)) + return ENXIO; +#elif defined(__FreeBSD__) + if (cdevsw[major(dev)] == NULL + || !xfs_func_is_devopen(cdevsw[major(dev)]->d_open)) + return ENXIO; +#endif + + if (xfs[minor(dev)].status & XFS_MOUNTED) + return EBUSY; + + xfs[minor(dev)].status = XFS_MOUNTED; + xfs[minor(dev)].mp = mp; + xfs[minor(dev)].root = 0; + xfs[minor(dev)].nnodes = 0; + xfs[minor(dev)].fd = minor(dev); + + VFS_TO_XFS(mp) = &xfs[minor(dev)]; +#if defined(HAVE_KERNEL_VFS_GETNEWFSID) +#if defined(HAVE_TWO_ARGUMENT_VFS_GETNEWFSID) + vfs_getnewfsid(mp, MOUNT_AFS); +#else + vfs_getnewfsid(mp); +#endif +#elif defined(__NetBSD__) || defined(__OpenBSD__) + getnewfsid(mp, makefstype(MOUNT_AFS)); +#elif defined(__FreeBSD__) + getnewfsid(mp, MOUNT_AFS); + mp->mnt_stat.f_type = MOUNT_AFS; +#endif + + mp->mnt_stat.f_bsize = DEV_BSIZE; +#ifndef __osf__ + mp->mnt_stat.f_iosize = DEV_BSIZE; + mp->mnt_stat.f_owner = 0; +#endif + mp->mnt_stat.f_blocks = 4711 * 4711; + mp->mnt_stat.f_bfree = 4711 * 4711; + mp->mnt_stat.f_bavail = 4711 * 4711; + mp->mnt_stat.f_files = 4711; + mp->mnt_stat.f_ffree = 4711; + mp->mnt_stat.f_flags = mp->mnt_flag; + +#ifdef __osf__ + mp->mnt_stat.f_fsid.val[0] = dev; + mp->mnt_stat.f_fsid.val[1] = MOUNT_XFS; + + MALLOC(mp->m_stat.f_mntonname, char *, strlen(path) + 1, + M_PATHNAME, M_WAITOK); + strcpy(mp->m_stat.f_mntonname, path); + + MALLOC(mp->m_stat.f_mntfromname, char *, sizeof("arla"), + M_PATHNAME, M_WAITOK); + strcpy(mp->m_stat.f_mntfromname, "arla"); +#else /* __osf__ */ + strncpy(mp->mnt_stat.f_mntonname, + path, + sizeof(mp->mnt_stat.f_mntonname)); + + strncpy(mp->mnt_stat.f_mntfromname, + "arla", + sizeof(mp->mnt_stat.f_mntfromname)); + +#if defined(__NetBSD__) || defined(__OpenBSD__) + strncpy(mp->mnt_stat.f_fstypename, + "xfs", + sizeof(mp->mnt_stat.f_fstypename)); +#endif +#endif /* __osf__ */ + + return 0; +} + +int +xfs_unmount_common(struct mount *mp, int mntflags) +{ + struct xfs *xfsp = VFS_TO_XFS(mp); + int flags = 0; + int error; + + if (mntflags & MNT_FORCE) { +#ifdef HAVE_KERNEL_DOFORCE + extern int doforce; + if (!doforce) + return EINVAL; +#endif + flags |= FORCECLOSE; + } + + error = free_all_xfs_nodes(xfsp, flags, 1); + if (error) + return error; + + xfsp->status = 0; + XFS_TO_VFS(xfsp) = NULL; + return 0; +} + +int +xfs_root_common(struct mount *mp, struct vnode **vpp, + struct proc *proc, struct ucred *cred) +{ + struct xfs *xfsp = VFS_TO_XFS(mp); + struct xfs_message_getroot msg; + int error; + + do { + if (xfsp->root != NULL) { + *vpp = XNODE_TO_VNODE(xfsp->root); + xfs_do_vget(*vpp, LK_INTERLOCK|LK_EXCLUSIVE, proc); + return 0; + } + msg.header.opcode = XFS_MSG_GETROOT; + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } while (error == 0); + /* + * Failed to get message through, need to pretend that all went well + * and return a fake dead vnode to be able to unmount. + */ + + if ((error = make_dead_vnode(mp, vpp))) + return error; + + (*vpp)->v_flag |= VROOT; + return 0; +} diff --git a/sys/xfs/xfs_vfsops-openbsd.c b/sys/xfs/xfs_vfsops-openbsd.c new file mode 100644 index 00000000000..c4c8f770bbe --- /dev/null +++ b/sys/xfs/xfs_vfsops-openbsd.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <xfs/xfs_locl.h> + +RCSID("$Id: xfs_vfsops-openbsd.c,v 1.1 1999/04/30 01:59:01 art Exp $"); + +#include <xfs/xfs_common.h> +#include <xfs/xfs_message.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_dev.h> +#include <xfs/xfs_deb.h> +#include <xfs/xfs_vfsops.h> +#include <xfs/xfs_vfsops-bsd.h> +#include <xfs/xfs_vnodeops.h> + +static vop_t **xfs_dead_vnodeop_p; + +int +make_dead_vnode(struct mount *mp, struct vnode **vpp) +{ + XFSDEB(XDEBNODE, ("make_dead_vnode mp = %p\n", mp)); + + return getnewvnode(VT_NON, mp, xfs_dead_vnodeop_p, vpp); +} + +static struct vnodeopv_entry_desc xfs_dead_vnodeop_entries[] = { + {&vop_default_desc, (vop_t *) xfs_eopnotsupp}, + {&vop_lookup_desc, (vop_t *) xfs_dead_lookup}, + {&vop_reclaim_desc, (vop_t *) xfs_returnzero}, + {NULL, NULL}}; + +static struct vnodeopv_desc xfs_dead_vnodeop_opv_desc = +{&xfs_dead_vnodeop_p, xfs_dead_vnodeop_entries}; + +extern struct vnodeopv_desc xfs_vnodeop_opv_desc; + +static int +xfs_init(struct vfsconf *vfs) +{ + XFSDEB(XDEBVFOPS, ("xfs_init\n")); + vfs_opv_init_explicit(&xfs_vnodeop_opv_desc); + vfs_opv_init_default(&xfs_vnodeop_opv_desc); + vfs_opv_init_explicit(&xfs_dead_vnodeop_opv_desc); + vfs_opv_init_default(&xfs_dead_vnodeop_opv_desc); + return 0; +} + +struct vfsops xfs_vfsops = { + xfs_mount, + xfs_start, + xfs_unmount, + xfs_root, + xfs_quotactl, + xfs_statfs, + xfs_sync, + xfs_vget, + xfs_fhtovp, + xfs_vptofh, + xfs_init, + NULL, +}; + +static struct vfsconf xfs_vfc = { + &xfs_vfsops, + "xfs", + 0, + 0, + 0, + NULL, + NULL +}; + +#ifndef HAVE_KERNEL_VFS_REGISTER + +static int +vfs_register (struct vfsconf *vfs) +{ + struct vfsconf *vfsp; + struct vfsconf **vfspp; + + /* Check if filesystem already known */ + for (vfspp = &vfsconf, vfsp = vfsconf; + vfsp; + vfspp = &vfsp->vfc_next, vfsp = vfsp->vfc_next) + if (strcmp(vfsp->vfc_name, vfs->vfc_name) == 0) + return (EEXIST); + + maxvfsconf++; + + /* Add to the end of the list */ + *vfspp = vfs; + + vfs->vfc_next = NULL; + + /* Call vfs_init() */ + XFSDEB(XDEBVFOPS, ("calling vfs_init\n")); + (*(vfs->vfc_vfsops->vfs_init)) (vfs); + + /* done! */ + + return 0; +} + +static int +vfs_unregister (struct vfsconf *vfs) +{ + struct vfsconf *vfsp; + struct vfsconf **vfspp; + + /* Find our vfsconf struct */ + for (vfspp = &vfsconf, vfsp = vfsconf; + vfsp; + vfspp = &vfsp->vfc_next, vfsp = vfsp->vfc_next) + if (strcmp(vfsp->vfc_name, vfs->vfc_name) == 0) + break; + + if (!vfsp) /* Not found */ + return (ENOENT); + + if (vfsp->vfc_refcount) /* In use */ + return (EBUSY); + + /* Remove from list and free */ + *vfspp = vfsp->vfc_next; + + maxvfsconf--; + + return 0; +} + +#endif + +int +xfs_install_filesys(void) +{ + return vfs_register (&xfs_vfc); +} + +int +xfs_uninstall_filesys(void) +{ + return vfs_unregister (&xfs_vfc); +} + +int +xfs_stat_filesys (void) +{ + return 0; +} diff --git a/sys/xfs/xfs_vfsops.h b/sys/xfs/xfs_vfsops.h new file mode 100644 index 00000000000..55a5ff1c175 --- /dev/null +++ b/sys/xfs/xfs_vfsops.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: xfs_vfsops.h,v 1.1 1999/04/30 01:59:01 art Exp $ */ + +#ifndef _xfs_vfsops_h +#define _xfs_vfsops_h + +int +xfs_mount_common(struct mount *mp, + const char *user_path, + caddr_t user_data, + struct nameidata *ndp, + struct proc *p); + +int +xfs_unmount_common(struct mount *mp, int mntflags); + +int +xfs_root_common(struct mount *mp, + struct vnode **vpp, + struct proc *proc, + struct ucred *cred); + +int +xfs_fhlookup (struct proc *proc, + fsid_t fsid, + long fileid, + long gen, + struct vnode **vpp); + +int +xfs_fhopen (struct proc *proc, + fsid_t fsid, + long fileid, + long gen, + int flags, + register_t *retval); + +int make_dead_vnode(struct mount *mp, struct vnode **vpp); + +#endif /* _xfs_vfsops_h */ diff --git a/sys/xfs/xfs_vnodeops-bsd.c b/sys/xfs/xfs_vnodeops-bsd.c new file mode 100644 index 00000000000..01b1f096a81 --- /dev/null +++ b/sys/xfs/xfs_vnodeops-bsd.c @@ -0,0 +1,1030 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * XFS operations. + */ + +#include <xfs/xfs_locl.h> +#include <xfs/xfs_message.h> +#include <xfs/xfs_common.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_dev.h> +#include <xfs/xfs_deb.h> +#include <xfs/xfs_syscalls.h> +#include <xfs/xfs_vnodeops.h> +#include <vm/vm.h> +#include <vm/vnode_pager.h> + +RCSID("$Id: xfs_vnodeops-bsd.c,v 1.1 1999/04/30 01:59:01 art Exp $"); + +/* + * vnode functions + */ + +#ifdef HAVE_VOP_OPEN +static int +xfs_open(struct vop_open_args * ap) + /* + struct vop_open { + struct vnode *vp; + int mode; + struct ucred *cred; + struct proc *p; + }; */ +{ + XFSDEB(XDEBVNOPS, ("xfs_open\n")); + + if (ap->a_mode & FWRITE) + return xfs_open_valid(ap->a_vp, ap->a_cred, XFS_OPEN_NW); + else + return xfs_open_valid(ap->a_vp, ap->a_cred, XFS_OPEN_NR); +} +#endif /* HAVE_VOP_OPEN */ + +#ifdef HAVE_VOP_FSYNC +static int +xfs_fsync(struct vop_fsync_args * ap) + /* + vop_fsync { + struct vnode *vp; + struct ucred *cred; + int waitfor; + struct proc *p; +}; */ +{ +#ifdef HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS + return xfs_fsync_common(ap->a_vp, ap->a_cred, ap->a_flags, ap->a_p); +#else + return xfs_fsync_common(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_p); +#endif +} +#endif /* HAVE_VOP_FSYNC */ + +#ifdef HAVE_VOP_CLOSE +static int +xfs_close(struct vop_close_args * ap) + /* vop_close { + IN struct vnode *vp; + IN int fflag; + IN struct ucred *cred; + IN struct proc *p; + }; */ +{ + return xfs_close_common(ap->a_vp, ap->a_fflag, ap->a_p, ap->a_cred); +} +#endif /* HAVE_VOP_CLOSE */ + +#ifdef HAVE_VOP_READ +static int +xfs_read(struct vop_read_args * ap) + /* vop_read { + IN struct vnode *vp; + INOUT struct uio *uio; + IN int ioflag; + IN struct ucred *cred; + }; */ +{ + return xfs_read_common(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred); +} +#endif /* HAVE_VOP_READ */ + +#ifdef HAVE_VOP_WRITE +static int +xfs_write(struct vop_write_args * ap) + /* vop_write { + IN struct vnode *vp; + INOUT struct uio *uio; + IN int ioflag; + IN struct ucred *cred; + }; */ +{ + return xfs_write_common(ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred); +} +#endif /* HAVE_VOP_WRITE */ + +#ifdef HAVE_VOP_IOCTL +static int +xfs_ioctl(struct vop_ioctl_args * ap) + /* struct vnode *vp, + int com, + caddr_t data, + int flag, + struct ucred *cred) */ +{ + XFSDEB(XDEBVNOPS, ("xfs_ioctl\n")); + + return EOPNOTSUPP; +} +#endif /* HAVE_VOP_IOCTL */ + +#ifdef HAVE_VOP_SELECT +static int +xfs_select(struct vop_select_args * ap) + /* struct vnode *vp, + int which, + struct ucred *cred ) */ +{ + XFSDEB(XDEBVNOPS, ("xfs_select\n")); + + return EOPNOTSUPP; +} +#endif /* HAVE_VOP_SELECT */ + +#ifdef HAVE_VOP_SEEK +static int +xfs_seek(struct vop_seek_args * ap) + /* +struct vop_seek_args { + struct vnodeop_desc *a_desc; + struct vnode *a_vp; + off_t a_oldoff; + off_t a_newoff; + struct ucred *a_cred; +}; +*/ +{ + XFSDEB(XDEBVNOPS, ("xfs_seek\n")); + return 0; +} +#endif /* HAVE_VOP_SEEK */ + +#ifdef HAVE_VOP_POLL +static int +xfs_poll(struct vop_poll_args * ap) + /* vop_poll { + IN struct vnode *vp; + IN int events; + IN struct proc *p; + }; */ +{ + XFSDEB(XDEBVNOPS, ("xfs_poll\n")); + return EOPNOTSUPP; +} +#endif /* HAVE_VOP_POLL */ + +#ifdef HAVE_VOP_GETATTR +static int +xfs_getattr(struct vop_getattr_args * ap) + /* struct vnode *vp, + struct vattr *vap, + struct ucred *cred) */ +{ + return xfs_getattr_common(ap->a_vp, ap->a_vap, ap->a_cred); +} +#endif /* HAVE_VOP_GETATTR */ + +#ifdef HAVE_VOP_SETATTR +static int +xfs_setattr(struct vop_setattr_args * ap) + /* +struct vnode *vp, + struct vattr *vap, + struct ucred *cred) + */ +{ + return xfs_setattr_common(ap->a_vp, ap->a_vap, ap->a_cred); +} +#endif /* HAVE_VOP_SETATTR */ + +#ifdef HAVE_VOP_ACCESS +static int +xfs_access(struct vop_access_args * ap) + /* +struct vnode *vp, + int mode, + struct ucred *cred) + */ +{ + return xfs_access_common(ap->a_vp, ap->a_mode, ap->a_cred); +} +#endif /* HAVE_VOP_ACCESS */ + +#ifdef HAVE_VOP_LOOKUP +static int +xfs_lookup(struct vop_lookup_args * ap) + /* struct vop_lookup_args { + struct vnodeop_desc *a_desc; + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; +}; */ +{ + struct componentname *cnp = ap->a_cnp; + int error; + + XFSDEB(XDEBVNOPS, ("xfs_lookup: (%s, %ld), nameiop = %lu, flags = %lu\n", + cnp->cn_nameptr, + cnp->cn_namelen, + cnp->cn_nameiop, + cnp->cn_flags)); + + error = xfs_lookup_common(ap->a_dvp, cnp, ap->a_vpp); + + if (error == ENOENT + && (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) + && (cnp->cn_flags & ISLASTCN)) { + error = EJUSTRETURN; + } + + if (cnp->cn_nameiop != LOOKUP && cnp->cn_flags & ISLASTCN) + cnp->cn_flags |= SAVENAME; + + XFSDEB(XDEBVNOPS, ("xfs_lookup: error = %d\n", error)); + + return error; +} +#endif /* HAVE_VOP_LOOKUP */ + +#ifdef HAVE_VOP_CACHEDLOOKUP +static int +xfs_cachedlookup(struct vop_cachedlookup_args * ap) + /* struct vop_cachedlookup_args { + struct vnodeop_desc *a_desc; + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; +}; */ +{ + return xfs_lookup(ap); +} +#endif /* HAVE_VOP_CACHEDLOOKUP */ + +#ifdef HAVE_VOP_CREATE +static int +xfs_create(struct vop_create_args * ap) +{ + struct vnode *dvp = ap->a_dvp; + struct componentname *cnp = ap->a_cnp; + const char *name = cnp->cn_nameptr; + struct ucred *cred = cnp->cn_cred; + int error; + + error = xfs_create_common(dvp, + name, + ap->a_vap, + cred); + + if (error == 0) + error = xfs_lookup_name(dvp, name, xfs_cnp_to_proc(cnp), + cred, ap->a_vpp); + + if (error != 0 || (ap->a_cnp->cn_flags & SAVESTART) == 0) +#ifdef HAVE_KERNEL_ZFREEI + zfreei(namei_zone, ap->a_cnp->cn_pnbuf); +#else + free (ap->a_cnp->cn_pnbuf, M_NAMEI); +#endif + + XFSDEB(XDEBVNOPS, ("xfs_create: error = %d\n", error)); + + return error; +} +#endif /* HAVE_VOP_CREATE */ + +#ifdef HAVE_VOP_REMOVE +static int +xfs_remove(struct vop_remove_args * ap) + /* struct vnode *dvp, + struct vnode *vp, + struct componentname *cnp */ +{ + struct componentname *cnp = ap->a_cnp; + int error = xfs_remove_common(ap->a_dvp, ap->a_vp, cnp->cn_nameptr, + cnp->cn_cred); + + if (error != 0 || (cnp->cn_flags & SAVESTART) == 0) +#ifdef HAVE_KERNEL_ZFREEI + zfreei(namei_zone, cnp->cn_pnbuf); +#else + free (cnp->cn_pnbuf, M_NAMEI); +#endif + + return error; +} +#endif /* HAVE_VOP_REMOVE */ + +#ifdef HAVE_VOP_RENAME +static int +xfs_rename(struct vop_rename_args * ap) + /* vop_rename { + IN WILLRELE struct vnode *fdvp; + IN WILLRELE struct vnode *fvp; + IN struct componentname *fcnp; + IN WILLRELE struct vnode *tdvp; + IN WILLRELE struct vnode *tvp; + IN struct componentname *tcnp; + }; */ +{ + struct vnode *tdvp = ap->a_tdvp; + struct vnode *tvp = ap->a_tvp; + struct vnode *fdvp = ap->a_fdvp; + struct vnode *fvp = ap->a_fvp; + + int error = xfs_rename_common(fdvp, + fvp, + ap->a_fcnp->cn_nameptr, + tdvp, + tvp, + ap->a_tcnp->cn_nameptr, + ap->a_tcnp->cn_cred); + if(tdvp == tvp) + vrele(tdvp); + else + vput(tdvp); + if(tvp) + vput(tvp); + vrele(fdvp); + vrele(fvp); + return error; +} +#endif /* HAVE_VOP_RENAME */ + +#ifdef HAVE_VOP_MKDIR +static int +xfs_mkdir(struct vop_mkdir_args * ap) + /* struct vnode *dvp, + char *nm, + struct vattr *va, + struct vnode **vpp, + struct ucred *cred) */ +{ + struct vnode *dvp = ap->a_dvp; + struct componentname *cnp = ap->a_cnp; + const char *name = cnp->cn_nameptr; + struct ucred *cred = cnp->cn_cred; + int error; + + error = xfs_mkdir_common(dvp, + name, + ap->a_vap, + cred); + + if (error == 0) + error = xfs_lookup_name(dvp, name, xfs_cnp_to_proc(cnp), + cred, ap->a_vpp); + + if (error != 0 || (ap->a_cnp->cn_flags & SAVESTART) == 0) { +#ifdef HAVE_KERNEL_ZFREEI + zfreei(namei_zone, ap->a_cnp->cn_pnbuf); +#else + free (ap->a_cnp->cn_pnbuf, M_NAMEI); +#endif + } + +#if defined(__OpenBSD__) + vput(ap->a_dvp); +#endif + + XFSDEB(XDEBVNOPS, ("xfs_create: error = %d\n", error)); + + return error; +} +#endif /* HAVE_VOP_MKDIR */ + +#ifdef HAVE_VOP_RMDIR +static int +xfs_rmdir(struct vop_rmdir_args * ap) + /* struct vnode *dvp, + struct vnode *vp, + struct componentname *cnp */ +{ + struct componentname *cnp = ap->a_cnp; + int error = xfs_rmdir_common(ap->a_dvp, ap->a_vp, + cnp->cn_nameptr, cnp->cn_cred); + + if (error != 0 || (cnp->cn_flags & SAVESTART) == 0) +#ifdef HAVE_KERNEL_ZFREEI + zfreei(namei_zone, cnp->cn_pnbuf); +#else + free (cnp->cn_pnbuf, M_NAMEI); +#endif + + return error; +} +#endif /* HAVE_VOP_RMDIR */ + +#ifdef HAVE_VOP_READDIR +static int +xfs_readdir(struct vop_readdir_args * ap) + /* struct vnode *vp, + struct uio *uiop, + struct ucred *cred) */ +{ + int error; + off_t off; + + off = ap->a_uio->uio_offset; + + error = xfs_readdir_common(ap->a_vp, ap->a_uio, ap->a_cred, + ap->a_eofflag); + + if (!error && ap->a_ncookies != NULL) { + struct uio *uio = ap->a_uio; + struct dirent* dp; + int ncookies; +#if defined(__FreeBSD__) || defined (__OpenBSD__) + u_long *cookies; + struct dirent* dpStart; + struct dirent* dpEnd; + u_long *cookiep; +#else + off_t *cookies; + cookies = ap->a_cookies; + ncookies = ap->a_ncookies; +#endif + if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) + panic("xfs_readdir: mail arla-drinkers and tell them to bake burned cookies"); + dp = (struct dirent *) + (uio->uio_iov->iov_base - (uio->uio_offset - off)); +#if defined(__FreeBSD__) || defined (__OpenBSD__) + dpEnd = (struct dirent *) uio->uio_iov->iov_base; + for (dpStart = dp, ncookies = 0; + dp < dpEnd; + dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) + ncookies++; + MALLOC(cookies, u_long *, ncookies * sizeof(u_long), + M_TEMP, M_WAITOK); + for (dp = dpStart, cookiep = cookies; + dp < dpEnd; + dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) { + off += dp->d_reclen; + *cookiep++ = (u_int) off; + } + *ap->a_cookies = cookies; + *ap->a_ncookies = ncookies; +#else /* __NetBSD__ */ + while (ncookies-- && off < uio->uio_offset) { + if (dp->d_reclen == 0) + break; + off += dp->d_reclen; + *(cookies++) = off; + dp = (struct dirent *)((caddr_t)dp + dp->d_reclen); + } +#endif + } + return error; +} +#endif /* HAVE_VOP_READDIR */ + +#ifdef HAVE_VOP_LINK +static int +xfs_link(struct vop_link_args * ap) + /* + WILLRELE struct vnode *tdvp; + struct vnode *vp; + struct componentname *cnp; + */ +{ + struct componentname *cnp = ap->a_cnp; + int error = xfs_link_common( +#if defined (__OpenBSD__) || defined(__NetBSD__) + ap->a_dvp, +#elif defined(__FreeBSD__) + ap->a_tdvp, +#endif + ap->a_vp, + cnp->cn_nameptr, + cnp->cn_cred); + + if (error != 0 || (cnp->cn_flags & SAVESTART) == 0) +#ifdef HAVE_KERNEL_ZFREEI + zfreei(namei_zone, cnp->cn_pnbuf); +#else + free (cnp->cn_pnbuf, M_NAMEI); +#endif + + return error; +} +#endif /* HAVE_VOP_LINK */ + +#ifdef HAVE_VOP_SYMLINK +static int +xfs_symlink(struct vop_symlink_args * ap) + /* + IN WILLRELE struct vnode *dvp; + OUT WILLRELE struct vnode **vpp; + IN struct componentname *cnp; + IN struct vattr *vap; + IN char *target; + */ +{ + struct componentname *cnp = ap->a_cnp; + int error = xfs_symlink_common(ap->a_dvp, + ap->a_vpp, + cnp->cn_nameptr, + xfs_cnp_to_proc(cnp), + cnp->cn_cred, + ap->a_vap, + ap->a_target); + + if (error != 0 || (cnp->cn_flags & SAVESTART) == 0) { +#ifdef HAVE_KERNEL_ZFREEI + zfreei(namei_zone, cnp->cn_pnbuf); +#else + free (cnp->cn_pnbuf, M_NAMEI); +#endif + } + return error; +} +#endif /* HAVE_VOP_SYMLINK */ + + +#ifdef HAVE_VOP_READLINK +static int +xfs_readlink(struct vop_readlink_args * ap) + /* struct vnode *vp, + struct uio *uiop, + struct ucred *cred) */ +{ + return xfs_readlink_common(ap->a_vp, ap->a_uio, ap->a_cred); +} +#endif /* HAVE_VOP_READLINK */ + +#ifdef HAVE_VOP_INACTIVE +static int +xfs_inactive(struct vop_inactive_args * ap) + /*struct vnode *vp, + struct ucred *cred)*/ +{ +#if 0 + /* + * This break freebsd 2.2.x + */ + + return xfs_inactive_common(ap->a_vp, xfs_curproc()); +#else + return 0; +#endif +} +#endif /* HAVE_VOP_INACTICE */ + +#ifdef HAVE_VOP_RECLAIM +static int +xfs_reclaim(struct vop_reclaim_args * ap) + /*struct vop_reclaim_args { + struct vnodeop_desc *a_desc; + struct vnode *a_vp; +};*/ +{ + return xfs_reclaim_common(ap->a_vp); +} +#endif /* HAVE_VOP_RECLAIM */ + +/* + * The lock, unlock, islocked vnode operations. + * + * This should be done with the generic locking function for the + * appropriate dialect of BSD (vop_nolock, genfs_nolock, ...). But, + * most of these functions are commented out and don't work enough to + * allow xfs_islocked to figure if the vnode is locked or not, which + * other parts of the kernel depend on. + * + * We try do locking the folling way: + * If we have LK_INTERLOCK & co: + * Do no locking with (we should use lockmgr) + * else + * When VXLOCK is set loop + */ + +#ifdef HAVE_VOP_LOCK +static int +xfs_lock(struct vop_lock_args * ap) +{ + struct vnode *vp = ap->a_vp; + struct xfs_node *xn = VNODE_TO_XNODE(vp); + + XFSDEB(XDEBVNOPS, ("xfs_lock: %p, %d\n", vp, xn->vnlocks)); + +#if defined(HAVE_LK_INTERLOCK) && !defined(HAVE_ONE_ARGUMENT_VOP_LOCK) + { + int flags = ap->a_flags; + + if (flags & LK_INTERLOCK) + simple_unlock(&vp->v_interlock); + + if (!(flags & LK_TYPE_MASK)) + return 0; + } +#else + while (vp->v_flag & VXLOCK) { + vp->v_flag |= VXWANT; + (void) tsleep((caddr_t)vp, PINOD, "xfs_vnlock", 0); + } + if (vp->v_tag == VT_NON) + return (ENOENT); +#endif + ++xn->vnlocks; + return 0; +} +#endif /* HAVE_VOP_LOCK */ + +#ifdef HAVE_VOP_UNLOCK +static int +xfs_unlock(struct vop_unlock_args * ap) +{ + struct vnode *vp = ap->a_vp; + struct xfs_node *xn = VNODE_TO_XNODE(vp); + XFSDEB(XDEBVNOPS, ("xfs_unlock: %p, %d\n", vp, xn->vnlocks)); + +#if defined(HAVE_LK_INTERLOCK) && !defined(HAVE_ONE_ARGUMENT_VOP_LOCK) + { + int flags = ap->a_flags; + + if (flags & LK_INTERLOCK) + simple_unlock(&vp->v_interlock); + if (!(flags & LK_TYPE_MASK)) + return 0; + } +#endif + --xn->vnlocks; + if (xn->vnlocks < 0) { + printf ("PANIC: xfs_unlock: unlocking unlocked\n"); + xn->vnlocks = 0; + } + return 0; +} +#endif /* HAVE_VOP_UNLOCK */ + +#ifdef HAVE_VOP_ISLOCKED +static int +xfs_islocked (struct vop_islocked_args *ap) +{ + struct vnode *vp = ap->a_vp; + struct xfs_node *xn = VNODE_TO_XNODE(vp); + + XFSDEB(XDEBVNOPS, ("xfs_islocked: %p, %d\n", vp, xn->vnlocks)); + + return xn->vnlocks; +} +#endif /* HAVE_VOP_ISLOCKED */ + +#ifdef HAVE_VOP_ABORTOP +static int +xfs_abortop (struct vop_abortop_args *ap) + /* struct vnode *dvp; + struct componentname *cnp; */ +{ + struct componentname *cnp = ap->a_cnp; + + if ((cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF) +#ifdef HAVE_KERNEL_ZFREEI + zfreei(namei_zone, cnp->cn_pnbuf); +#else + FREE(cnp->cn_pnbuf, M_NAMEI); +#endif + return 0; +} +#endif /* HAVE_VOP_ABORTOP */ + +#ifdef HAVE_VOP_MMAP +static int +xfs_mmap(struct vop_mmap_args *ap) + /* + IN struct vnode *vp; + IN int fflags; + IN struct ucred *cred; + IN struct proc *p; + */ +{ + XFSDEB(XDEBVNOPS, ("xfs_mmap\n")); + return EOPNOTSUPP; +} +#endif /* HAVE_VOP_MMAP */ + +#ifdef HAVE_VOP_BMAP +static int +xfs_bmap(struct vop_bmap_args *ap) + /* IN struct vnode *vp; + IN daddr_t bn; + OUT struct vnode **vpp; + IN daddr_t *bnp; + OUT int *runp; + OUT int *runb; + */ +{ + XFSDEB(XDEBVNOPS, ("xfs_bmap\n")); + return EOPNOTSUPP; +} +#endif /* HAVE_VOP_BMAP */ + +#ifdef HAVE_VOP_GETPAGES +static int +xfs_getpages (struct vop_getpages_args *ap) + /* + IN struct vnode *vp; + IN vm_page_t *m; + IN int count; + IN int reqpage; + IN vm_ooffset_t offset; + */ +{ + int error; + + XFSDEB(XDEBVNOPS, ("xfs_getpages\n")); + +#if HAVE_KERNEL_VNODE_PAGER_GENERIC_GETPAGES + error = vnode_pager_generic_getpages (ap->a_vp, ap->a_m, + ap->a_count, ap->a_reqpage); +#else + error = EOPNOTSUPP; +#endif + XFSDEB(XDEBVNOPS, ("xfs_getpages = %d\n", error)); + return error; +} +#endif /* HAVE_VOP_GETPAGES */ + +#ifdef HAVE_VOP_PUTPAGES +static int +xfs_putpages (struct vop_putpages_args *ap) + /* + IN struct vnode *vp; + IN vm_page_t *m; + IN int count; + IN int sync; + IN int *rtvals; + IN vm_ooffset_t offset; + */ +{ + XFSDEB(XDEBVNOPS, ("xfs_putpages\n")); + +#if HAVE_KERNEL_VNODE_PAGER_GENERIC_PUTPAGES + return vnode_pager_generic_putpages (ap->a_vp, ap->a_m, ap->a_count, + ap->a_sync, ap->a_rtvals); +#else + return EOPNOTSUPP; +#endif +} +#endif /* HAVE_VOP_PUTPAGES */ + +#ifdef HAVE_VOP_CMP +static int +xfs_cmp(struct vnode * vp1, struct vnode * vp2) +{ + XFSDEB(XDEBVNOPS, ("xfs_cmp\n")); + return EOPNOTSUPP; +} +#endif /* HAVE_VOP_CMP */ + +#ifdef HAVE_VOP_REALVP +static int +xfs_realvp(struct vnode * vp, + struct vnode ** vpp) +{ + XFSDEB(XDEBVNOPS, ("xfs_realvp\n")); + return EOPNOTSUPP; +} +#endif /* HAVE_VOP_REALVP */ + +#ifdef HAVE_VOP_CNTL +static int +xfs_cntl(struct vnode * vp, + int cmd, + caddr_t idata, + caddr_t odata, + int iflag, + int oflag) +{ + XFSDEB(XDEBVNOPS, ("xfs_cntl\n")); + return EOPNOTSUPP; +} +#endif /* HAVE_VOP_CNTL */ + +#ifdef HAVE_VOP_PRINT +static int +xfs_print (struct vnode *vp) +{ + xfs_printnode_common (vp); + return 0; +} +#endif + +#if 0 +#ifdef HAVE_VOP_ADVLOCK +static int +xfs_advlock(void *v) +{ + struct vop_advlock_args /* { + struct vnode *a_vp; + caddr_t a_id; + int a_op; + struct flock *a_fl; + int a_flags; + } */ *ap = v; + + struct xfs_node *xn = VNODE_TO_XNODE(ap->a_vp); + int ret; + xfs_locktype_t locktype; + +/* if (XFS_TOKEN_GOT(xn, */ + +#if 0 + if (ap->a_fl.l_start != 0 || + ap->a_fl.l_end != 0) + printf ("WARN: someone is trying byte-range locking\n"); + + switch (ap->a_op) { + case F_SETLCK: + locktype = XFS_READLOCK; + break; + + ret = xfs_advlock_common (xn, ); + + return ret; +#else + return 0; +#endif +} +#endif /* HAVE_VOP_ADVOCK */ +#endif + +#ifdef HAVE_VOP_REVOKE +static int +xfs_revoke(void *v) +{ +#if defined(HAVE_KERNEL_GENFS_REVOKE) + return genfs_revoke (v); +#elif defined(HAVE_KERNEL_VOP_REVOKE) + return vop_revoke (v); +#else + return EOPNOTSUPP; +#endif +} +#endif /* HAVE_VOP_REVOKE */ + +vop_t **xfs_vnodeop_p; + +int +xfs_eopnotsupp (void *v) +{ + XFSDEB(XDEBVNOPS, ("xfs_eopnotsupp\n")); + return EOPNOTSUPP; +} + +int +xfs_returnzero (void *v) +{ + XFSDEB(XDEBVNOPS, ("xfs_returnzero\n")); + return 0; +} + +static struct vnodeopv_entry_desc xfs_vnodeop_entries[] = { + {&vop_default_desc, (vop_t *) xfs_eopnotsupp}, +#ifdef HAVE_VOP_LOOKUP +#ifdef HAVE_KERNEL_VFS_CACHE_LOOKUP + {&vop_lookup_desc, (vop_t *) vfs_cache_lookup }, +#else + {&vop_lookup_desc, (vop_t *) xfs_lookup }, +#endif +#endif +#ifdef HAVE_VOP_CACHEDLOOKUP + {&vop_cachedlookup_desc, (vop_t *) xfs_cachedlookup }, +#endif +#ifdef HAVE_VOP_OPEN + {&vop_open_desc, (vop_t *) xfs_open }, +#endif +#ifdef HAVE_VOP_FSYNC + {&vop_fsync_desc, (vop_t *) xfs_fsync }, +#endif +#ifdef HAVE_VOP_CLOSE + {&vop_close_desc, (vop_t *) xfs_close }, +#endif +#ifdef HAVE_VOP_READ + {&vop_read_desc, (vop_t *) xfs_read }, +#endif +#ifdef HAVE_VOP_WRITE + {&vop_write_desc, (vop_t *) xfs_write }, +#endif +#ifdef HAVE_VOP_MMAP + {&vop_mmap_desc, (vop_t *) xfs_mmap }, +#endif +#ifdef HAVE_VOP_BMAP + {&vop_bmap_desc, (vop_t *) xfs_bmap }, +#endif +#ifdef HAVE_VOP_IOCTL + {&vop_ioctl_desc, (vop_t *) xfs_ioctl }, +#endif +#ifdef HAVE_VOP_SELECT + {&vop_select_desc, (vop_t *) xfs_select }, +#endif +#ifdef HAVE_VOP_SEEK + {&vop_seek_desc, (vop_t *) xfs_seek }, +#endif +#ifdef HAVE_VOP_POLL + {&vop_poll_desc, (vop_t *) xfs_poll }, +#endif +#ifdef HAVE_VOP_GETATTR + {&vop_getattr_desc, (vop_t *) xfs_getattr }, +#endif +#ifdef HAVE_VOP_SETATTR + {&vop_setattr_desc, (vop_t *) xfs_setattr }, +#endif +#ifdef HAVE_VOP_ACCESS + {&vop_access_desc, (vop_t *) xfs_access }, +#endif +#ifdef HAVE_VOP_CREATE + {&vop_create_desc, (vop_t *) xfs_create }, +#endif +#ifdef HAVE_VOP_REMOVE + {&vop_remove_desc, (vop_t *) xfs_remove }, +#endif +#ifdef HAVE_VOP_LINK + {&vop_link_desc, (vop_t *) xfs_link }, +#endif +#ifdef HAVE_VOP_RENAME + {&vop_rename_desc, (vop_t *) xfs_rename }, +#endif +#ifdef HAVE_VOP_MKDIR + {&vop_mkdir_desc, (vop_t *) xfs_mkdir }, +#endif +#ifdef HAVE_VOP_RMDIR + {&vop_rmdir_desc, (vop_t *) xfs_rmdir }, +#endif +#ifdef HAVE_VOP_READDIR + {&vop_readdir_desc, (vop_t *) xfs_readdir }, +#endif +#ifdef HAVE_VOP_SYMLINK + {&vop_symlink_desc, (vop_t *) xfs_symlink }, +#endif +#ifdef HAVE_VOP_READLINK + {&vop_readlink_desc, (vop_t *) xfs_readlink }, +#endif +#ifdef HAVE_VOP_INACTIVE + {&vop_inactive_desc, (vop_t *) xfs_inactive }, +#endif +#ifdef HAVE_VOP_RECLAIM + {&vop_reclaim_desc, (vop_t *) xfs_reclaim }, +#endif +#ifdef HAVE_VOP_LOCK + {&vop_lock_desc, (vop_t *) xfs_lock }, +#endif +#ifdef HAVE_VOP_UNLOCK + {&vop_unlock_desc, (vop_t *) xfs_unlock }, +#endif +#ifdef HAVE_VOP_ISLOCKED + {&vop_islocked_desc, (vop_t *) xfs_islocked }, +#endif +#ifdef HAVE_VOP_ABORTOP + {&vop_abortop_desc, (vop_t *) xfs_abortop }, +#endif +#ifdef HAVE_VOP_GETPAGES + {&vop_getpages_desc, (vop_t *) xfs_getpages }, +#endif +#ifdef HAVE_VOP_PUTPAGES + {&vop_putpages_desc, (vop_t *) xfs_putpages }, +#endif +#ifdef HAVE_VOP_REVOKE + {&vop_revoke_desc, (vop_t *) xfs_revoke }, +#endif +#ifdef HAVE_VOP_PRINT + {&vop_print_desc, (vop_t *) xfs_print}, +#endif +#if 0 +#ifdef HAVE_VOP_ADVLOCK + {&vop_advlock_desc, (vop_t *) xfs_advlock }, +#endif +#endif + {(struct vnodeop_desc *) NULL, (int (*) (void *)) NULL} +}; + +struct vnodeopv_desc xfs_vnodeop_opv_desc = +{&xfs_vnodeop_p, xfs_vnodeop_entries}; + +#ifdef VNODEOP_SET +VNODEOP_SET(xfs_vnodeop_opv_desc); +#endif diff --git a/sys/xfs/xfs_vnodeops-common.c b/sys/xfs/xfs_vnodeops-common.c new file mode 100644 index 00000000000..fee9b17acc8 --- /dev/null +++ b/sys/xfs/xfs_vnodeops-common.c @@ -0,0 +1,948 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * XFS operations. + */ + +#include <xfs/xfs_locl.h> +#include <xfs/xfs_message.h> +#include <xfs/xfs_common.h> +#include <xfs/xfs_fs.h> +#include <xfs/xfs_dev.h> +#include <xfs/xfs_deb.h> +#include <xfs/xfs_syscalls.h> +#include <xfs/xfs_vnodeops.h> + +RCSID("$Id: xfs_vnodeops-common.c,v 1.1 1999/04/30 01:59:01 art Exp $"); + +int +xfs_open_valid(struct vnode * vp, struct ucred * cred, u_int tok) +{ + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + int error = 0; + + XFSDEB(XDEBVFOPS, ("xfs_open_valid\n")); + + do { + if (!XFS_TOKEN_GOT(xn, tok)) { + struct xfs_message_open msg; + + msg.header.opcode = XFS_MSG_OPEN; + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + msg.handle = xn->handle; + msg.tokens = tok; + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } else { + goto done; + } + } while (error == 0); + +done: + XFSDEB(XDEBVFOPS, ("xfs_open_valid: error = %d\n", error)); + + return error; +} + +int +xfs_attr_valid(struct vnode * vp, struct ucred * cred, u_int tok) +{ + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + int error = 0; + pag_t pag = xfs_get_pag(cred); + + do { + if (!XFS_TOKEN_GOT(xn, tok)) { + struct xfs_message_getattr msg; + + msg.header.opcode = XFS_MSG_GETATTR; + msg.cred.uid = cred->cr_uid; + msg.cred.pag = pag; + msg.handle = xn->handle; + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } else { + goto done; + } + } while (error == 0); + +done: + return error; +} + +int +xfs_fetch_rights(struct vnode * vp, struct ucred * cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + int error = 0; + + pag_t pag = xfs_get_pag(cred); + + do { + if (!xfs_has_pag(xn, pag)) { + struct xfs_message_getattr msg; + + msg.header.opcode = XFS_MSG_GETATTR; + msg.cred.uid = cred->cr_uid; + msg.cred.pag = pag; + msg.handle = xn->handle; + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } else { + goto done; + } + } while (error == 0); + +done: + + return error; +} + +int +xfs_data_valid(struct vnode * vp, struct ucred * cred, u_int tok) +{ + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + int error = 0; + + do { + if (!XFS_TOKEN_GOT(xn, tok)) { + struct xfs_message_getdata msg; + + msg.header.opcode = XFS_MSG_GETDATA; + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + msg.handle = xn->handle; + msg.tokens = tok; + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } else { + goto done; + } + } while (error == 0); + +done: + return error; +} + +static int +do_fsync(struct xfs * xfsp, + struct xfs_node * xn, + struct ucred * cred, + u_int flag) +{ + int error; + struct xfs_message_putdata msg; + + msg.header.opcode = XFS_MSG_PUTDATA; + if (cred != NOCRED) { + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + } else { + msg.cred.uid = 0; + msg.cred.pag = XFS_ANONYMOUSID; + } + msg.handle = xn->handle; + vattr2xfs_attr(&xn->attr, &msg.attr); + msg.flag = flag; + + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + + if (error == 0) + xn->flags &= ~XFS_DATA_DIRTY; + + return error; +} + +int +xfs_fsync_common(struct vnode *vp, struct ucred *cred, + int waitfor, struct proc *proc) +{ + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_fsync: %p\n", vp)); + + /* + * It seems that fsync is sometimes called after reclaiming a node. + * In that case we just look happy. + */ + + if (xn == NULL) { + printf("XFS PANIC WARNING! xfs_fsync called after reclaiming!\n"); + return 0; + } + + if (xn->flags & XFS_DATA_DIRTY) + error = do_fsync(xfsp, xn, cred, XFS_WRITE); + + return error; +} + +int +xfs_close_common(struct vnode *vp, int fflag, + struct proc *proc, struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_close cred = %p\n", cred)); + + if (fflag & FWRITE && xn->flags & XFS_DATA_DIRTY) + error = do_fsync(xfsp, xn, cred, XFS_WRITE); + + return error; +} + +int +xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) +{ + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_read\n")); + + error = xfs_data_valid(vp, cred, XFS_DATA_R); + + if (error == 0) { + struct vnode *t = DATA_FROM_VNODE(vp); + + xfs_vfs_readlock(t, xfs_uio_to_proc(uio)); +#ifdef __osf__ + VOP_READ(t, uio, ioflag, cred, error); +#else /* __osf__ */ + error = VOP_READ(t, uio, ioflag, cred); +#endif /* __osf__ */ + xfs_vfs_unlock(t, xfs_uio_to_proc(uio)); + } + return error; +} + +int +xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *cred) +{ + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_write\n")); + + error = xfs_data_valid(vp, cred, XFS_DATA_W); + + if (error == 0) { + struct xfs_node *xn = VNODE_TO_XNODE(vp); + struct vnode *t = DATA_FROM_XNODE(xn); + struct vattr sub_attr; + int error2 = 0; + + xfs_vfs_writelock(t, xfs_uio_to_proc(uiop)); +#ifdef __osf__ + VOP_WRITE(t, uiop, ioflag, cred, error); + VNODE_TO_XNODE(vp)->flags |= XFS_DATA_DIRTY; + VOP_GETATTR(t, &sub_attr, cred, error2); +#else /* __osf__ */ + error = VOP_WRITE(t, uiop, ioflag, cred); + VNODE_TO_XNODE(vp)->flags |= XFS_DATA_DIRTY; + error2 = VOP_GETATTR(t, &sub_attr, cred, uiop->uio_procp); +#endif /* __osf__ */ + + if (error2 == 0) { + xn->attr.va_size = sub_attr.va_size; + xn->attr.va_mtime = sub_attr.va_mtime; +#ifdef HAVE_KERNEL_VNODE_PAGER_SETSIZE + vnode_pager_setsize(vp, sub_attr.va_size); +#endif + } + xfs_vfs_unlock(t, xfs_uio_to_proc(uiop)); + } + + return error; +} + +int +xfs_getattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred) +{ + int error = 0; + + struct xfs_node *xn = VNODE_TO_XNODE(vp); + + XFSDEB(XDEBVNOPS, ("xfs_getattr\n")); + + error = xfs_attr_valid(vp, cred, XFS_ATTR_R); + if (error == 0) + *vap = xn->attr; + return error; +} + +int +xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_setattr\n")); + +#define CHECK_XFSATTR(A, cast) (vap->A == cast VNOVAL || vap->A == xn->attr.A) + if (CHECK_XFSATTR(va_mode,(mode_t)) && + CHECK_XFSATTR(va_nlink,) && + CHECK_XFSATTR(va_size,) && + CHECK_XFSATTR(va_uid,) && + CHECK_XFSATTR(va_gid,) && + CHECK_XFSATTR(va_mtime.tv_sec,) && + CHECK_XFSATTR(va_fileid,) && + CHECK_XFSATTR(va_type,)) + return 0; /* Nothing to do */ +#undef CHECK_XFSATTR + + if (XFS_TOKEN_GOT(xn, XFS_ATTR_W)) { + /* Update attributes and mark them dirty. */ + VNODE_TO_XNODE(vp)->flags |= XFS_ATTR_DIRTY; + error = EINVAL; /* XXX not yet implemented */ + goto done; + } else { + struct xfs_message_putattr msg; + + msg.header.opcode = XFS_MSG_PUTATTR; + if (cred != NOCRED) { + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + } else { + msg.cred.uid = 0; + msg.cred.pag = XFS_ANONYMOUSID; + } + msg.handle = xn->handle; + vattr2xfs_attr(vap, &msg.attr); + + XFS_TOKEN_CLEAR(xn, XFS_ATTR_VALID, XFS_ATTR_MASK); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } + +done: + return error; +} + +static int +check_rights (u_char rights, int mode) +{ + int error = 0; + + if (mode & VREAD) + if ((rights & XFS_RIGHT_R) == 0) + error = EACCES; + if (mode & VWRITE) + if ((rights & XFS_RIGHT_W) == 0) + error = EACCES; + if (mode & VEXEC) + if ((rights & XFS_RIGHT_X) == 0) + error = EACCES; + return error; +} + +int +xfs_access_common(struct vnode *vp, int mode, struct ucred *cred) +{ + int error = 0; + pag_t pag = xfs_get_pag(cred); + + XFSDEB(XDEBVNOPS, ("xfs_access mode = 0%o\n", mode)); + + error = xfs_attr_valid(vp, cred, XFS_ATTR_R); + if (error == 0) { + struct xfs_node *xn = VNODE_TO_XNODE(vp); + int i; + + error = check_rights (xn->anonrights, mode); + + if (error == 0) + goto done; + + XFSDEB(XDEBVNOPS, ("xfs_access anonaccess failed\n")); + + xfs_fetch_rights(vp, cred); /* ignore error */ + + error = EACCES; /* default to EACCES if pag isn't in xn->id */ + + for (i = 0; i < MAXRIGHTS; i++) + if (xn->id[i] == pag) { + error = check_rights (xn->rights[i], mode); + break; + } + } + +done: + XFSDEB(XDEBVNOPS, ("xfs_access(0%o) = %d\n", mode, error)); + + return error; +} + +int +xfs_lookup_common(struct vnode *dvp, + xfs_componentname *cnp, + struct vnode **vpp) +{ + struct xfs_message_getnode msg; + struct xfs *xfsp = XFS_FROM_VNODE(dvp); + struct xfs_node *d = VNODE_TO_XNODE(dvp); + int error = 0; + struct proc *proc = xfs_cnp_to_proc(cnp); + struct ucred *cred = xfs_proc_to_cred(proc); + + *vpp = NULL; + + if (dvp->v_type != VDIR) + return ENOTDIR; + + again: + + do { +#ifdef __osf__ + VOP_ACCESS(dvp, VEXEC, cred, error); +#else + error = VOP_ACCESS(dvp, VEXEC, cred, xfs_cnp_to_proc(cnp)); +#endif + if (error != 0) + goto done; + + error = xfs_dnlc_lookup(dvp, cnp, vpp); + if (error == 0) { + + /* + * Doesn't quite work. + */ + +#if 0 + if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) + && (cnp->cn_flags & ISLASTCN)) { + error = EJUSTRETURN; + goto done; + } +#endif + + msg.header.opcode = XFS_MSG_GETNODE; + if (cnp->cn_cred != NOCRED) { + msg.cred.uid = cnp->cn_cred->cr_uid; + msg.cred.pag = xfs_get_pag(cnp->cn_cred); + } else { + msg.cred.uid = 0; + msg.cred.pag = XFS_ANONYMOUSID; + } + msg.parent_handle = d->handle; + + bcopy(cnp->cn_nameptr, msg.name, cnp->cn_namelen); + msg.name[cnp->cn_namelen] = '\0'; + + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + if(error == ENOENT && cnp->cn_nameiop != CREATE) { + XFSDEB(XDEBVNOPS, ("xfs_lookup: neg cache %p (%s, %ld)\n", + dvp, + cnp->cn_nameptr, cnp->cn_namelen)); + xfs_dnlc_enter (dvp, cnp, NULL); + } + } else if (error == -1) { + if (xfs_do_vget(*vpp, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp))) + goto again; + error = 0; + goto done; + } + } while (error == 0); + +done: + return error; +} + +int +xfs_lookup_name(struct vnode *dvp, + const char *name, + struct proc *proc, + struct ucred *cred, + struct vnode **vpp) +{ + xfs_componentname cn; + + xfs_cnp_init (&cn, name, NULL, dvp, proc, cred, CREATE); + return xfs_lookup_common (dvp, &cn, vpp); +} + +int +xfs_create_common(struct vnode *dvp, + const char *name, + struct vattr *vap, + struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(dvp); + struct xfs_node *xn = VNODE_TO_XNODE(dvp); + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_create: (%s)\n", name)); + { + struct xfs_message_create msg; + + msg.header.opcode = XFS_MSG_CREATE; + msg.parent_handle = xn->handle; + strncpy(msg.name, name, 256); + vattr2xfs_attr(vap, &msg.attr); + + msg.mode = 0; /* XXX - mode */ + if (cred != NOCRED) { + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + } else { + msg.cred.uid = 0; + msg.cred.pag = XFS_ANONYMOUSID; + } + + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } + +#if 0 + if (error == EEXIST) + error = 0; +#endif + + return error; +} + +int +xfs_remove_common(struct vnode *dvp, + struct vnode *vp, + const char *name, + struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(dvp); + struct xfs_node *xn = VNODE_TO_XNODE(dvp); + struct xfs_message_remove msg; + int error; + + XFSDEB(XDEBVNOPS, ("xfs_remove: %s\n", name)); + + msg.header.opcode = XFS_MSG_REMOVE; + msg.parent_handle = xn->handle; + strncpy(msg.name, name, 256); + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) &msg)->error; + + if (error == 0) + xfs_dnlc_purge (vp); + +#if !defined(__FreeBSD__) || __FreeBSD_version < 300000 + if (dvp == vp) + vrele(vp); + else + vput(vp); + vput(dvp); +#endif + + return error; +} + +int +xfs_rename_common(struct vnode *fdvp, + struct vnode *fvp, + const char *fname, + struct vnode *tdvp, + struct vnode *tvp, + const char *tname, + struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(fdvp); + int error; + + XFSDEB(XDEBVNOPS, ("xfs_rename: %s %s\n", fname, tname)); + + if ((fvp->v_mount != tdvp->v_mount) + || (tvp && (fvp->v_mount != tvp->v_mount))) { + return EXDEV; + } + + { + struct xfs_message_rename msg; + + msg.header.opcode = XFS_MSG_RENAME; + msg.old_parent_handle = VNODE_TO_XNODE(fdvp)->handle; + strncpy(msg.old_name, fname, 256); + msg.new_parent_handle = VNODE_TO_XNODE(tdvp)->handle; + strncpy(msg.new_name, tname, 256); + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) &msg)->error; + + } + + XFSDEB(XDEBVNOPS, ("xfs_rename: error = %d\n", error)); + + return error; +} + +int +xfs_mkdir_common(struct vnode *dvp, + const char *name, + struct vattr *vap, + struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(dvp); + struct xfs_node *xn = VNODE_TO_XNODE(dvp); + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_mkdir: %s\n", name)); + { + struct xfs_message_mkdir msg; + + msg.header.opcode = XFS_MSG_MKDIR; + msg.parent_handle = xn->handle; + strncpy(msg.name, name, 256); + vattr2xfs_attr(vap, &msg.attr); + if (cred != NOCRED) { + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + } else { + msg.cred.uid = 0; + msg.cred.pag = XFS_ANONYMOUSID; + } + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } + + return error; +} + +int +xfs_rmdir_common(struct vnode *dvp, + struct vnode *vp, + const char *name, + struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(dvp); + struct xfs_node *xn = VNODE_TO_XNODE(dvp); + struct xfs_message_rmdir msg; + int error; + + XFSDEB(XDEBVNOPS, ("xfs_rmdir: %s\n", name)); + + msg.header.opcode = XFS_MSG_RMDIR; + msg.parent_handle = xn->handle; + strncpy(msg.name, name, 256); + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) &msg)->error; + + if (error == 0) + xfs_dnlc_purge (vp); + +#if !defined(__FreeBSD__) || __FreeBSD_version < 300000 + if (dvp == vp) + vrele(vp); + else + vput(vp); + vput(dvp); +#endif + + return error; +} + +int +xfs_readdir_common(struct vnode *vp, + struct uio *uiop, + struct ucred *cred, + int *eofflag) +{ + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_readdir\n")); + + if(eofflag) + *eofflag = 0; + error = xfs_data_valid(vp, cred, XFS_DATA_R); + if (error == 0) { + struct vnode *t = DATA_FROM_VNODE(vp); + + xfs_vfs_readlock(t, xfs_uio_to_proc(uiop)); +#ifdef __osf__ + VOP_READ(t, uiop, 0, cred, error); +#else + error = VOP_READ(t, uiop, 0, cred); +#endif + if(eofflag) + *eofflag = VNODE_TO_XNODE(vp)->attr.va_size <= uiop->uio_offset; + xfs_vfs_unlock(t, xfs_uio_to_proc(uiop)); + } + return error; +} + +int +xfs_link_common(struct vnode *dvp, + struct vnode *vp, + const char *name, + struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(dvp); + struct xfs_node *xn = VNODE_TO_XNODE(dvp); + struct xfs_node *xn2 = VNODE_TO_XNODE(vp); + struct xfs_message_link msg; + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_link: %s\n", name)); + + msg.header.opcode = XFS_MSG_LINK; + msg.parent_handle = xn->handle; + msg.from_handle = xn2->handle; + strncpy(msg.name, name, 256); + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + + return error; +} + +int +xfs_symlink_common(struct vnode *dvp, + struct vnode **vpp, + const char *name, + struct proc *proc, + struct ucred *cred, + struct vattr *vap, + char *target) +{ + struct xfs *xfsp = XFS_FROM_VNODE(dvp); + struct xfs_node *xn = VNODE_TO_XNODE(dvp); + struct xfs_message_symlink msg; + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_symlink: %s\n", name)); + + msg.header.opcode = XFS_MSG_SYMLINK; + msg.parent_handle = xn->handle; + strncpy(msg.name, name, sizeof(msg.name)); + msg.name[sizeof(msg.name) - 1] = '\0'; + vattr2xfs_attr(vap, &msg.attr); + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + strncpy (msg.contents, target, sizeof(msg.contents)); + msg.contents[sizeof(msg.contents) - 1] = '\0'; + + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + + if (error == 0) { + error = xfs_lookup_name(dvp, name, proc, cred, vpp); + if (error == 0) + vput (*vpp); + } + +#if !defined(__FreeBSD__) || __FreeBSD_version < 300000 + vput(dvp); +#endif + + return error; +} + +int +xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred) +{ + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_readlink\n")); + + error = xfs_data_valid(vp, cred, XFS_DATA_R); + if (error == 0) { + struct vnode *t = DATA_FROM_VNODE(vp); + + xfs_vfs_readlock(t, xfs_uio_to_proc(uiop)); +#ifdef __osf__ + VOP_READ(t, uiop, 0, cred, error); +#else + error = VOP_READ(t, uiop, 0, cred); +#endif + xfs_vfs_unlock(t, xfs_uio_to_proc(uiop)); + } + return error; +} + +int +xfs_inactive_common(struct vnode *vp, struct proc *p) +{ + struct xfs_message_inactivenode msg; + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + + XFSDEB(XDEBVNOPS, ("xfs_inactive, %p\n", vp)); + + /* + * This seems rather bogus, but sometimes we get an already + * cleaned node to be made inactive. Just ignoring it seems safe. + */ + + if (xn == NULL) { + XFSDEB(XDEBVNOPS, ("xfs_inactive: clean node\n")); + return 0; + } + + xn->tokens = 0; + msg.header.opcode = XFS_MSG_INACTIVENODE; + msg.handle = xn->handle; + msg.flag = XFS_NOREFS; + xfs_message_send(xfsp->fd, &msg.header, sizeof(msg)); + +#ifndef __osf__ + xfs_vfs_unlock(vp, p); +#else + /* XXX ? */ +#endif + + XFSDEB(XDEBVNOPS, ("return: xfs_inactive\n")); + + return 0; +} + +int +xfs_reclaim_common(struct vnode *vp) +{ + struct xfs_message_inactivenode msg; + struct xfs *xfsp = XFS_FROM_VNODE(vp); + struct xfs_node *xn = VNODE_TO_XNODE(vp); + + XFSDEB(XDEBVNOPS, ("xfs_reclaim: %p\n", vp)); + + msg.header.opcode = XFS_MSG_INACTIVENODE; + msg.handle = xn->handle; + msg.flag = XFS_NOREFS | XFS_DELETE; + xfs_message_send(xfsp->fd, &msg.header, sizeof(msg)); + + xfs_dnlc_purge(vp); + free_xfs_node(xn); + + return 0; +} + +/* + * + */ + +#if 0 + +int +xfs_advlock_common(struct vnode *dvp, + int locktype, + unsigned long lockid, /* XXX this good ? */ + struct ucred *cred) +{ + struct xfs *xfsp = XFS_FROM_VNODE(dvp); + struct xfs_node *xn = VNODE_TO_XNODE(dvp); + int error = 0; + + XFSDEB(XDEBVNOPS, ("xfs_advlock\n")); + { + struct xfs_message_advlock msg; + + msg.header.opcode = XFS_MSG_ADVLOCK; + msg.handle = xn->handle; + msg.locktype = locktype; + msg.lockid = lockid; + + if (cred != NOCRED) { + msg.cred.uid = cred->cr_uid; + msg.cred.pag = xfs_get_pag(cred); + } else { + msg.cred.uid = 0; + msg.cred.pag = XFS_ANONYMOUSID; + } + error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg)); + if (error == 0) + error = ((struct xfs_message_wakeup *) & msg)->error; + } + + if (error == 0) { + + /* sleep until woken */ + + } else { + + /* die */ + } + + return error; +} + +#endif + +/* + * + */ + +void +xfs_printnode_common (struct vnode *vp) +{ + struct xfs_node *xn = VNODE_TO_XNODE(vp); + + printf ("xnode: fid: %d.%d.%d.%d\n", + xn->handle.a, xn->handle.b, xn->handle.c, xn->handle.d); + printf ("\tattr: %svalid\n", + XFS_TOKEN_GOT(xn, XFS_ATTR_VALID) ? "": "in"); + printf ("\tdata: %svalid\n", + XFS_TOKEN_GOT(xn, XFS_DATA_VALID) ? "": "in"); + printf ("\tflags: 0x%x\n", xn->flags); +} diff --git a/sys/xfs/xfs_vnodeops.h b/sys/xfs/xfs_vnodeops.h new file mode 100644 index 00000000000..c608f6669b1 --- /dev/null +++ b/sys/xfs/xfs_vnodeops.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: xfs_vnodeops.h,v 1.1 1999/04/30 01:59:02 art Exp $ */ + +#ifndef _xfs_vnodeops_h +#define _xfs_vnodeops_h + +/* + * xfs_vfs_readlock + * xfs_vfs_writelock + * xfs_vfs_unlock + */ + +#ifdef __osf__ /* XXX - what about VN_LOCK? */ + +#define xfs_vfs_readlock(vp, proc) VREF((vp)) +#define xfs_vfs_writelock(vp, proc) VREF((vp)) +#define xfs_vfs_unlock(vp, proc) vrele((vp)) + +#elif defined(HAVE_TWO_ARGUMENT_VOP_LOCK) + +#define xfs_vfs_readlock(vp, proc) vn_lock((vp), LK_SHARED | LK_RETRY) +#define xfs_vfs_writelock(vp, proc) vn_lock((vp), LK_EXCLUSIVE | LK_RETRY) +#define xfs_vfs_unlock(vp, proc) VOP_UNLOCK((vp), 0) + +#elif defined(HAVE_THREE_ARGUMENT_VOP_LOCK) + +#define xfs_vfs_readlock(vp, proc) vn_lock((vp), LK_SHARED | LK_RETRY, (proc)) +#define xfs_vfs_writelock(vp, proc) vn_lock((vp), LK_EXCLUSIVE | LK_RETRY, (proc)) +#define xfs_vfs_unlock(vp, proc) VOP_UNLOCK((vp), 0, (proc)) + +#else + +#define xfs_vfs_readlock(vp, proc) VOP_LOCK((vp)) +#define xfs_vfs_writelock(vp, proc) VOP_LOCK((vp)) +#define xfs_vfs_unlock(vp, proc) VOP_UNLOCK((vp)) + +#endif + +int +xfs_open_valid(struct vnode * vp, struct ucred * cred, u_int tok); + +int +xfs_attr_valid(struct vnode * vp, struct ucred * cred, u_int tok); + +int +xfs_fetch_rights(struct vnode * vp, struct ucred * cred); + +int +xfs_data_valid(struct vnode * vp, struct ucred * cred, u_int tok); + +int +xfs_fsync_common(struct vnode *vp, struct ucred *cred, + int waitfor, struct proc *proc); + +int +xfs_close_common(struct vnode *vp, int fflag, + struct proc *proc, struct ucred *cred); + +int +xfs_read_common(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred); + +int +xfs_write_common(struct vnode *vp, struct uio *uiop, int ioflag, struct ucred *cred); + +int +xfs_getattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred); + +int +xfs_setattr_common(struct vnode *vp, struct vattr *vap, struct ucred *cred); + +int +xfs_access_common(struct vnode *vp, int mode, struct ucred *cred); + +int +xfs_lookup_common(struct vnode *dvp, + xfs_componentname *cnp, + struct vnode **vpp); + +int +xfs_lookup_name(struct vnode *dvp, + const char *name, + struct proc *proc, + struct ucred *cred, + struct vnode **vpp); + +int +xfs_create_common(struct vnode *dvp, + const char *name, + struct vattr *vap, + struct ucred *cred); + +int +xfs_remove_common(struct vnode *dvp, + struct vnode *vp, + const char *name, + struct ucred *cred); + +int +xfs_rename_common(struct vnode *fdvp, + struct vnode *fvp, + const char *fname, + struct vnode *tdvp, + struct vnode *tvp, + const char *tname, + struct ucred *cred); + +int +xfs_mkdir_common(struct vnode *dvp, + const char *name, + struct vattr *vap, + struct ucred *cred); + +int +xfs_rmdir_common(struct vnode *dvp, + struct vnode *vp, + const char *name, + struct ucred *cred); + +int +xfs_readdir_common(struct vnode *vp, + struct uio *uiop, + struct ucred *cred, + int *eofflag); + +int +xfs_link_common(struct vnode *dvp, + struct vnode *vp, + const char *name, + struct ucred *cred); + +int +xfs_symlink_common(struct vnode *dvp, + struct vnode **vpp, + const char *name, + struct proc *proc, + struct ucred *cred, + struct vattr *vap, + char *target); + +int +xfs_readlink_common(struct vnode *vp, struct uio *uiop, struct ucred *cred); + +int +xfs_inactive_common(struct vnode *vp, struct proc *p); + +int +xfs_reclaim_common(struct vnode *vp); + +int +xfs_eopnotsupp (void *); + +int +xfs_returnzero (void *v); + +void +xfs_printnode_common (struct vnode *vp); + +#endif /* _xfs_vnodeops_h */ diff --git a/sys/xfs/xfs_vopdefs.h b/sys/xfs/xfs_vopdefs.h new file mode 100644 index 00000000000..f0c3d2706ec --- /dev/null +++ b/sys/xfs/xfs_vopdefs.h @@ -0,0 +1,43 @@ +#define HAVE_VOP_ISLOCKED 1 +#define HAVE_VOP_LOOKUP 1 +#define HAVE_VOP_CREATE 1 +#define HAVE_VOP_MKNOD 1 +#define HAVE_VOP_OPEN 1 +#define HAVE_VOP_CLOSE 1 +#define HAVE_VOP_ACCESS 1 +#define HAVE_VOP_GETATTR 1 +#define HAVE_VOP_SETATTR 1 +#define HAVE_VOP_READ 1 +#define HAVE_VOP_WRITE 1 +#define HAVE_VOP_LEASE 1 +#define HAVE_VOP_IOCTL 1 +#define HAVE_VOP_SELECT 1 +#define HAVE_VOP_REVOKE 1 +#define HAVE_VOP_MMAP 1 +#define HAVE_VOP_FSYNC 1 +#define HAVE_VOP_SEEK 1 +#define HAVE_VOP_REMOVE 1 +#define HAVE_VOP_LINK 1 +#define HAVE_VOP_RENAME 1 +#define HAVE_VOP_MKDIR 1 +#define HAVE_VOP_RMDIR 1 +#define HAVE_VOP_SYMLINK 1 +#define HAVE_VOP_READDIR 1 +#define HAVE_VOP_READLINK 1 +#define HAVE_VOP_ABORTOP 1 +#define HAVE_VOP_INACTIVE 1 +#define HAVE_VOP_RECLAIM 1 +#define HAVE_VOP_LOCK 1 +#define HAVE_VOP_UNLOCK 1 +#define HAVE_VOP_BMAP 1 +#define HAVE_VOP_PRINT 1 +#define HAVE_VOP_PATHCONF 1 +#define HAVE_VOP_ADVLOCK 1 +#define HAVE_VOP_BLKATOFF 1 +#define HAVE_VOP_VALLOC 1 +#define HAVE_VOP_BALLOC 1 +#define HAVE_VOP_REALLOCBLKS 1 +#define HAVE_VOP_VFREE 1 +#define HAVE_VOP_TRUNCATE 1 +#define HAVE_VOP_UPDATE 1 +#define HAVE_VOP_WHITEOUT 1 diff --git a/usr.sbin/afs/Applflags.inc b/usr.sbin/afs/Applflags.inc index 1f678a846c7..96a20c36376 100644 --- a/usr.sbin/afs/Applflags.inc +++ b/usr.sbin/afs/Applflags.inc @@ -1,9 +1,9 @@ -LDADD += -lkrb -ldes ../libarla/libarla.a -ltermcap ../libroken/libroken.a -lreadline -lcurses -DPADD += ../libroken/libroken.a ../libarla/libarla.a ${LIBKRB} ${LIBDES} ${LIBREADLINE} ${LIBTERMCAP} ${LIBCURSES} +LDADD += -lkrb -ldes ../libarla/libarla.a -ltermcap ../libroken/libroken.a -lreadline -lcurses -lkafs +DPADD += ../libroken/libroken.a ../libarla/libarla.a ${LIBKRB} ${LIBDES} ${LIBREADLINE} ${LIBTERMCAP} ${LIBCURSES} ${LIBKAFS} CFLAGS += -I${.CURDIR}/../src/util -I${.CURDIR}/../src/lib/roken \ -I${.CURDIR}/../src/include -I${.CURDIR}/../libroken \ -I${.CURDIR}/../src/rxdef -I${.CURDIR}/../src/lwp -I../libarla \ -I${.CURDIR}/../src/arlad -I${.CURDIR}/../src \ -I${.CURDIR}/../src/lib/ko -I${.CURDIR}/../src/rxkad \ - -I${.CURDIR}/../src/lib/sl + -I${.CURDIR}/../src/lib/sl -I/usr/include/kerberosIV diff --git a/usr.sbin/afs/afsd/Makefile b/usr.sbin/afs/afsd/Makefile index 69731473967..55e2891486a 100644 --- a/usr.sbin/afs/afsd/Makefile +++ b/usr.sbin/afs/afsd/Makefile @@ -1,9 +1,10 @@ -# $OpenBSD: Makefile,v 1.1.1.1 1998/09/14 21:53:33 art Exp $ +# $OpenBSD: Makefile,v 1.2 1999/04/30 01:59:02 art Exp $ PROG = afsd MAN = afsd.8 BINDIR = /usr/libexec -SRCS = adir.c arla.c arladeb.c cmcb.c conn.c cred.c fbuf.c fcache.c \ - fprio.c inter.c kernel.c messages.c volcache.c bsd-subr.c +SRCS = adir.c arla.c arladeb.c cmcb.c conn.c cred.c darla.c discon_log.c \ + fbuf.c fcache.c fprio.c inter.c kernel.c messages.c reconnect.c \ + volcache.c bsd-subr.c .include "../Applflags.inc" diff --git a/usr.sbin/afs/fs/Makefile b/usr.sbin/afs/fs/Makefile index 0b1d0052549..9d881b09cd8 100644 --- a/usr.sbin/afs/fs/Makefile +++ b/usr.sbin/afs/fs/Makefile @@ -9,4 +9,8 @@ DPADD += ${LIBKAFS} .PATH: ${.CURDIR}/../src/appl +SRCS += arladeb.c + +.PATH: ${.CURDIR}/../src/arlad + .include <bsd.prog.mk>
\ No newline at end of file diff --git a/usr.sbin/afs/libarla/Makefile.ko.inc b/usr.sbin/afs/libarla/Makefile.ko.inc index 016822331f7..38d4d60fafb 100644 --- a/usr.sbin/afs/libarla/Makefile.ko.inc +++ b/usr.sbin/afs/libarla/Makefile.ko.inc @@ -1,7 +1,7 @@ ### ko stuff OS_VER != uname -r -SRCS += koerror.c kocell.c ports.c kodebug.c +SRCS += koerror.c kocell.c ports.c kodebug.c vlmisc.c SRCS += sysname.c CLEANFILES += sysname.c gensysname CFLAGS += -I${.CURDIR}/../src/lib/ko diff --git a/usr.sbin/afs/libarla/Makefile.lwp.inc b/usr.sbin/afs/libarla/Makefile.lwp.inc index 6f585eb538d..02e886fac1c 100644 --- a/usr.sbin/afs/libarla/Makefile.lwp.inc +++ b/usr.sbin/afs/libarla/Makefile.lwp.inc @@ -3,7 +3,7 @@ SRCS += lwp.c lock.c iomgr.c timer.c fasttime.c preempt.c q.c OBJS += process.o CLEANFILES += process.o .PATH: ${.CURDIR}/../src/lwp -CFLAGS += -DFD_SPEED_HACK -I${.CURDIR}/../src/lwp +CFLAGS += -DAFS_BSD_ENV -DFD_SPEED_HACK -I${.CURDIR}/../src/lwp process.o: process.S @@ -20,4 +20,4 @@ process.o: process.S *) echo "Unknown host_cpu, good luck" ;; \ esac; \ OSDEF="-DAFS_NETBSD_ENV"; \ - ${CC} $$CPUDEF $$OSDEF -c ${.CURDIR}/../src/lwp/process.S + ${CC} ${CFLAGS} $$CPUDEF $$OSDEF -c ${.CURDIR}/../src/lwp/process.S diff --git a/usr.sbin/afs/libarla/Makefile.rxdef.inc b/usr.sbin/afs/libarla/Makefile.rxdef.inc index 19f0629a524..1ec12ad1aba 100644 --- a/usr.sbin/afs/libarla/Makefile.rxdef.inc +++ b/usr.sbin/afs/libarla/Makefile.rxdef.inc @@ -11,7 +11,7 @@ CLEANFILES += vldb.ss.c vldb.cs.c vldb.ydr.c vldb.ss.h vldb.cs.h vldb.h \ volumeserver.ss.h volumeserver.cs.h volumeserver.h \ ubik.ss.c ubik.cs.c ubik.ydr.c ubik.cs.h ubik.ss.h ubik.h -CFLAGS += -I${.CURDIR}/../src/rxdef +CFLAGS += -I${.CURDIR}/../src/rxdef -I${.CURDIR}/../src/arlad YDR = ../ydr/ydr YDRFLAGS = -I${.CURDIR} diff --git a/usr.sbin/afs/libarla/Makefile.rxkad.inc b/usr.sbin/afs/libarla/Makefile.rxkad.inc index 372437aab5c..6cf8eab6e68 100644 --- a/usr.sbin/afs/libarla/Makefile.rxkad.inc +++ b/usr.sbin/afs/libarla/Makefile.rxkad.inc @@ -2,6 +2,6 @@ SRCS += rxk_locl.c rxk_clnt.c rxk_serv.c rxk_crpt.c rxk_info.c \ osi_alloc.c compat.c -CFLAGS += -I${.CURDIR}/../src/rxkad +CFLAGS += -I${.CURDIR}/../src/rxkad -I/usr/include/kerberosIV .PATH: ${.CURDIR}/../src/rxkad diff --git a/usr.sbin/afs/libroken/Makefile b/usr.sbin/afs/libroken/Makefile index 2d42d672906..4051303d1b0 100644 --- a/usr.sbin/afs/libroken/Makefile +++ b/usr.sbin/afs/libroken/Makefile @@ -1,13 +1,14 @@ -# $OpenBSD: Makefile,v 1.1.1.1 1998/09/14 21:53:31 art Exp $ +# $OpenBSD: Makefile,v 1.2 1999/04/30 01:59:03 art Exp $ LIB = roken # roken stuff -SRCS = base64.c getarg.c k_getpwuid.c k_getpwnam.c signal.o tm2time.c \ - verify.c inaddr2str.c mini_inetd.c get_window_size.c warnerr.c \ - snprintf.c resolve.c parse_units.c strnlen.c strtok_r.c strupr.c +SRCS = base64.c emalloc.c estrdup.c getarg.c k_getpwuid.c k_getpwnam.c \ + signal.o tm2time.c verify.c inaddr2str.c mini_inetd.c \ + get_window_size.c warnerr.c snprintf.c resolve.c parse_units.c \ + strnlen.c strtok_r.c strupr.c strlwr.c # util stuff -SRCS += atom.c date_rfc822.c efile.c fnameutil.c freelist.c hash.c ip.c \ - list.c log.c mem.c mmaptime.c prio.c strmatch.c strsplit.c \ - strutil.c timeprio.c timeval.c +SRCS += atom.c date_rfc822.c efile.c eefile.c fnameutil.c freelist.c \ + hash.c heap.c ip.c list.c log.c mmaptime.c strmatch.c \ + strsplit.c strutil.c timeval.c # sl stuff SRCS += sl.c CFLAGS += -DHAVE_CONFIG_H -I${.CURDIR}/../src/lib/roken \ diff --git a/usr.sbin/afs/libroken/config.h b/usr.sbin/afs/libroken/config.h index 30f2df67411..aa8a53346de 100644 --- a/usr.sbin/afs/libroken/config.h +++ b/usr.sbin/afs/libroken/config.h @@ -1,11 +1,11 @@ -/* $OpenBSD: config.h,v 1.1.1.1 1998/09/14 21:53:31 art Exp $ */ /* include/config.h. Generated automatically by configure. */ /* include/config.h.in. Generated automatically from configure.in by autoheader. */ -#ifndef BROKEN_MMAP /* Define if you have a working `mmap' system call. */ #define HAVE_MMAP 1 -#endif + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void @@ -16,6 +16,9 @@ /* Define if you can safely include both <sys/time.h> and <time.h>. */ #define TIME_WITH_SYS_TIME 1 +/* Define if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + /* Define this if we can include both sys/dir.h and dirent.h */ #define USE_SYS_DIR_H 1 @@ -25,6 +28,12 @@ /* Define this if struct winsize is declared in sys/termios.h */ #define HAVE_STRUCT_WINSIZE 1 +/* Define this if struct msghdr is declared in sys/socket.h */ +#define HAVE_STRUCT_MSGHDR 1 + +/* Define this if struct iovec is declared in sys/uio.h */ +#define HAVE_STRUCT_IOVEC 1 + /* Define this if struct winsize have ws_xpixel */ #define HAVE_WS_XPIXEL 1 @@ -35,7 +44,7 @@ #define SOCKADDR_HAS_SA_LEN 1 /* define if the system is missing a prototype for strtok_r() */ -#define NEED_STRTOK_R_PROTO 1 +/* #undef NEED_STRTOK_R_PROTO */ /* define if you have h_errno */ #define HAVE_H_ERRNO 1 @@ -73,6 +82,12 @@ /* Define if you have the FOUR_ARGUMENT_VFS_BUSY function. */ #define HAVE_FOUR_ARGUMENT_VFS_BUSY 1 +/* Define if you have the FOUR_ARGUMENT_VFS_OBJECT_CREATE function. */ +/* #undef HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE */ + +/* Define if you have the ONE_ARGUMENT_VOP_LOCK function. */ +/* #undef HAVE_ONE_ARGUMENT_VOP_LOCK */ + /* Define if you have the THREE_ARGUMENT_VFS_BUSY function. */ /* #undef HAVE_THREE_ARGUMENT_VFS_BUSY */ @@ -274,6 +289,9 @@ /* Define if you have the tgetent function. */ #define HAVE_TGETENT 1 +/* Define if you have the thr_yield function. */ +/* #undef HAVE_THR_YIELD */ + /* Define if you have the unsetenv function. */ #define HAVE_UNSETENV 1 @@ -322,11 +340,17 @@ /* Define if you have the <arpa/nameser.h> header file. */ #define HAVE_ARPA_NAMESER_H 1 +/* Define if you have the <asm/smp_lock.h> header file. */ +/* #undef HAVE_ASM_SMP_LOCK_H */ + +/* Define if you have the <asm/smplock.h> header file. */ +/* #undef HAVE_ASM_SMPLOCK_H */ + /* Define if you have the <crypt.h> header file. */ /* #undef HAVE_CRYPT_H */ /* Define if you have the <dbm.h> header file. */ -/* #undef HAVE_DBM_H */ +#define HAVE_DBM_H 1 /* Define if you have the <dirent.h> header file. */ #define HAVE_DIRENT_H 1 @@ -352,9 +376,24 @@ /* Define if you have the <libelf/nlist.h> header file. */ /* #undef HAVE_LIBELF_NLIST_H */ +/* Define if you have the <linux/devfs_fs.h> header file. */ +/* #undef HAVE_LINUX_DEVFS_FS_H */ + +/* Define if you have the <linux/modversions.h> header file. */ +/* #undef HAVE_LINUX_MODVERSIONS_H */ + /* Define if you have the <linux/types.h> header file. */ /* #undef HAVE_LINUX_TYPES_H */ +/* Define if you have the <machine/alpha/asm.h> header file. */ +/* #undef HAVE_MACHINE_ALPHA_ASM_H */ + +/* Define if you have the <machine/asm.h> header file. */ +#define HAVE_MACHINE_ASM_H 1 + +/* Define if you have the <machine/regdef.h> header file. */ +/* #undef HAVE_MACHINE_REGDEF_H */ + /* Define if you have the <miscfs/genfs/genfs.h> header file. */ /* #undef HAVE_MISCFS_GENFS_GENFS_H */ @@ -385,6 +424,9 @@ /* Define if you have the <pwd.h> header file. */ #define HAVE_PWD_H 1 +/* Define if you have the <regdef.h> header file. */ +/* #undef HAVE_REGDEF_H */ + /* Define if you have the <resolv.h> header file. */ #define HAVE_RESOLV_H 1 @@ -400,9 +442,6 @@ /* Define if you have the <sys/cdefs.h> header file. */ #define HAVE_SYS_CDEFS_H 1 -/* Define if you have the <sys/dirent.h> header file. */ -#define HAVE_SYS_DIRENT_H 1 - /* Define if you have the <sys/filedesc.h> header file. */ #define HAVE_SYS_FILEDESC_H 1 @@ -418,6 +457,9 @@ /* Define if you have the <sys/mman.h> header file. */ #define HAVE_SYS_MMAN_H 1 +/* Define if you have the <sys/module.h> header file. */ +/* #undef HAVE_SYS_MODULE_H */ + /* Define if you have the <sys/mount.h> header file. */ #define HAVE_SYS_MOUNT_H 1 @@ -448,6 +490,9 @@ /* Define if you have the <sys/stat.h> header file. */ #define HAVE_SYS_STAT_H 1 +/* Define if you have the <sys/syscallargs.h> header file. */ +#define HAVE_SYS_SYSCALLARGS_H 1 + /* Define if you have the <sys/sysconfig.h> header file. */ /* #undef HAVE_SYS_SYSCONFIG_H */ @@ -472,6 +517,12 @@ /* Define if you have the <sys/uio.h> header file. */ #define HAVE_SYS_UIO_H 1 +/* Define if you have the <sys/user.h> header file. */ +#define HAVE_SYS_USER_H 1 + +/* Define if you have the <sys/utsname.h> header file. */ +#define HAVE_SYS_UTSNAME_H 1 + /* Define if you have the <sys/vfs.h> header file. */ /* #undef HAVE_SYS_VFS_H */ @@ -484,6 +535,24 @@ /* Define if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 +/* Define if you have the <vm/vm.h> header file. */ +#define HAVE_VM_VM_H 1 + +/* Define if you have the <vm/vm_extern.h> header file. */ +#define HAVE_VM_VM_EXTERN_H 1 + +/* Define if you have the <vm/vm_object.h> header file. */ +#define HAVE_VM_VM_OBJECT_H 1 + +/* Define if you have the <vm/vm_pager.h> header file. */ +#define HAVE_VM_VM_PAGER_H 1 + +/* Define if you have the <vm/vm_zone.h> header file. */ +/* #undef HAVE_VM_VM_ZONE_H */ + +/* Define if you have the <vm/vnode_pager.h> header file. */ +#define HAVE_VM_VNODE_PAGER_H 1 + /* Define if you have the curses library (-lcurses). */ /* #undef HAVE_LIBCURSES */ @@ -533,6 +602,7 @@ #define HAVE_REGISTER_T 1 /* #undef HAVE_INT32 */ /* #undef HAVE_U_INT32 */ +/* #undef HAVE_INTPTR_T */ #define EFF_NTOHL ntohl @@ -540,7 +610,7 @@ #define RCSID(msg) \ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } -#define VERSION "0.9" +#define VERSION "0.24pre" #define PACKAGE "arla" /* Check for posix signals */ @@ -560,6 +630,10 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* We have krb_principal from kth-krb ? */ #define HAVE_KRB_PRINCIPAL 1 +/* Define if you have a krb_get_err_text (otherwise, you should really + get more modern kerberos code) */ +#define HAVE_KRB_GET_ERR_TEXT 1 + /* If we have _res */ /* #undef HAVE__RES */ @@ -575,6 +649,15 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your kernel has a vop_noislocked */ /* #undef HAVE_KERNEL_VOP_NOISLOCKED */ +/* Define if your kernel has a vop_stdnolock */ +/* #undef HAVE_KERNEL_VOP_STDLOCK */ + +/* Define if your kernel has a vop_stdnounlock */ +/* #undef HAVE_KERNEL_VOP_STDUNLOCK */ + +/* Define if your kernel has a vop_stdnoislocked */ +/* #undef HAVE_KERNEL_VOP_STDISLOCKED */ + /* Define if your kernel has a vop_revoke */ /* #undef HAVE_KERNEL_VOP_REVOKE */ @@ -590,17 +673,50 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your kernel has a genfs_revoke */ /* #undef HAVE_KERNEL_GENFS_REVOKE */ +/* Define if your kernel has a vfs_opv_init */ +#define HAVE_KERNEL_VFS_OPV_INIT 1 + /* Define if your kernel has a vfs_opv_init_default */ #define HAVE_KERNEL_VFS_OPV_INIT_DEFAULT 1 +/* Define if your kernel has a vfs_opv_init_explicit */ +#define HAVE_KERNEL_VFS_OPV_INIT_EXPLICIT 1 + +/* Define if your kernel has a vfs_add_vnodeops */ +/* #undef HAVE_KERNEL_VFS_ADD_VNODEOPS */ + /* Define if your kernel has a vfs_attach */ /* #undef HAVE_KERNEL_VFS_ATTACH */ +/* Define if your kernel has a vfs_register */ +#define HAVE_KERNEL_VFS_REGISTER 1 + /* Define if your kernel has a vfs_getnewfsid */ #define HAVE_KERNEL_VFS_GETNEWFSID 1 -/* Define if your kernel has a vfs_opv_init_explicit */ -#define HAVE_KERNEL_VFS_OPV_INIT_EXPLICIT 1 +/* Define if your kernel has a vfs_getvfs */ +#define HAVE_KERNEL_VFS_GETVFS 1 + +/* Define if your kernel has a vfs_object_create */ +/* #undef HAVE_KERNEL_VFS_OBJECT_CREATE */ + +/* Define if your kernel has a zfreei */ +/* #undef HAVE_KERNEL_ZFREEI */ + +/* Define if your kernel has a vfs_cache_lookup */ +/* #undef HAVE_KERNEL_VFS_CACHE_LOOKUP */ + +/* Define if your kernel has a vnode_pager_generic_putpages */ +/* #undef HAVE_KERNEL_VNODE_PAGER_GENERIC_PUTPAGES */ + +/* Define if your kernel has a vnode_pager_generic_getpages */ +/* #undef HAVE_KERNEL_VNODE_PAGER_GENERIC_GETPAGES */ + +/* Define if your kernel has a vnode_pager_setsize */ +#define HAVE_KERNEL_VNODE_PAGER_SETSIZE 1 + +/* Define if your kernel has a doforce */ +#define HAVE_KERNEL_DOFORCE 1 /* Define if your struct dirent has a field d_type */ #define HAVE_STRUCT_DIRENT_D_TYPE 1 @@ -608,8 +724,11 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your struct vfsconf has a field vfc_refcount */ #define HAVE_STRUCT_VFSCONF_VFC_REFCOUNT 1 +/* Define if your struct vfsconf has a field vfc_mountroot */ +/* #undef HAVE_STRUCT_VFSCONF_VFC_MOUNTROOT */ + /* Define if your struct uio has a field uio_procp */ -/* #undef HAVE_STRUCT_UIO_UIO_PROCP */ +#define HAVE_STRUCT_UIO_UIO_PROCP 1 /* Define if your struct vfsops has a field vfs_opv_descs */ /* #undef HAVE_STRUCT_VFSOPS_VFS_OPV_DESCS */ @@ -617,6 +736,15 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your struct vfsops has a field vfs_name */ /* #undef HAVE_STRUCT_VFSOPS_VFS_NAME */ +/* Define if your struct vfsops has a field vfs_oid */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_OID */ + +/* Define if your struct vfsops has a field vfs_checkexp */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */ + +/* Define if your struct vfsops has a field vfs_uninit */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_UNINIT */ + /* Define if you want to use mmap:ed time */ /* #undef USE_MMAPTIME */ @@ -626,6 +754,9 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your hstrerror need proto */ /* #undef NEED_HSTRERROR_PROTO */ +/* define if the system is missing a prototype for inet_aton() */ +/* #undef NEED_INET_ATON_PROTO */ + /* Define if you have gnu libc */ /* #undef HAVE_GLIBC */ @@ -648,12 +779,68 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* #undef HAVE_LINUX_KERNEL_U_INT32_T */ /* #undef HAVE_LINUX_KERNEL_U_INT64_T */ +/* Define this if you have a struct new_stat */ +/* #undef HAVE_STRUCT_NEW_STAT */ + /* Define this if you have a type vop_t */ /* #undef HAVE_VOP_T */ /* Define this is you have a vfssw */ /* #undef HAVE_VFSSW */ +/* Define this if struct mount have mnt_syncer */ +#define HAVE_STRUCT_MOUNT_MNT_SYNCER 1 + /* Define this if struct proc have p_sigmask */ #define HAVE_STRUCT_PROC_P_SIGMASK 1 +/* Define this if you have struct a_flags instead of a_waitfor in vop_fseek*/ +/* #undef HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS */ + +/* Define this if struct proc have p_retval */ +/* #undef HAVE_STRUCT_PROC_P_RETVAL */ + +/* Define this if struct file_operations has flush */ +/* #undef HAVE_STRUCT_FILE_OPERATIONS_FLUSH */ + +/* Define this if the read_super superoperation takes the dir_d argument */ +/* #undef HAVE_READ_SUPER_FOUR_ARGS */ + +/* Define this if the follow_link inode-operation takes the follow argument */ +/* #undef HAVE_FOLLOW_LINK_THREE_ARGS */ + +/* Define this if your full_name_hash works with 8bit characters */ +/* #undef HAVE_FULL_NAME_HASH_8BIT */ + +/* Define if your getvfsbyname takes two arguments */ +/* #undef HAVE_GETVFSBYNAME_TWO_ARGS */ + +/* Define if you have DIRSIZ in <dirent.h> */ +/* #undef DIRSIZ_IN_DIRENT_H */ + +/* Define if you have DIRSIZ in <sys/dir.h> */ +#define DIRSIZ_IN_SYS_DIR_H 1 + +/* Define if you have GENERIC_DIRENT in <sys/dirent.h> */ +/* #undef GENERIC_DIRSIZ_IN_SYS_DIRENT_H */ + +/* Define if running on Irix 6.4 or later */ +/* #undef IRIX_64 */ + +/* + * Defintions that are ugly but needed to get all the symbols used + */ + +/* + * Defining this enables lots of useful (and used) extensions on + * glibc-based systems such as Linux + */ + +#define _GNU_SOURCE + +/* + * Defining this enables us to get the definition of `sigset_t' and + * other importatnt definitions on Solaris. + */ + +#define __EXTENSIONS__ diff --git a/usr.sbin/afs/libroken/version.h b/usr.sbin/afs/libroken/version.h index eda2502f5fd..bce23be694a 100644 --- a/usr.sbin/afs/libroken/version.h +++ b/usr.sbin/afs/libroken/version.h @@ -1,3 +1,2 @@ -/* $OpenBSD: version.h,v 1.1.1.1 1998/09/14 21:53:31 art Exp $ */ -char *arla_long_version = "arla-0.9 on "ARLACPU"-"ARLAVENDOR"-"ARLAOS; -char *arla_version = "arla-0.9"; +char *arla_long_version = "@(#)$Version: arla-0.24pre by art on kurrent.stacken.kth.se (sparc-unknown-openbsd2.5) Wed Apr 28 18:54:29 MEST 1999 $"; +char *arla_version = "arla-0.24pre"; diff --git a/usr.sbin/afs/src/ChangeLog b/usr.sbin/afs/src/ChangeLog index 80a48ee8064..90d50531f2f 100644 --- a/usr.sbin/afs/src/ChangeLog +++ b/usr.sbin/afs/src/ChangeLog @@ -1,3 +1,2586 @@ +1999-04-12 Assar Westerlund <assar@sics.se> + + * arlad/Makefile.in (LDFLAGS): set + + * configure.in: LDFLAGS: substitute + +1999-04-06 Love <lha@s3.kth.se> + + * arlad/messages.c (viocsetvolstat): Do not change volumename, + motd or offlinemsg + + * arlad/fcache.c (fcache_get): Added check if we missed + volume. Note that we should really either nuke the entry or check + for e->volume == NULL everywhere. + +1999-03-29 Love <lha@s3.kth.se> + + * arlad/messages.c (try_again) If we don't have EDQUOT use ENOSPC + +1999-03-28 Robert Burgess <rb@stacken.kth.se> + + * Release 0.23 + +Sat Mar 27 05:16:49 1999 Assar Westerlund <assar@sics.se> + + * arlad/messages.c (vioc_get_cellstatus): reverse issuid test + + * configure.in (freebsd[34]): build KLD if kernel is ELF + + * xfs/bsd/xfs_syscalls-wrap-osf.c (rename sys_xfspioctl -> + xfspioctl) + + * xfs/bsd/xfs_syscalls-wrap-freebsd.c (rename sys_xfspioctl -> + xfspioctl) + + * xfs/bsd/xfs_syscalls-wrap-bsd.c (rename sys_xfspioctl -> + xfspioctl) + + * xfs/bsd/xfs_syscalls-common.c (rename sys_xfspioctl -> + xfspioctl) + + * xfs/bsd/xfs/xfs_syscalls.h (rename sys_xfspioctl -> xfspioctl) + +1999-03-27 Robert Burgess <rb@stacken.kth.se> + + * Removed Solaris umount_xfs (the umount command that comes with + Solaris works better) + + * xfs/solaris/xfs_syscalls.c (fhopen_call): Changed in_size check + +Wed Mar 24 23:31:09 1999 Assar Westerlund <assar@sics.se> + + * arlad/arla.c: always do fork_late + +1999-03-20 Love <lha@s3.kth.se> + + * xfs/bsd/xfs/xfs_node.h: Added test for LK_SHARED + + * xfs/bsd/xfs_message.c (xfs_message_installnode): lock node when + doing vget + (xfs_message_installdata): lock node when doing vget + + +1999-03-19 Love <lha@s3.kth.se> + + * Snapshot 1999-03-19 + + * arlad/volcache.h (volume_make_uptodate): new function + + * arlad/volcache.c (volume_make_uptodate): new function + + * arlad/messages.c (try_again): ARLA_VMOVED and ARLA_VNOVOL + invalidates volcache + (*): new useage of try_again() + + * arlad/fcache.c (find_first_fs): make sure the volume is uptodate + (try_next_fs): ARLA_VMOVED and ARLA_VNOVOL are errornous and will break + the search for next fileserver (they mean that we should update + our vldb info) + + * lib/ko/koerror.c: Added <rx/rx.h>, <fs_errors.h> and fileserver + converted errors. + + * arlad/messages.c (viocflushvolume): when flushing the volume, + flush the volume from the volcache at the same time + + * ydr/parse.y: use create_type + + * ydr/types.c (create_type): New function + + * xfs/bsd/xfs/xfs_node.h: If LK_EXCLUSIVE isn't defined make sure + we define it to 1, its used for compat with old vget() that + doesn't use lockmgr locking-style + + * xfs/bsd/xfs_vfsops-common.c (xfs_root_common): return a locked + vnode + + * xfs/bsd/xfs_message.c: (xfs_message_install{node,root}): do + vrele() instead of vput() since we never locks the vnode in the + vget + + * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common): Get a lock on + when returning it + +1999-03-16 Love <lha@s3.kth.se> + + * include/Makefile.in: Break out generated headers and files that + comes with the dist + +Sun Mar 14 20:03:10 1999 Assar Westerlund <assar@sics.se> + + * appl/vos_local.h: update prototypes + + * appl/vos_listvldb.c (vos_listvldb_iter): complain if + find_db_cell_and_host fails + + * appl/vos_examine.c (printvolstat): complain if + find_db_cell_and_host fails + + * appl/vos_common.c (get_vlentry): write a comment to make Magnus + happy. assume host != NULL. + (new_vlentry): check and complain if find_db_cell_and_host fails + (find_db_cell_and_host): comment and remove casts + + * rxkad/rxk_clnt.c (client_GetResponse): handle versions >= + RXKAD_VERSION and always generate a version 2 response + +1999-03-12 Love <lha@s3.kth.se> + + * Snapshot 1999-03-12 + + * ydr/parse.y: (TPOINTER): set symbol to NULL + + * arlad/fcache.c (find_first_fs): set num_conns to 0 for + DISCONNECTED case + (do_read_attr): check if disconnected and have bits + +1999-03-11 Love <lha@s3.kth.se> + + * arlad/fcache.c (setacl): flush bits in kernel to make it + update acl + +1999-03-10 Assar Westerlund <assar@sics.se> + + * rxdef/*.xg: include <config.h> and <roken.h>. They are needed + when building with !gcc + + * xfs/bsd/xfs/xfs_vfsops.h (xfs_fhopen): correct prototype + + * xfs/bsd/xfs/xfs_syscalls.h (xfs_pioctl_call): correct prototype + + * xfs/bsd/xfs_syscalls-common.c (lookup_node): printf format fix + +1999-03-06 Love <lha@s3.kth.se> + + * appl/vos_syncsite.c (vos_syncsite): Added arguments (-cell and + -no-resolve) + + * rxdef/volumeserver.xg (AFSVolCreateVolume): name is string + + * appl/vos_local.h: Added prototypes + + * appl/vos_listvldb.c (vos_listvldb_iter): use + find_db_cell_and_host + + * appl/vos_examine.c (vos_examine): use find_db_cell_and_host + + * appl/vos_common.c (getvolumetype): document + (new_vlentry): New function + (find_db_cell_and_host): new function + + * appl/fs.c(apropos_cmd): use sl apropos + + * appl/Makefile.in: Added vos_createvolume.c vos_endtrans.c to vos + + * appl/vos_{createvolume,endtrans}.c: New files + +Thu Mar 4 02:40:46 1999 Assar Westerlund <assar@sics.se> + + * appl/vos_listvldb.c (vos_listvldb_iter): const-ify + + * appl/vos_examine.c (printvolstat): use get_vlentry + + * appl/vos_common.c (get_vlentry): use arlalib_authflags_t + + * appl/vos_common.c (get_vlentry): new function + + * appl/vos_dump.c: new file + + * ydr/types.c (define_struct): handle already declared structures + (set_struct_body_sym): new function + + * ydr/parse.y: handle forward declaration of struct and redundant + struct keywords + + * ydr/output.c (generating_multi): fix macro call code + + * ydr/lex.l: match the final newline on the #line-lines from cpp + so that we don't increment the lineno when we should not. + + * ydr: patches from Derrick J Brashear <shadow@dementia.org> for + generating rx-multi macros + +1999-03-04 Love <lha@s3.kth.se> + + * appl/*: started to use arlalib_getauthflag arlalib_authflags_t + for unified -noauth and -local + + * appl/vos_listvldb.c: New file + + * appl/vos_local.h: Added prototypes for vos_listvldb() and + vos_listvldb_iter() + + * appl/vos.c (cmds): added listvldb + + * appl/Makefile.in (vos): vos_listvldb + +Thu Mar 4 02:40:46 1999 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vfsops-netbsd.c (xfs_vfsops): add vfs_checkexp + conditionally + + * configure.in: check for vfsops.vfs_checkexp + + * rx/rx_pkt.c (rxi_ReadPacket): ignore errors from recvmsg + silently. + (osi_NetSend): sendmsg can return ECONNREFUSED on linux. ignore it. + + * rx/rx_user.c (rxi_GetUDPSocket): set SO_BSDCOMPAT. clean-up + + * include/Makefile.in (install): install stds.h + +Wed Mar 3 13:10:15 1999 Marcus Sundberg <mackan@stacken.kth.se> + + * xfs/linux/getcwd.c: removed redundant fcntl.h so it works on glibc 2.1 + +Wed Mar 3 00:49:00 1999 Marcus Sundberg <mackan@stacken.kth.se> + + * configure.in, xfs/linux/xfs_load.c, xfs/linux/xfs/xfs_locl.h: + Linux devfs support + +Tue Mar 2 08:50:27 1999 Assar Westerlund <assar@sics.se> + + * rxdef/*.xg: more RPCs + + * rx/Makefile.in (install): install header files + + * lwp/Makefile.in (install): install include files from srcdir + + * lib/ko/Makefile.in: add vlmisc + + * arlad/volcache.c (vldb2vldbN): move to vlmisc.c + (get_info_loop): less warnings + + * appl/arlalib.c: let all the functions take a cell argument + + * appl/appl_locl.h: add rx header files + + * appl/Makefile.in: vos: re-organize + + * lib/ko/vlmisc.c: new file + + * lib/acl/Makefile.in (INCLUDES): use include directory in srcdir + (Makefile): add + * appl/vos.c: clean-up + + * ydr/output.c (print_varray): correct code + (init_generate): let all the files include the appropriate header + files + (print_type): make `string<>' generate `char *' + (encode_string): allocate memory dynamically with string<> + + * arlad/volcache.c (recycle_entry): don't assume that num_ptr and + name_ptr are parallel + (add_clone): add a parameter for the suffix_type + (get_info_common): if there's no read-write volume, add the read-only + volume with the vanilla name + + * arlad/fcache.c (find_first_fs): do not believe volumeId[type] to + be valid + (find_volume): more paranoid checks for if the volumes really exist. + + * arlad/conn.c (pinger): re-structure the code + + * rx/rx_user.c (rxi_getUDPSocket): remove code for looping around + bind and for checking the port number + + * rx/Makefile.in (install): install headers + + * lwp/Makefile.in (install): install headers + +Sun Feb 28 00:44:51 1999 Assar Westerlund <assar@sics.se> + + * ydr/output.c (init_generate): add inclusion of foo.{s,c}s.h in + foo.{c,s}s.c + (generate_server_stub): use prefix when writing the prototype. + + * configure.in: freebsd34: nuke DIAGNOSTIC test + + * xfs/bsd/xfs_vnodeops-bsd.c: call zfreei instead of zfree + + * ydr/output.c: always generate includs for atypes.h and rx.h in + stubs + + * ydr/main.c (main): return an error if parse_errors is true. + + * ydr/lex.l: recognize `proc' + (error_message): set a flag when an error has occured. + + * ydr/lex.h (error_message): update prototype + + * ydr/parse.y: add prefix + + * ydr/lex.l: add prefix + + * lwp/Makefile.in (install): install lwp.h + + * ydr/Makefile.in (install): install ydr + + * ydr/output.c (generating): remove roken.h and arlad/fs_errors.h + + * rxdef/*.xg: arlad/fs_errors.h -> fs_errors.h + + * lwp/Makefile.in (clean): remove test programs. + + * include/Makefile.in: install some headers + + * ydr/parse.y (param_type): default to IN + (memberdecl2): handle string without size + +Sat Feb 27 20:11:28 1999 Johan Danielsson <joda@blubb.pdc.kth.se> + + * xfs/bsd/xfs_dev-common.c (xfs_uprintf_device): don't print junk + +Sat Feb 27 12:01:35 1999 Assar Westerlund <assar@sics.se> + + * util/eefile.c, util/eefile.h: new files + + * ydr: Install patches from Derrick J Brashear + <shadow@dementia.org> for running several instances simultaneously. + +1999-02-26 Love <lha@s3.kth.se> + + * xfs/bsd/xfs_vnodeops-common.c: (xfs_rename_common): Don't remove + "tname". Arlad changes the fid if it exist (linux does this today) + + * configure.in: welcome back test for mnt_syncer + + * xfs/bsd/xfs_node-bsd.c: (free_all_xfs_nodes): check if we don't + unmount and then skip mnt_syncer + + * xfs/bsd/xfs_node-osf.c: (free_all_xfs_nodes): third dummy + argument + + * xfs/bsd/xfs_dev-common.c (xfs_devclose_common): pass on to + free_all_xfs_nodes that we dont unmount + + * xfs/bsd/xfs_vfsops-common.c (xfs_unmount_common): pass on to + free_all_xfs_nodes that we unmount + +1999-02-25 Love <lha@s3.kth.se> + + * arlad/messages.c (xfs_message_rename): flush new dir from DNLC + cache + +1999-02-22 Love <lha@s3.kth.se> + + * xfs/bsd/xfs_dev-common.c:(xfs_devclose_common): Removed dead + mnt_syncer code. + + * acconfig.h: HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_fseek): + HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS + + * configure.in: check for vop_fsync_args.a_flags + + * Release 0.22 + + * arlad/fs_errors.h: catch VRESTARTING + + * arlad/messages.c: catch VRESTARTING. + + * xfs/bsd/bin/startarla.in: test for kld + +Sun Feb 21 04:31:22 1999 Magnus Ahltorp <map@stacken.kth.se> + + * xfs/linux/xfs_message.c (xfs_message_installnode): Try a + requested entry first, then try any entry. Delete old alias from + alias chain before adding it. + +Sat Feb 13 02:32:37 1999 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_syscalls-common.c (sys_xfspioctl): use + `xfs_proc_to_cred' + + * util/Makefile.in: add heaptest + (check): new target + + * util/heaptest.c, util/util-tester.c: improve batchability a + little bit + + * util/Makefile.in (libutil_SRCS, libutil_OBJS): removed prio and + timeprio + + * util/prio.[ch], util/timeprio.[ch]: removed + + * util/mem.[ch]: removed. + + * xfs/linux/getcwd.c: handle both `struct stat' and `struct + new_stat' + + * acconfig.h (HAVE_STRUCT_NEW_STAT): add + + * configure.in: remove old BSD kernel functions not being called + any longer. test for `struct new_stat' for linux + + * xfs/linux/getcwd.c: handle the case without getcwd + + * xfs/linux/getcwd.c: try to get the current directory by any of + these ways: + a. the getcwd syscall + b. /proc/self/cwd (only on 2.1) + c. by tracing the directory structure backwards and comparing + inode numbers + + also make sure that buf == NULL works everywhere + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock): re-organize + the code so that we handle the case of there not being any flag + argument (with one argument vop_lock) + + * xfs/bsd/xfs/xfs_vnodeops.h (xfs_fsync_common, xfs_close_common): + update prototypes + + * xfs/bsd/xfs_vnodeops-common.c (xfs_fsync_common, + xfs_close_common): add `proc' argument + + * xfs/bsd/xfs_vnodeops-osf.c (xfs_fsync, xfs_close): adapt to + changing *-common functions + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_fsync, xfs_close): adapt to + changing *-common functions + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked): + re-introduce counted locking but only when flags & LK_TYPE_MASK, + otherwise the assymetry comes back to bite us. + + * xfs/bsd/Makefile.in (unload): add support for kld + + * configure.in (freebsd): generate vnode_if.[ch] and -I. to be + able to find them + +Sat Feb 6 03:22:56 1999 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs/xfs_vnodeops.h (xfs_fsync_common, xfs_close_common): + update prototypes + + * xfs/bsd/xfs_vnodeops-common.c (xfs_fsync_common, + xfs_close_common): add `proc' argument + + * xfs/bsd/xfs_vnodeops-osf.c (xfs_fsync, xfs_close): adapt to + changing *-common functions + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_fsync, xfs_close): adapt to + changing *-common functions + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked): + re-introduce counted locking but only when flags & LK_TYPE_MASK, + otherwise the assymetry comes back to bite us. + + * xfs/bsd/Makefile.in (unload): add support for kld + + * configure.in (freebsd): generate vnode_if.[ch] and -I. to be + able to find them + + * xfs/bsd/xfs_syscalls-common.c (xfs_debug): move the super-user + test to the setting of the debug level. I don't quite remember + why I did this but I can see no harm in letting any user find out + the current debug level? + + * tests/run-tests.in: add --help + + * arlad/volcache.c (vldb2vldbN): constize and only copy the safe + number of servers + + * arlad/fcache.c: remove old code + + * arlad/inter.c: always set Result.error to make things simpler. + +1999-02-05 Love <lha@s3.kth.se> + + * arlad/volcache.c (vldb2vldbN): Added bounce checking + (get_info_loop): dont loop if old serve returns RXGEN_OPCODE + +1999-02-05 Love <lha@s3.kth.se> + + * arlad/volcache.c (vldb2vldbN): New function + (get_info_loop): Added fallback-code for old server + + * arlad/volcache.c (ConnCacheEntry): Added field flags.old + + * arlad/conn.c (new_connection): reset flags.old + + * arlad/arla_local.h: Added rxgencon.h + + * appl/fs.c (connect_cmd): return 0; + (newcell_cmd): rewrote and started to use getarg + (getmaxfprio): return 0 + + * arlad/messages.c (viocgetwscell): len strlen(cellname)+1 as + suggested by Chuck Lever <cel@monkey.org> + +Mon Feb 1 05:53:52 1999 Assar Westerlund <assar@sics.se> + + * lwp/plwp.c: include config.h + (LWP_CreateProcess): call thr_yield if there's one + (Create_Process_Part2): fix call to pthread_attr_setstacksize + + * acconfig.h: define __EXTENSIONS__ to make solaris' header files + happy. + + * configure.in: check for thr_yield + + * lwp/plwp.[ch]: new files with lwp-over-pthreads + + * lwp/rw.c: new file with test code + + * lwp/preempt.h: more prototypes + + * lwp/Makefile.in: support building with lwp-over-pthreads + + * include/Makefile.in (lwp.h): link in the correct file for + LWP/pthreads + + * appl/Makefile.in: handle linking with pthreads + + * arlad/Makefile.in: handle linking with pthreads + + * INSTALL: document --with-pthreads + + * configure.in (--with-pthreads): add code from Derrick J Brashear + <shadow@dementia.org> for using pthreads + +Sun Jan 31 20:48:57 1999 Assar Westerlund <assar@sics.se> + + * configure.in (irix): always add -DR4000 to cflags, otherwise it + seems to break. + + * xfs/irix/xfs/xfs_syscalls.h: use correct include files + + * xfs/irix/xfs/xfs_node.h: port to Irix 6.4 + + * xfs/irix/xfs/xfs_fs.h: port to Irix 6.4 + + * xfs/irix/xfs_vnodeops.c: port to Irix 6.4 + + * xfs/irix/xfs_vfsops.c: port to Irix 6.4 + + * xfs/irix/xfs_syscalls.c: use `curprocp' instead of `u'. that + makes it work under 6.4 as well + + * xfs/irix/xfs_node.c: port to Irix 6.4 + + * xfs/irix/xfs_message.c (xfs_message_installdata): VOP_LOOKUP is + called differently under irix 6.4 + + * xfs/irix/Makefile.in (LDFLAGS): always add -32 + (MOD): write in current directory and not source directory + + * configure.in (irix): correct and portabilize irix6.4-test + + * xfs/solaris/xfs_vnodeops.c (xfs_map): always cast len to + unsigned long in the debug output + + * xfs/bsd/xfs_vfsops-osf.c (xfs_root): send both proc and cred to + xfs_root_common + + * configure.in (irix): define IRIX_64 if running on Irix 6.4 or + above. + + * tests/dir-size-mismatch: use find | xargs rm to remove the + files, it was overflowing the argument size. + + * xfs/solaris/xfs/xfs_dev.h (intptr_t): define if there's none + + * acconfig.h (HAVE_INTPTR_T): add + + * configure.in: bump version to 0.22pre remove duplicate test for + syslog test for `intptr_t' + +Sun Jan 31 17:51:34 1999 Assar Westerlund <assar@sics.se> + + * Release 0.21 + + * configure.in (freebsd34): add -I. to kernel flags to find the + generated vnode_if.h + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked): + more debug output + +Sat Jan 30 17:42:00 1999 Assar Westerlund <assar@sics.se> + + * tests/copy-and-diff-gnu-mirror: use correct fd. From Simon + Josefsson <jas@pdc.kth.se> + +1999-01-28 Love <lha@s3.kth.se> + + * arlad/arla.c(arla_cp): Added copy command. + +1999-01-24 Love <lha@s3.kth.se> + + * conf/Makefile.in(install): Install a empty SuidCells if there is no. + + * tests/run-tests.in: Print out that the test FAILED while running + + * xfs/bsd/Makefile.in: (xfs_vopdefs.h): Make the link even if + 'mkdir xfs' fails, and test if xfs is a dir + + * configure.in (freebsd[34]*) Add support for freebsd4, default to + kld on freebsd4, add output from test + +Tue Jan 19 20:31:50 1999 Assar Westerlund <assar@sics.se> + + * configure.in (irix): check for IP and cpu and add them to + KERNEL_CFLAGS + + * xfs/irix/Makefile.in: use KERNEL_CFLAGS for figuring out CPU and + such + +Sat Jan 16 18:55:17 1999 Love <lha@stacken.kth.se> + + * configure.in: check if VOP_LOCK takes one argument (NetBSD1.3.x) + + * xfs/bsd/xfs_vnodeops-bsd.c: Check if VOP_LOCK takes one argument + +Tue Jan 12 01:16:12 1999 Assar Westerlund <assar@sics.se> + + * xfs/include/xfs/xfs_message.h (CACHEHANDLESIZE): bump to 80 + (needed on Solaris 7 in 64bit mode) + + * lwp/process.S: add even more ifdef's to handle sparc v9 + + * lwp/make-process.o.sh.in: use CC and AS from environment. + remove foo.c when we're done. + + * lwp/lwp.c (REGSIZE): on a sparc v9 the registers are also 8 + bytes + + * lwp/lwp.h (lwp_context): try to use the correct amount for sparc + v9 + + * rx/rx_user.c (rxi_Listener): use `rx_maxSocketNumber' when + selecting to avoid having to send the rather large FD_SETSIZE + + * rx/rx_pkt.h (rx_GetLong, rx_PutLong): use `u_int32_t' instead of + `long' + + * tests/build-gdb: change path for gdb. + + * tests/build-emacs: change path for emacs. GNU has reorganized + their ftp server and moved all programs into subdirectories. + +Sun Jan 10 07:25:51 1999 Assar Westerlund <assar@sics.se> + + * arlad/fprio.c (fprio_readin): don't print a warning if the file + cannot be opened. + + * xfs/linux/xfs_dev.c (xfs_message_rpc): also check for strange + positive return values. + + * xfs/bsd/xfs_wrap-bsd.c (SYSCALL_MODULE): replace index with + pointer + (xfs_load): update prototype + + * xfs/bsd/xfs_vfsops-bsd.c (vfs_object_create): use the correct + number of arguments + + * INSTALL (--enable-kld): add + + * configure.in (freebsd3): change test for kernel object format + (vfs_object_create): add test for number of arguments + + * xfs/bsd/xfs_vfsops-freebsd.c: preliminary support for syscall + KLD module + + * xfs/bsd/xfs/xfs_vfsops.h (xfs_root_common): update prototype + + * xfs/bsd/xfs_vfsops-common.c (xfs_root_common): take a `proc' as + argument. call vget instead of vref. + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_root): call new style + xfs_root_common update comments + + * xfs/bsd/xfs_syscalls-freebsd.c: preliminary support for syscall + KLD module + + * xfs/bsd/xfs_wrap-bsd.c: preliminary support for syscall KLD + module + + * arlad/messages.c (CELLSTATUS_{PRIMARY,SETUID}): use defines + (vioc_gcpags): implement no-op + + * arlad/inter.c (cm_getattr): real_fid is always set. + + * appl/fs_lib.c (fs_gcpags): send in a correct (and empty) params + structure + + * appl/fs.c (gc_cmd): correct argc and string in printf + (all): add XDEBNODE + + * configure.in (freebsd): use sysctl to get the name of the kernel + reorder the include files in the kernel compilation tests, it was + failing on FreeBSD-current + +1999-01-05 Magnus Ahltorp <map@stacken.kth.se> + + * xfs/linux/xfs_vfsops.c: Do xfs_d_init() when building too to + prevent dangling pointers + + * xfs/linux/xfs_message.c: Hopefully more correct invalidation of + dentries + +Tue Jan 5 00:07:51 1999 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vfsops-openbsd.c (vfs_register, vfs_unregister): + define and use + + * include/kafs.h: add cell status flags + +1999-01-03 Love <lha@s3.kth.se> + + * arlad/fcache.c + (throw_entry,fcache_reobtain_callbacks,fcache_giveup_all_callbacks): + if the fileserver is `down' don't give up callbacks + + * xfs/bsd/xfs_node-bsd.c (xfs_getnewvnode): Set field vnlock to 0 + (new_xfs_node): Use HAVE_LK_INTERLOCK + + * xfs/include/xfs/xfs_message.h: XFS_MSG_ADVLOCK confusion + + * xfs/bsd/xfs/xfs_node.h: Added locks confusion + + * lib/ko/kocell.c: Implement clue-code for + cell_{is,set}suid{,by_{num,name}} and $SYSCONFDIR/SuidCells + + * lib/ko/ko.h (cell_issuid): new function + (cell_issuid_by_name): new function + (cell_issuid_by_num): new function + (cell_setsuid_by_num): new function + (struct cell_entry): Added field suid_cell + + * arlad/messages.c: added rpc messages advlock + (vioc_get_cellsstatus): implement + (vioc_get_cells): implement + + * appl/fs_local.h: afs_listcells() + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_invalid): dummyify since is + break free 2.2.x + (xfs_print): write + (xfs_advlock): comment out comfusing code + + * arlad/fcache.c (update_entry): suid-flags cleaner + + * appl/fs.c:suidcells: New command, show all cells with suid cells + marked. afs_listcells(): Rewritten + + + * appl/fs_lib.c: fs_getcells(): New function fs_getcellstatus(): + New function + + * appl/alralib.c(hfs_getcells): New function fs_getcellstatus(): + New function + + * xfs/bsd/xfs_vfsops-freebsd.c(xfs_init (<3.0)): reset ptr's + (vfs_register): set ptr before calling function + + * conf/CellServDB(stacken.kth.se): dog.stacken.kth.se -> + fishburger.stacken.kth.se + +1999-01-03 Assar Westerlund <assar@sics.se> + + * arlad/reconnect.c: add some more O_BINARY + + * arlad/messages.c: add some more O_BINARY + + * arlad/fcache.c: add some more O_BINARY + + * util/date_rfc822.c (date_time2rfc822): update from rfc822 to + rfc1123 section 5.2.14 + + * rx/rx_pkt.h (RX_FIRSTBUFFERSIZE): always define it to 1468 + (RX_CBUFFERSIZE): always define it to 1024 + + * xfs/bsd/xfs_syscalls-freebsd.c: use `sysent' instead of + `aout_sysvec' + +1999-01-02 Magnus Ahltorp <map@stacken.kth.se> + + * Changed getcwd.so to libgetcwd.so. + +Thu Dec 31 12:13:10 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_enter): actually set nameiop to + CREATE. (when did this disappear?) + +Thu Dec 31 13:04:23 1998 Assar Westerlund <assar@sics.se> + + * arlad/volcache.c (volcache_getbyid): use correct hash table + + * arlad/volcache.c (recycle_entry): don't clear entire entry + (volcache_getbyname, volcache_getbyname): restructure + + * xfs/linux/xfs_message.c (xfs_message_installnode): nuke benign + warning + +Wed Dec 30 11:56:04 1998 Assar Westerlund <assar@sics.se> + + * tests/untar-emacs: esthetically corect on fd 3 + + * configure.in (freebsd3): always try to guess the kernel object + format, also print it out to give the user the change to see if + the guess was wrong. also, warn when building LKMs with a !aout + kernel (maybe we should just switch to KLDs in that case). + + * arlad/volcache.c (recycle_entry): hopefully work around + refcount-bug + +Tue Dec 29 03:01:57 1998 Assar Westerlund <assar@sics.se> + + * tests/generic-build: get rid of warning messages from tar + + * configure.in (full_name_hash): more politically correct test. + + * configure.in: --with-sys: actually use the value. + + * arlad/messages.c (vioc_afs_sysname): send 4 bytes length and + then string + * appl/fs_lib.c (fs_get_sysname): change to expect 4 bytes before + sysname string + + * arlad/arla.c (krb_get_err_text): fallback version. Should + probably be somewhere else. kroken? + + * configure.in: test for krb_get_err_text + + * configure.in: HAVE_BROKEN_FULL_NAME_HASH -> + HAVE_FULL_NAME_HASH_8BIT + + * xfs/linux/xfs/xfs_locl.h: conditionalize on replacing + full_name_hash + + * configure.in: test for broken full_name_hash + +1998-12-28 Love <lha@s3.kth.se> + + * xfs/bsd/bin/Makefile.in(startarla): Build startarla via + startarla.new as suggested by Ken Raeburn <raeburn@raeburn.org> + + * rx/Makefile.in(INCLUDE): typo, fix by Ken Raeburn + <raeburn@raeburn.org> + + * Snapshot 0.21pre + +Mon Dec 28 01:16:36 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vfsops-freebsd.c (xfs_init): kludge that might make + it work with kld modules + + * aclocal.m4: KERNEL_CFLAGS -> test_KERNEL_CFLAGS + + * configure.in: support for building kld modules. more tests + + * xfs/bsd/Makefile.in: support building a kld module + + * xfs/bsd/xfs_vfsops-freebsd.c (xfs_init): try with + vfs_add_vnodeops + + * xfs/bsd/xfs_vfsops-netbsd.c (xfs_init): vfs_opv_init depending + on NetBSD-version + + * configure.in: check for vfs_opv_init include <sys/module.h> in + some tests + + * xfs/bsd/xfs_wrap-bsd.c: update and conditionalize KLD_MODULE + + * arlad/messages.c (all_powerful_p): new function. use it. + (vioc_afs_sysname): fix reading of sysname + + * configure.in: new files to test for + (freebsd3): try to make kld work + + * xfs/bsd/xfs_vfsops-netbsd.c: try without having a special vfs + for xfs dead vnodes + + * xfs/bsd/xfs_vfsops-netbsd.c: HAVE_VFS_ATTACH -> + HAVE_KERNEL_VFS_ATTACH + + * xfs/bsd/xfs_vfsops-freebsd.c (xfs_stat_filesys): add + + * xfs/bsd/xfs_vfsops-openbsd.c (xfs_stat_filesys): add + + * xfs/bsd/xfs_vfsops-netbsd.c (xfs_stat_filesys): add + (xfs_install_filesys): try xfs first + (xfs_uninstall_filesys): dito + + * xfs/bsd/xfs_wrap-bsd.c (xfs_unload): try unloading filesystem + first + (xfs_may_unload): remove + + * xfs/bsd/xfs_vfsops-netbsd.c (vfs_attach): check for vfs_init + being NULL + + * include/Makefile.in (HEADERS): add heap.h + + * util/heap.c, util/heap.h: new files + + * util/Makefile.in: add heap.[ch] + + * arlad/fcache.c (add_to_invalidate): go backwards + + * util/list.h (listhead, listtail, listprev, listnext, listdata, + listemptyp, listnextp): made into inline functions + + * arlad/inter.c (cm_close): don't overwrite the error code. + + * arlad/fcache.c (fcache_update_length): assert against usedbytes + wrapping around + + * arlad/fcache.c (create_file, create_directory): don't touch + dir_entry->status.Length + + * arlad/fcache.c (create_symlink): update usedbytes + + * INSTALL: linux: add map's warning message about updating + getcwd.so + + * arlad/reconnect.c (reconnect_putdata): adapt to new semantics of + copyfd2rx + + * arlad/fcache.c (read_data): adapt to new semantics of copyrx2fd + and copyfd2rx + + * arlad/fbuf.c: *_copyfd2rx, *_copyrx2fd: don't close the fd some + comments + + * arlad/fcache.c: assert that all closes are succesful. + + * arlad/adir.c: assert that all closes are succesful. + +1998-12-24 Robert Burgess <rb@stacken.kth.se> + + * Release 0.20 + +1998-12-23 Assar Westerlund <assar@sics.se> + + * xfs/linux/getcwd.c (getcwd): If we fail with ENOSYS, fall back + on the old getcwd. From <allbery@ece.cmu.edu> + + * lib/ko/kocell.c (newcell): no dbnum + (readcellservdb): init dbnum + + * arlad/messages.c (vioc_new_cell): new function + (vioc_get_cell): fix bugs + + * lib/ko/ko.h: sync with kocell.c + + * lib/ko/kocell.c: re-organize and write some new functions + + * appl/fs.c: newcell: implement + + * appl/fs_lib.c (fs_newcell): implement + + * xfs/bsd/xfs_vfsops.c: move all xfs initialization code into + xfs_vfsops-*bsd.c + + * configure.in (*bsd): use xfs_vfsops-*bsd.c + +1998-12-22 Love <lha@s3.kth.se> + + * */*/*: Moved xfs's include files to xfs/ + +1998-12-21 Assar Westerlund <assar@sics.se> + + * arlad/cred.c (print_cred): print uid correctly + + * arlad/fcache.c (find_next_fs): made global + (*): hopefully use try_next_fs properly + +Sun Dec 20 17:52:17 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_message.c (xfs_message_installnode): vget and vput + the parent node to prevent it from being recycled + (xfs_message_installdata): vget and vput the vnode. + + * xfs/bsd/xfs_vnodeops-common.c (xfs_symlink_common): vput the + just created symlink... + + * arlad/messages.c (try_again): also translate error codes + (*): realfid always contains the correct fid + + * arlad/fcache.c (try_next_fs): some more error codes + + * arlad/fs_errors.h: add some more error codes + + * arlad/fs_errors.h (VNOVOL, ARLA_VNOVOL): add + + * arlad/fcache.c (findconn): remove + (try_next_fs): figure out if it's worth trying the next fs from the + error code. call it. + (fcache_get): always set realfid + +1998-12-19 Magnus Ahltorp <map@stacken.kth.se> + + * xfs/linux/xfs_inodeops.c: Prevent xfs_lookup from returning + errno values below -1000 in 2.1 kernels. They would otherwise be + dereferenced in other parts of the kernel. + + * arlad/fcache.c: Check for rw flag when looking for backup volume + + * arlad/reconnect.c: Use find_first_fs instead of find_conn + +Sat Dec 19 01:34:23 1998 Assar Westerlund <assar@sics.se> + + * appl/fs.c: move around some more + (apropos_cmd): implement + + * conf/CellServDB (transarc.com): updated cell entry + + * arlad/volcache.c (get_info_loop): call VL_GetEntryByNameN + instead of VL_GetEntryByName + + * arlad/fs_errors.h (conv_to_arla_errno): add unused. this also + requires <roken.h> + + * arlad/fcache.c (fs_server_context): MAXNSERVERS -> NMAXNSERVERS + + * arlad/volcache.h (volcacheentry): use nvldbentry + +1998-12-16 Magnus Ahltorp <map@stacken.kth.se> + + * xfs/linux/bin/startarla.in: start arlad with -z switch + +1998-12-15 Assar Westerlund <assar@sics.se> + + * Release 0.19 + + * xfs/solaris/xfs_dev.c (xfs_message_rpc): bzero the xfs_link's. + why is this necessary? + + * xfs/solaris/xfs_node.c (xfs_dnlc_enter): handle the case of no + NC_NAMLEN + + * xfs/solaris/xfs_syscalls.c (xfs_debug): new function + (xfs_pioctl_call): call xfs_debug + + * xfs/irix/xfs_dev.c (xfs_message_wakeup_data): fix call to + MUTEX_LOCK + + * arlad/fcache.c (find_next_fs): simplify + (free_fs_server_context): simplify + + * tests: introduce and use AFSROOT + + * arlad/fcache.c (find_first_fs): only sort valid entries. + estimate rtt:s before sorting. + * arlad/volcache.c (get_info_loop): only sort valid entries. + estimate rtt:s before sorting. + * arlad/conn.c (conn_rtt_cmp): don't handle NULL pointers + + * arlad/conn.h (conncacheentry): add rtt + (RTT_FUZZ): add + +1998-12-14 Love <lha@s3.kth.se> + + * xfs/unknown/xfs_deb.h: dummy + +Sun Dec 13 10:55:10 1998 Assar Westerlund <assar@sics.se> + + * Release 0.18 + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked): + add a large comment describing the sad state of affairs and remove + all commented out code from the functions + + * ydr/parse.y: add syntax: error-function <function> + + * configure.in (AC_C_INLINE): test for + + * arlad/fcache.c (find_first_fs, find_next_fs): update to sort + filservers by rtt (+ random fuzz) + (free_fs_server_context): new function + + * arlad/volcache.c (get_info_loop): get all db-servers and sort + them by rtt + random fuzz. + + * arlad/conn.c (conn_rtt_cmp): comparison function for rtt of two + entries. adds a random fuzz to load balance. + + * arlad/conn.h (conn_rtt_cmp): function for comparing two entries + for rtt + +Sun Dec 13 10:47:21 1998 Magnus Ahltorp <map@stacken.kth.se> + + * appl/fs.c: Added fs rmm. + + * arlad/messages.c: Change to new symlink creation + sematics. VIOC_AFS_DELETE_MT_PT added. VIOC_AFS_STAT_MT_PT code + rewritten. + + * arlad/inter.c: Do followmountpoint in cm_symlink in order to + install correct information into xfs + + * arlad/fcache.c: Don't to fcache_update_length when doing + directory operations. Put more paranoia into fcache_update_length + + * arlad/adir.c: Change to unsigned char in hash function + + * xfs/linux/xfs_message.c: Invalidate cache when directory is + installed. + + * tests/*: New tests. + +Sat Dec 12 11:52:22 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/Makefile.in (SYS): set from configure + + * configure.in (--with-sys): add + + * arlad/volcache.c (get_info_loop): try to return better errors. + also handle the case of an non-existing volume better. + + * arlad/fcache.c (followmountpoint): update some comments and move + some code. + + * arlad/fcache.c (followmountpoint): more comments. + + * arlad/fcache.c (followmountpoint): restructure and split up. + also return better errors. + + * arlad/messages.c (vioc_arladebug): new function + + * arlad/volcache.c (volcache_getby*): return ETIMEDOUT instead of + ENODEV + + * arlad/fcache.c (followmountpoint): don't nuke the error code + + * arlad/conn.c (pinger): ping one host per loop. print debug + information correctly + (conn_dead): print port number/services correctly. + + * appl/fs.c (checkservers_cmd): try to give better error messages + for non-existing cells + + * tests/Makefile.in (SRC_TESTS): add ls-afs + + * tests/ls-afs: new test + + * appl/arlalib.h (fserr): update prototype + + * appl/fs_lib.c (fserr): const-ize, print to stderr + (fs_checkservers): copy cell name correctly. return correct return + value + + * appl/fs.c (checkservers): fixes + + * appl/arlalib.h: add prototype for fs_checkservers + + * appl/fs_lib.c (fs_checkservers): random fixups move around + #ifdef's + + * arlad/messages.c (viocckserv): some fixes + + * arlad/conn.h (conn_probe): add prototype + + * arlad/conn.c (pinger): run `conn_free' instead of just + decrementing the refcount when done with a connection. if + somebody else killed it while we're using it, it should get + recycled. + (conn_probe): new function + (host_down): implement CKSERV_DONTPING and some other random stuff + + * xfs/linux/xfs_inodeops.c (xfs_write_file): return `i_blocks' in + units of `I_BLOCKS_UNIT' + + * xfs/linux/xfs_node.c (xfs_attr2inode): return `i_blocks' in + units of `I_BLOCKS_UNIT' + + * xfs/linux/xfs_locl.h (I_BLOCKS_UNIT): add + + * configure.in (VERSION): bump + +1998-12-08 Love <lha@s3.kth.se> + + * tests/run-tests.in: new file, do it in shellscript instead + of the makefile. + + * lib/roken/getarg.[ch]: Made arg_printusage() understand style. + + * */{,*/}*.c: Made world aware of that arg_printusage() took + a style argument. + + * fs/fs_lib.c: stub for VIOCCKSERV + + * fs/fs.c: checkservers + + * arlad/conn.[ch]: conn_downhosts + + * arlad/messages.c: Non working viocckserv() + + * include/kafs.h: Flags for VIOCCKSERV + +Tue Dec 8 00:49:26 1998 Robert Burgess <rb@stacken.kth.se> + + * Release 0.17.1 + +Tue Dec 8 00:47:49 1998 Magnus Ahltorp <map@stacken.kth.se> + + * xfs/*: Fix memory leak. + +1998-12-06 Love <lha@s3.kth.se> + + * tests/find-and-cat-netbsd: cat netbsd 1.3.2 + +Sun Dec 6 20:00:25 1998 Assar Westerlund <assar@sics.se> + + * Release 0.17 + + * appl/amon.c (main): no options to XtAppInitialize + + * configure.in (VERSION): bump + + * INSTALL: add --without-x + + * appl/Makefile.in (AMON_LIBS): add more libraries + + * appl/fs_lib.c (debug): new helper function + (arla_debug): new function + + * appl/fs_local.h (arla_debug): add prototype + + * appl/fs.c (arladebug_cmd): new function + (xfsdebug_cmd): fix parsing and unparsing of flags + + * appl/Makefile.in (fs): add arladeb.c + + * xfs/bsd/xfs_deb.c (xfsdeb): no XDEBANY + + * xfs/linux/xfs_syscalls.h: remove xfs_syscall debug stuff + + * xfs/linux/xfs_syscalls.c (handle_xfs_syscall): remove + + * xfs/include/xfs_debug.h (XDEBANY): remove + + * include/kafs.h (VIOC_ARLADEBUG): add + + * configure.in (VERSION): bump + +1998-12-06 Love <lha@s3.kth.se> + + * arlad/messages.c (viocaviator): New funtion + (xfs_message_pioctl): Add VIOC_AVIATOR case + + * appl/fs_lib.c (fs_getaviatorstats)new function + + * appl/arlalib.h (fs_getaviatorstats)new function + + * arlad/kernel.[ch]: added kernel_usedworkers() and + kernel_highworkers() + + * include/kafs.h: added VIOC_AVIATOR + + * appl/amon.c: Break out stripChart and add workers + + * configure.in: Check for X. + + * appl/amon.c: New, monitor number of vnodes and kbytes used i cache. + +Sun Dec 6 00:02:42 1998 Assar Westerlund <assar@sics.se> + + * arlad/arladeb.h (arla_deb_units): export new prototypes + * arlad/arladeb.c (arla_deb_units): define in order. define all + and almost-all properly + (arla_log_set_level_num, arla_log_get_level_num): new functions + + * xfs/linux/setdebug.c: removed + + * xfs/linux/Makefile.in: removed setdebug + + * arlad/discon_log.c (log_head): initialize to zero by default + + * arlad/reconnect.c: static-ize some + + * arlad/darla.h: add prototypes + + * arlad/arla_local.h: include reconnect.h + + * arlad/reconnect.h: new file + + * appl/vos.c (main): initports -> ports_init + + * appl/pts.c (main): initports -> ports_init + + * lib/ko/ports.c (ports_num2name): new function + (initports): renamed to ports_init. changed all callers + + * arlad/volcache.c (vl_probe): new function + + * arlad/messages.c (try_again): print a warning and sleep while + waiting for a busy volume + (viocgetacl, viocsetacl, viocgetvolstat, viocsetvolstat): call + try_again + + * arlad/fcache.c (fs_probe): new function + (invalidator): new debug messages + + * arlad/cred.c (cred_expire): print a message telling the user + that credentials have expired + + * arlad/conn.h (ConnCacheEntry): add `probe', `probe_le', + `probe_next', `ntries' + (conn_get): new parameter `probe' + + * arlad/conn.c: probe servers that were marked as down. + (re_probe, add_to_probe_list, pinger): new functions + (conn_init): start a pinger thread + (new_connection, add_connection, internal_get, conn_get): new + parameter `probe' (a function that probes the service) + (conn_dead): print message when loosing connection to a server + (conn_alive): print message when a server comes up again + + * arlad/arla_local.h: add <pwd.h> + + * arlad/arla.c (main): init rx before conn. initports -> + ports_init + + * xfs/irix/Makefile.in (CFLAGS): update with more magic flags + + * util/list.c (listempty): explicit cast to shut up SGI cc + + * tests/copy-and-diff-gnu-mirror: use find and cmp instead of diff + -r + + * arlad/discon_log.c (write_log_ent): add type to `index' + + * xfs/linux/xfs_message.c (xfs_message_installnode): use + xfs_full_name_hash instead of full_name_hash + + * xfs/linux/xfs_inodeops.c (xfs_readdir): use xfs_full_name_hash + instead of full_name_hash + + * xfs/linux/xfs_locl.h (xfs_full_name_hash): work-around for + broken full_name_in_hash in 2.1.131 + + * xfs/linux/xfs_vfsops.c (xfs_delete_inode): correct type in debug + output + +Sat Dec 5 00:35:05 1998 Assar Westerlund <assar@sics.se> + + * tests/Makefile.in (SRC_TESTS): add build-gdb + + * tests/build-emacs: use generic-build + + * tests/build-gdb: new test + + * tests/generic-build: new file + + * tests/strange-characters: new test + + * tests/read-vs-mmap.c, read-vs-mmap2.c, mmap-and-read.c: include + <time.h> + + * tests/Makefile.in: add copy-and-diff-gnu-mirror + (check): generate more unique directory names so that several tests + can be run in the same directory at the same time + + * tests/copy-and-diff-gnu-mirror: new test + + * arlad/kernel.c (worker): move `data' up front to make sure it's + more suitably aligned. how should this really be done? + + * lwp/make-process.o.sh.in (irix): needs -n32 to as. + + * arlad/discon_log.h: clean-up + + * arlad/discon.h: clean-up + + * arlad/reconnect.c (reconnect_create): remove C++-comment + + * arlad/discon_log.c (update_log_ent): fix strange comment + look-a-likes + + * arlad/messages.c (afsstatus2xfs_attr): use ClientModTime instead + of ServerModTime + + * arlad/adir.c: spell-checking and updating of comments + + * arlad/fcache.c (find_next_fs): destroy previous connection. + change all callers. + + * arlad/fcache.c: call conn_dead at all the appropriate places + + * arlad/volcache.c (get_info_loop): mark conns as dead + + * arlad/conn.c (create_new_connections): init `parent' + (recycle_conn): remove one reference to `parent' + (internal_get): new function. handle setting of parent. + (conn_get): only return live servers + (conn_dead, conn_alive): new functions + + * arlad/conn.h (ConnCacheEntry): `parent' points to a + security-cred-free instance + (conn_dead, conn_alive): new functions + + * arlad/fcache.c (find_next_fs, find_first_fs): fill the daily + quota for comments. + + * arlad/fcache.c (find_next_fs): remember how far we got + (getacl, setacl, getvolstat, setvolstat): always call fcache_release + +1998-12-05 Love <lha@s3.kth.se> + + * arlad/arla.c: New option, --fork-late,-f that daemonify, + when everything is setup and running. + +1998-12-03 Love <lha@s3.kth.se> + + * Cleaned up disconnected code (no warnings). + +Wed Dec 2 05:04:04 1998 Assar Westerlund <assar@sics.se> + + * arlad/messages.c (viocgetcell): update to use `cell_dbservers' + + * arlad/fcache.c (find_first_fs, find_next_fs): new functions. + use them. + (findconn): dead. reconnect code probably doesn't work + + * arlad/volcache.c (get_info_loop): new function to try all db + servers. use it. + + * lib/ko/ko.h (cell_dbservers): new prototype + + * lib/ko/kocell.c (cell_dbservers): new function to list all DB + servers + (cell_listdbserver, cell_finddbserver): removed + + * ydr/output.c (print_array, print_varray): fix printf types + +Wed Dec 2 09:26:55 1998 Robert Burgess <rb@stacken.kth.se> + + * Release 0.16 + +Wed Dec 2 00:10:05 1998 Assar Westerlund <assar@sics.se> + + * tests/large-dir.c, tests/large-dir-16384: new files + + * tests/Makefile.in (TEST_PROGRAMS): add large-dir + + * tests/large-dir.c (creat_files): fix types + + * tests/mmap-and-read.c (generate_random_file): generate digits in + the different pages + + * configure.in: vm/vm_object.h, vm/vm_pager.h, vm/vnode_pager.h: + check for + + * util/hash.c (_add): add braces to make it do what I mean + + * util/hash.h (hashtabaddreplace): new prototype + + * util/hash.c (hashtabadd): renamed hashtabaddreplace + (hashtabadd): don't replace existing entry + + * arlad/afs_dir.h (MAXPAGES): update comment + + * arlad/afsdir_check.c: handle large directories + + * arlad/adir.c (getpage): new function. use it. + (is_page_empty): new function + handle large directories + + * tests/large-dir.c (creat_files): better close the files + + * xfs/bsd/xfs_message.c (xfs_message_installattr, + xfs_message_installdata): set pager size + + * xfs/bsd/xfs_locl.h: include vm/vm.h and vm/vm_extern.h + + * configure.in: VERSION: bump to 0.15 + vm/vm.h, vm/vm_extern.h: check for + + * arlad/reconnect.c: don't inlcude discon_fix.h + + * arlad/discon_fix.h: remove. not used anymore. + + * arlad/discon_log.c: don't inlcude discon_fix.h + + * arlad/arla_local.h: remove discon_fix.h + + * arlad/discon_log.h: replace vattr by xfs_attr and moved two + definitions here from discon_fix.h + +1998-11-23 Love <lha@s3.kth.se> + + * Release 0.15 + +Sun Nov 22 00:35:33 1998 Assar Westerlund <assar@sics.se> + + * arlad/inter.c (cm_open): set result to zero if succesful + + * arlad/fs_errors.h: new file + + * arlad/messages.c (try_again): new function + (xfs_message_*): rewritten to use a loop and call try_again to handle + expiring kerberos credentials and busy volumes + + * arlad/kernel.c (WORKER_STACKSIZE): increase + + * tests/untar-emacs: progress to fd 3 + + * tests/Makefile.in (check): give the tests a fd to stderr + + * tests/Makefile.in: add read-vs-mmap2 + + * tests/read-vs-mmap2.c: new file + + * tests/Makefile.in (SRC_TESTS): add rename2 + (check): write output of failing tests into temporary files. run + scripts with $(SHELL) -x + + * tests/Makefile.in: add mmap-and-read + + * arlad/inter.c (cm_mkdir): ReleaseSharedLock -> ReleaseWriteLock + + * arlad/fcache.h (fcache_update_length); add prototype + + * arlad/fcache.c (fcache_update_length): new function. use it. + + * arlad/adir.c: call fcache_update_length at appropriate places + + * configure.in: don't test for <sys/dirent.h> test for + vfs_object_create and vnode_pager_setsize + + * tests/read-vs-mmap.c: new file + + * tests/hello-world.in: new file + + * tests/Makefile.in: hello-world, read-vs-mmap: add + + * arlad/fbuf.c (fbuf_buf): new function + + * arlad/fbuf.h (fbuf_buf): add prototype + + * arlad/fbuf.h: (fbuf_len): add prototype + + * arlad/fbuf.c (fbuf_len): add + + * tests/untar-emacs: add . in loop + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_getpages): report the error + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): call vfs_object_create + if there's one. + + * xfs/bsd/xfs_vnodeops-common.c (xfs_write_comon): call + `vnode_pager_setsize' if there's one + +1998-11-18 Love <lha@s3.kth.se> + + * xfs/bsd/xfs_vnodeops-bsd.c(xfs_{get,put}pages): use + vnode_pager_generic_{put,get}pages if they exist. + +Tue Nov 17 04:10:59 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/bin/startarla.in: create /afs + + * arlad/bsd-subr.c (write_dirent): use _GENERIC_DIRSIZ + + * arlad/arla_local.h: only include <sys/dir.h> if there's no + <dirent.h> + +1998-11-15 Love <lha@s3.kth.se> + + * arlad/inter.c(cm_rename): Check in new_name already exist, and + delete it in that case, this should not happen. Suggested by + Chuck Lever <chuckl@netscape.com>. Relly a problem between + implementations of rename i bsd and linux xfs. + +1998-11-14 Love <lha@s3.kth.se> + + * arlad/inter.c(cm_rename): use adir_lookup_fcacheentry() + + * arlad/adir.[ch]: New function adir_lookup_fcacheentry() + +Fri Nov 13 05:31:27 1998 Assar Westerlund <assar@sics.se> + + * arlad/volcache.c (get_info_common): check for dfs fileset + + * rxdef/vldb.xg (VLF_DFSFILE_SET): added + +Tue Nov 10 05:08:27 1998 Assar Westerlund <assar@sics.se> + + * arlad/fcache.c (fcache_get): handle the case of the entry + appearing while we were out looking for a free entry to put it in. + + * arlad/adir.c (adir_lookup): centry shouldn't be static + +1998-11-08 Love <lha@s3.kth.se> + + * ydr/output.c: dont ydr the OUT arguments in server stub if + function fails, ie returns != 0. + +Sat Nov 7 17:22:58 1998 Assar Westerlund <assar@sics.se> + + * arlad/arla.c: new argument --workers + + * arlad/kernel.c (kernel_interface): dynamic number of worker + threads + + * arlad/{discon_fix.h,darla.h,discon_log.c,discon.h,discon_log.h,darla.c,reconnect.c}: new files (from wwshen) + + * include/kafs.h (CONNMODE_PARCONNECTED): new + + * arlad/messages.c (xfs_message_create): preliminary disconn + support + (viocconnectmode): create and replay log on transitions between + DISCONNECTED and CONNECTED + + * arlad/fcache.h: some new prototypes + + * arlad/cmcb.c (cmcb_init): not being able to create security + objects is a fatal error + + * arlad/fcache.c (throw_entry): signal threads waiting on fee + nodes + (unlink_lru_entry): if there are no nodes, sleep until they appear. + don't reuse nodes being used. + (findconn): made global. handle disconnected mode + (find_entry): remove bogus assert + (fcache_unused): new function + (fcache_giveup_all_callbacks): new function + (fcache_reobtain_callbacks): new function + (do_read_attr): more asserts + (read_data): more asserts + (write_data): try to handle disconnected mode + (truncate_file): try to handle disconnected mode + (create_file): dito + (fcache_get): can't set volume if disconnected + + * arlad/adir.c (adir_lookup): remove static variables. add more + asserts + (adir_readdir): handle the case of broken pgcount in athena.mit.edu + + * arlad/kernel.c: create NUM_WORKERS worker threads to handle + messages from xfs + + * arlad/volcache.c (get_info): handle the case of getting back a + different name (seems to happen with DFS-servers). move out some + common code. + +1998-11-07 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_dead_lookup): add + + * arlad/volcache.c: separate out the _byid and _byname functions. + +1998-11-07 Love <lha@s3.kth.se> + + * appl/fs.c: Patches from Andrzej Filinski <andrzej@daimi.aau.dk> + +1998-11-04 Love <lha@s3.kth.se> + + * arlad/fbuf.c (malloc_create): Do lseek(fd, 0, SEEK_SET) before + reading in the file. + + * doc/oddities.texi: Added. + +1998-11-02 Love <lha@s3.kth.se> + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): Fix for FreeBSD3.0 + + * util/list.[ch] (listnextp): New function. + + * ydr/main.c: Call generate_tcpdump_patches(). + + * ydr/parse.y: Call generate_printfunction{,_prototype} and + generate_tcpdump_stub + + * ydr/output.h: Random prototypes for below functions. + + * ydr/output.c: Introduces concept of printing ydr structures, + added random comment (in generated and !generated code). + (td_file): where tcpdump patches ends up. + (encode_*): Changed sematics for *_MEM, now do goto fail; instead + of return + (print_*): Implemented random functions and stubs for the rest. + (display_type): entrypoint for printing functions + +Mon Nov 2 05:11:25 1998 Assar Westerlund <assar@sics.se> + + * arlad/fcache.c (throw_data): check that the length of the cache + file agress with the status + + * arlad/arladeb.c (arla_deb_units): add `almost-all' + + * xfs/bsd/xfs_vnodeops-osf.c (xfs_create): don't print va_rawmode, + there's no such field in 4.0 + + * xfs/bsd/xfs_vfsops-osf.c (xfs_root): moved the code to + xfs_root_common + + * xfs/bsd/xfs_vfsops.h (xfs_root_common, make_dead_vnode): add + + * xfs/bsd/xfs_vfsops-common.c (xfs_root_common): new function + + * xfs/bsd/xfs_vfsops-bsd.c (make_dead_vnode): set v_data in newly + created node + (xfs_root): moved the code to xfs_root_common + (xfs_install_filesys): use vfs_register if available + + * arlad/fcache.c (write_data): make sure `usedbytes' and + entry->status.Length is updated correctly even if we fail to write + the data to the server + + * aclocal.m4 (AC_C___ATTRIBUTE__): update to discover that the + support for __attribute__ in gcc 2.6.3 is not enough for us + +Mon Nov 2 05:53:25 1998 Robert Burgess <rb@stacken.kth.se> + + * Release 0.14.1 + +1998-11-02 Love <lha@s3.kth.se> + + * README: Note about ultrix. + + * lib/acl/acl.h: Added stds.h, patch from Max + <davros@cyclone.Stanford.EDU> + +Mon Nov 2 02:38:52 1998 Robert Burgess <rb@stacken.kth.se> + + * Release 0.14 + +1998-11-02 Love <lha@s3.kth.se> + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_{get,put}pages): Disable since + it doesn't work. + +1998-10-31 Love <lha@s3.kth.se> + + * configure.in (FreeBSD3.0): Ugly hack to check if we have + DIAGNOSTIC in kernel. + + * xfs/bsd/xfs_vnodeops-common.c: FreeBSD3.0 + (xfs_rename-common): Removed common + + +Sat Oct 31 15:00:55 1998 Johan Danielsson <joda@hella.pdc.kth.se> + + * xfs/bsd/xfs_syscalls-common.c: make xfs_is_pag static + + * xfs/bsd/xfs_node-osf.c (vattr2xfs_attr): va_mode is u_short, not + mode_t + +Sat Oct 31 03:42:23 1998 Assar Westerlund <assar@sics.se> + + * xfs/linux/xfs_inodeops.c (xfs_d_delete): make sure we have an + xfs_node to delete + + * xfs/solaris/bin/Makefile.in (check): add + + * arlad/inter.c (cm_rename): swap order of adir_creat and + adir_remove + +Wed Oct 28 04:00:05 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_syscalls-freebsd.c (xfs_syscall): fix typo + + * configure.in: vfsops: test for vfs_uninit and vfs_oidp struct + proc.p_retval: improve test vfs_register: test for + +Sun Oct 25 20:36:37 1998 Johan Danielsson <joda@hella.pdc.kth.se> + + * arlad/arla.c: implement simple `wc' command + + * rx/rx_clock.c: STARTVALUE for UXP/V + + * lwp/make-process.o.sh.in: UXP/V + + * lwp/lwp.c: set regsize to 8 for UXP/V + + * lwp/process-vpp.s: LWP context switch for Fujitsu UXP/V + +1998-10-25 Assar Westerlund <assar@sics.se> + + * configure.in (freebsd3): set VFS_LKM + +Sun Oct 25 09:48:25 1998 Magnus Ahltorp <map@lroken.stacken.kth.se> + + * arlad: Added viocgetcacheparms + + * xfs/linux: Use filehandles in installdata. SMP fixes. + +Sat Oct 24 02:11:00 1998 Magnus Ahltorp <map@lroken.stacken.kth.se> + + * xfs/linux: Added filehandle support + +1998-10-24 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_message.c (xfs_message_installdata): revert second + part of last change. + + * xfs/bsd/xfs_message.c (xfs_message_installdata): fall back to + looking up cached by names if fhlookup fails. do not reinstall + the same node. + + * xfs/bsd/xfs_vfsops-common.c (xfs_unmount_common): conditionalize + on HAVE_KERNEL_DOFORCE + + * xfs/bsd/Makefile.in (DEFS): remove DIAGNOSTICS. defining this + when it's defined in the kernel build would be a good idea but we + currently have no way of knowing when that's the case. + + * arlad/adir.c (adir_lookup, adir_changefid): fcache_release + properly + + * configure.in (doforce): check for + + * aclocal.m4 (AC_CHECK_KERNEL_VAR): new macro + + * xfs/bsd/bin/mount_xfs.c: handle two argument getvfsbyname + + * configure.in: getvfsbyname: check for two argument version + +1998-10-23 Love <lha@natt.e.kth.se> + + * rxkad/rxkad_locl.h: #ifndef assert + + * appl/pts.c: Implemented: createuser, creategroup, delete, remove, + rename, chown, setfields + (pr_name2id): Bugfixed + (prdebug): Added debugging variable, and added some output code. + (main): Added cvs style debugging switch. + + * lib/ko/koerror.c: Added prerrors. + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_readdir): Cookies are off_t in NetBSD + +1998-10-21 Love <lha@s3.kth.se> + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_readdir): No need to save cookies + for netbsd. + + * ydr/output.c (encode_string): Check length of size-less TSTRING + when decoding. + +Wed Oct 21 22:41:29 1998 Johan Danielsson <joda@hella.pdc.kth.se> + + * xfs/bsd/xfs_node-bsd.c (xfs_cnp_init): init cn_proc + +Mon Oct 19 01:47:22 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_syscalls-common.c (fhget_call, remote_pioctl): + re-order code so that we always vrele vp + + * arlad/adir.c (adir_lookup): don't release the centry if + fcache_get fails + + * arlad/messages.c (viocvenuslog): only print rx stats if RX_DEBUG + + * xfs/bsd/xfs_msg_locl.h: new prototype + + * xfs/bsd/xfs_message.c (xfs_message_updatefid): new function + + * xfs/include/xfs_message.h (XFS_MESSAGE_UPDATEFID): new message + + * xfs/bsd/xfs_dev-common.c (xfs_message_receive): handle + XFS_MSG_UPDATEFID + + * arlad/messages.c (update_kernelfid): new function + (xfs_message_pioctl): moved most of the operations into functions of + their own + + * arlad/adir.h: new prototypes + + * arlad/adir.c (find_entry): new function + (find_by_name): use find_entry + (update_fid_by_name): new function + (adir_changefid): new function + (adir_emptyp): new function + +1998-10-19 Assar Westerlund <assar@sics.se> + + * lwp/make-process.o.sh.in (irix): needs -n32 add -I../include to + find config.h + + * lwp/process.S (hopefully) improve some of the conditional stuff. + +Sun Oct 18 11:00:58 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_mkdir): conditionalize vput + + * xfs/irix/xfs_vnodeops.c (xfs_write): merge solaris fix for + updating mtime and size + (xfs_creat): merge solaris fix for truncating file + (xfs_map): try to implement + +Sun Oct 18 00:03:12 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_symlink): fix call to + xfs_symlink_common + + * arlad/cred.h (cred_add_krb4): updated prototype + + * arlad/cred.c (cred_add_krb4): add `uid' + +Sun Oct 18 00:02:36 1998 Johan Danielsson <joda@hella.pdc.kth.se> + + * xfs/bsd/xfs_node-osf.c (vattr2xfs_attr): cast VNOVAL to correct + type + (xfs_cnp_init): fix hash calculation + + * xfs/bsd/xfs_vnodeops-*.c: don't pass cnp to various common + vnode-ops + +Sat Oct 17 12:37:54 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common, + xfs_create_common): disable my create optimization + + * xfs/bsd/xfs_node-bsd.c (new_xfs_node): fix interlock stuff + + * arlad/adir.c (adir_lookup): disable cache + + * xfs/bsd/xfs_message.c (xfs_message_installdata): only purge + cache if XFS_INVALID_DNLC is set + + * arlad/messages.c: set installdata.flag + + * xfs/include/xfs_message.h (installdata): add a flag + +Sat Oct 17 11:47:48 1998 Assar Westerlund <assar@sics.se> + + * arlad/messages.c (token_for_cell): return uid + (xfs_message_pioctl VIOCSETTOK): remember uid + + * arlad/cred.c (cred_add): add `uid' + + * arlad/cred.h (CredCacheEntry): add uid + + * xfs/irix/xfs_vnodeops.c (xfs_readdir): look at the abi and + convert to irix5_dirent if needed + + * xfs/bsd/xfs_vnodeops-common.c: remove bsd-specific code + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lookup, xfs_remove, xfs_rmdir, + xfs_link, xfs_symlink): move the freeing of the namei buffer here + from common + + * xfs/bsd/xfs_vfsops-osf.c (make_dead_vnode): fix prototype + + * xfs/bsd/xfs_syscalls-common.c: include <sys/ioccom.h> or + <sys/ioctl.h> + + * xfs/bsd/xfs_node-osf.c (xfs_dnlc_enter): do the negative cache + check + + * xfs/bsd/xfs_vnodeops-common.c: VOP_UNLOCK -> xfs_vfs_unlock + + * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_enter): make sure there's no + entry already in the DNLC + + * xfs/bsd/xfs_message.c (xfs_message_installnode): removed cache + checking code + + * arlad/fcache.c (read_data): if copyrx2fd fails, bail out + +Fri Oct 16 16:46:57 1998 Johan Danielsson <joda@hella.pdc.kth.se> + + * xfs/bsd/xfs_locl.h: #define cn_nameiop ni_nameiop + +1998-10-16 Love <lha@s3.kth.se> + + * appl/fs*.[ch]: Added code to gc pags (compat). + + * include/kafs.h: Added VIOC_GCPAGS + +1998-10-15 Love <lha@s3.kth.se> + + * INSTALL,configure.in: --enable-knfs + + * xfs/bsd/xfs_vnodeops.c(xfs_readdir): Added cookie creation code. + +Wed Oct 14 05:41:34 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vnodeops.h: update prototypes + + * xfs/bsd/xfs_vnodeops-osf.c (xfs_mkdir, xfs_readdir): adapt to + new versions of -common functions + + * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common): do not enter + negative entries if creating + (xfs_mkdir_common): remove the OS-specific code + (xfs_readdir): set `eofflag' + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_create): make sure to call + VOP_LOOKUP with cn_nameiop == LOOKUP + (xfs_mkdir): do the post mkdir lookup + (xfs_readdir): set eofflag + + * xfs/bsd/xfs_vfsops-bsd.c: replace printf with XFSDEB + + * xfs/bsd/xfs_syscalls-common.c (fhget_call): check suser + + * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_enter_name): init more fields + in `cn' + + * xfs/bsd/xfs_message.c (xfs_message_installnode): make sure we + get rid of any negative entries before adding the new entry. Is + this really needed? + (xfs_message_installdata): remove old stuff + + * xfs/bsd/xfs_locl.h (xfs_proc_to_cred): new macro + + * xfs/bsd/Makefile.in (unload): fix for non-OSF1 + + * xfs/bsd/bin/mount_locl.h (__progname): remove + + * xfs/bsd/xfs_vfsops.h (xfs_fhlookup): update prototype + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): take `gen' and check it + + * lib/ko/gensysname.c (sysnames): remove all bsd entries + + * TODO: I think we do this (at least on some OSes) + + * xfs/bsd/xfs_dev-common.c (xfs_message_rpc): sigmask seems to be + defined on more systems than __sigmask. are there any with only + __sigmask? + + * xfs/bsd/xfs_common.h: s/define/endif/ + +Thu Oct 15 05:29:19 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/Makefile.in: use KERNEL_LD + + * xfs/bsd/xfs_locl.h: <vm/vm_zone.h> + + * configure.in (KERNEL_LD): set + <vm/vm_zone.h>: check for + + * xfs/bsd/xfs_vnodeops-bsd.c: free pathnames with zfree if there's + a zfreei. + + * aclocal.m4 (AC_KERNEL): allow ac_kernel_ld to be already set + (AC_HAVE_KERNEL_FUNC): use KERNEL_CLAGS. should probably call + AC_TRY_COMPILE_KERNEL directly + + * xfs/bsd/xfs_vnodeops-common.c: free pathnames with zfree if + there's a zfreei. + + * configure.in (freebsd3): add + (vfc_mountroot in struct vfsconf): check for + (zfreei, vfs_cache_lookup): check for + + * xfs/irix/xfs_vfsops.c (xfs_root): don't VN_HOLD + (make_dead_vnode): use vn_alloc + + * xfs/bsd/xfs_vfsops-bsd.c: move around and reorganize the code + + * xfs/bsd/xfs_wrap-bsd.c: handle different versions of MOD_DEV + + * xfs/bsd/xfs_syscalls.h: re-organize SCARG & syscallarg + + * configure.in: add -I. before testing for VOP_LOCK & c:o + + * configure.in (freebsd): use /bin/sh and not $SHELL + + * acconfig.h (HAVE_STRUCT_PROC_P_RETVAL): add + + * configure.in (freebsd): generate vnode_if.[ch] + (struct proc): look for `p_retval' + + * xfs/bsd/xfs_wrap-bsd.c: replace printf by XFSDEB + (xfs_mod): handle MOD_DISPATCH + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_cachedlookup): new function + (xfs_eopnotsupp): always return EOPNOTSUPP. use instead of + vn_default_error + + * xfs/bsd/xfs_syscalls.h (xfs_setpag_call, xfs_pioctl_call): add + + * xfs/bsd/xfs_syscalls-freebsd.c (xfs_syscall): move here. handle + 3.0 returning values + (xfs_install_syscalls): try AFS_SYSCALL first, then first free lkm + slot + + * xfs/bsd/xfs_syscalls-common.c (xfs_syscall): remove + + * xfs/bsd/xfs_syscalls-osf.c (xfs_syscall): move here + (xfs_install_syscalls): try AFS_SYSCALL first, then AFS_SYSCALL2, and + then first free lkm slot + + * xfs/bsd/xfs_syscalls-bsd.c (xfs_syscall): move here + (xfs_install_syscalls): try AFS_SYSCALL first, then first free lkm + slot + + * xfs/bsd/xfs_locl.h: <sys/filedesc.h>: move <sys/fctnl.h>: + include + + * xfs/bsd/xfs_dev-bsd.c (xfs_dev): modern FreeBSD has poll instead + of select + +Sun Oct 11 16:15:04 1998 Johan Danielsson <joda@stp.pdc.kth.se> + + * xfs/bsd/xfs_vnodeops-{osf,bsd}.c (xfs_create): move some code from + xfs_create_common here + + * xfs/bsd/xfs_vnodeops-common.c (xfs_create_common): remove + architecture dependent code (specifically the call to VOP_LOOKUP) + + * xfs/bsd/xfs_dev-common.c (xfs_message_rpc): use __sigaddset if + defined + +Sat Oct 10 21:05:13 1998 Johan Danielsson <joda@hella.pdc.kth.se> + + * lib/ko/gensysname.c: add generic bsd handler + + * configure.in, lib/ko/ko_locl.h: sys/utsname.h + +1998-10-09 Love <lha@s3.kth.se> + + * ydr/output.c: (sizeof_type) TOPAQUE has a size (1). + +Thu Oct 8 14:39:48 1998 Johan Danielsson <joda@hella.pdc.kth.se> + + * xfs/bsd/xfs_node-osf.c (new_xfs_node): move call to insmntque to + after initializing the vnode + (so it will automagically create a VM object) + + * xfs/bsd/xfs_vfsops.h: xfs_fhlookup takes generation number iff + OSF/1 + + * xfs/bsd/xfs_message.c (xfs_message_installdata): pass generation + number to xfs_fhlookup iff OSF/1 + + * xfs/bsd/xfs_vfsops-osf.c: implement xfs_fhlookup, and xfs_fhopen + + * xfs/bsd/xfs_vfsops-common.c (xfs_mount_common): init OSF/1 + f_fsid + + * xfs/bsd/xfs_dev-osf.c (xfs_install_device): try to install + device with major 64 + + * xfs/bsd/xfs_syscalls-osf.c: try to install syscall at slot 232 + + * xfs/bsd/xfs_syscalls-common.c: fixes for OSF/1 + + * xfs/bsd/xfs_dev-common.c (xfs_devclose_common): cleanup, + (xfs_message_rpc): use xfs_curproc() + + * xfs/bsd/xfs_locl.h: xfs_curproc() + + * arlad/bsd-subr.c (conv_dir): check return value from + fcache_fhget + + * xfs/bsd/bin/mount_xfs.c: call set_progname, add `-F' option to + set mountflags (used by OSF/1 mount) + +Wed Oct 7 21:28:14 1998 Johan Danielsson <joda@hella.pdc.kth.se> + + * lib/ko/gensysname.c: Add Digital UNIX/Alpha + +Wed Oct 7 05:01:53 1998 Assar Westerlund <assar@sics.se> + + * xfs/linux/xfs_inodeops.c (xfs_follow_link): handle both two and + three argument versions + + * acconfig.h: HAVE_FOLLOW_LINK_THREE_ARGS: add + + * configure.in (linux): try looking in /proc/ksyms before + /proc/cpuinfo + (follow_link): test for number of arguments + +1998-10-05 Assar Westerlund <assar@sics.se> + + * Release 0.13 + + * NEWS: updated + + * configure.in: bump to 0.13 + + * arlad/irix-subr.c: use the correct size macro + + * INSTALL: add --disable-dynamic-afs and --enable-smp + + * xfs/irix/Makefile.in (unload): add + + * configure.in (linux): fall back on testing on /proc/cpuinfo + (--enable-smp): add + + * configure.in (linux): do the smp test against the include-files + instead of /proc + + * configure.in (linux): test for smp by looking in /proc/ksyms + instead of /proc/cpuinfo + +1998-10-04 Assar Westerlund <assar@sics.se> + + * arlad/fcache.c (stale): set sentenced iff already locked. + changed all callers. + + * util/log.c (log_vprint_syslog): fflush + + * xfs/irix: much improved. most stuff (except getdents) seems to + work. + +Sun Oct 4 03:44:53 1998 Magnus Ahltorp <map@stacken.kth.se> + + * acconfig.h configure.in: Check for read_super arguments. + + * xfs/linux/xfs_load.c: Fix read_super argument confusion. + +1998-10-03 Love <lha@e.kth.se> + + * xfs/bsd/xfs_node-bsd.c(new_xfs_node): Broke out the + getnewvnode() code. + (xfs_getnewvnode): new function, creates xnode too. + + * xfs/bsd/xfs_vfsops-{bsd.c,common.c}: Added strange knfs code. + +Fri Oct 2 06:39:15 1998 Assar Westerlund <assar@sics.se> + + * arlad/volcache.c (get_info): remove bogus `we didn't get what we + asked for'-warning + + * xfs/linux/xfs_inodeops.c (xfs_readdir, xfs_follow_link): do + xfs_free + + * xfs/linux/xfs_dev.c (xfs_devread): do free + + * xfs/linux/xfs_common.c (xfs_alloc): debugging for xfs_allocs - + xfs_frees + + * xfs/linux/xdeb.h (XDEBMEM): add + + * ydr/symbol.c (printsymbol): unused + + * lwp/iomgr.c (IOMGR): correct printf format string + + * include/bits.c: some unused to get rid of warnings + + * arlad/messages.c (xfs_message_rpc): mark as unused to get rid of + a warning + + * acconfig.h (_GNU_SOURCE): define it + +Wed Sep 30 06:39:08 1998 Assar Westerlund <assar@sics.se> + + * xfs/irix/xfs_dev.c (xfs_install_device): initialize the queues + + * xfs/irix/xfs_vfsops.c (xfs_mount): remove cdevsw check + +Wed Sep 30 01:10:31 1998 Assar Westerlund <assar@sics.se> + + * Release 0.12 + + * arlad/fcache.c (create_node): new function + (fcache_get): call create_node if there is no cache node. + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_lock, xfs_unlock, xfs_islocked): + don't use vop_nolock/vop_nounlock/vop_noislocked + +Tue Sep 29 04:07:14 1998 Assar Westerlund <assar@sics.se> + + * arlad/volcache.c (recycle_entry): release the filecache entry + + * arlad/fcache.c (fcache_get): assert that find_free_entry + succeeded + +Mon Sep 28 00:51:45 1998 Assar Westerlund <assar@sics.se> + + * acconfig.h (HAVE_KERNEL_VFS_GETVFS): add + +Sun Sep 27 11:55:55 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_may_uninstall_filesys): new + (xfs_fhlookup): use vfs_getvfs + + * configure.in (vfs_getvfs): check for + (linux): check for __SMP__ + +Sun Sep 27 11:55:54 1998 Assar Westerlund <assar@sics.se> + + * Release 0.11 + + * xfs/bsd/xfs_vnodeops-bsd.c (xfs_islocked): faking always having + it locked is better. + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): bump v_writecount if + opening for wrinting + +Sun Sep 27 11:29:46 1998 Assar Westerlund <assar@sics.se> + + * xfs/linux/Makefile.in: use KERNEL_CFLAGS + + * configure.in (linux): set KERNEL_CFLAGS + use AC_HAVE_KERNEL_STRUCT_FIELD + + * aclocal.m4 (AC_HAVE_KERNEL_STRUCT_FIELD): new macro + +Sun Sep 27 07:33:18 1998 Assar Westerlund <assar@sics.se> + + * arlad/adir.c (add_to_page): set flag + +Sat Sep 26 19:45:37 1998 Robert Burgess <rb@stacken.kth.se> + + * Release 0.10 + +Sat Sep 26 19:28:00 1998 Assar Westerlund <assar@sics.se> + + * arlad/adir.c (adir_lookup): correct centry logic + + * lwp/Makefile.in (REALCFLAGS): add DEBUG + + * arlad/fbuf.c (mmap_copyrx2fd, mmap_copyfd2rx, malloc_copyrx2fd, + malloc_copyfd2rx): handle len == 0 properly + + * arlad/arla.c: use fcache_release + + * arlad/adir.c (adir_lookup): verify datap of cached directory + + * arlad/fcache.c (find_entry_nolock): new function + (fcache_stale_entry): if entry is locked, sentence it + (read_data): always call copyrx2fd + (write_data): always call copyfd2rx + (fcache_release): new function. change all callers. + + * arlad/fcache.h (FCacheEntry): new flag `sentenced' + (fcache_release): new function + +Wed Sep 23 03:31:48 1998 Assar Westerlund <assar@sics.se> + + * xfs/solaris/xfs_common.c (memcpy): define in terms of bcopy + because gcc generates references to it and solaris doesn't have + any in the kernel + +Sun Sep 20 06:18:09 1998 Assar Westerlund <assar@sics.se> + + * arlad/sunos-subr.c (conv_dir): `handle' should be `cache_name' + + * arlad/irix-subr.c (conv_dir): `handle' should be `cache_name' + + * arlad/hpux-subr.c (conv_dir): `handle' should be `cache_name' + + * arlad/linux-subr.c (conv_dir): `handle' should be `cache_name' + +Thu Sep 17 00:26:08 1998 Assar Westerlund <assar@sics.se> + + * arlad/messages.c: conditionalize all tests of RXKADEXPIRED on + KERBEROS + + * xfs/bsd/xfs_message.c (xfs_message_installdata): use cache + handle + + * xfs/bsd/xfs_syscalls-common.c: use xfs_fh_args + + * xfs/bsd/xfs_syscalls.h (xfs_fh_args): define + + * xfs/bsd/xfs_vfsops.h (xfs_fhlookup): add prototype + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhlookup): new function + (xfs_fhopen): use `xfs_fhlookup' + +1998-09-15 Love <lha@s3.kth.se> + + * xfs/linux/xfs_locl.h: Checked for HAVE_LINUX_MODVERSIONS_H + and appied patch from Aaron M. Ucko <amu@mit.edu>. + + * configure.in: - Added check for <linux/modversions.h> + - Applied patch from (Dima Ruban) <dima@best.net> + +Mon Sep 14 03:14:13 1998 Assar Westerlund <assar@sics.se> + + * xfs/solaris/xfs_vnodeops.c (xfs_read, xfs_write): complain if + not VREG + + * xfs/solaris/xfs_message.c (xfs_message_installdata): only purge + the name cache if this file had data before. + + * xfs/bsd/xfs_vnodeops-common.c (xfs_lookup_common): removed bogus + NCHNAMLEN test + + * xfs/bsd/xfs_node-bsd.c (xfs_dnlc_enter): check for NCHNAMLEN. + apparently freebsd-3.0 doesn't have any limit on the length of + file names in the dnlc. + + * conf/arla.conf: bump {high,low}_bytes + + * arlad/messages.c (xfs_message_mkdir): do an installdata of the + new directory + + * arlad/inter.c (cm_getattr): should be no need to set the tokens + here explicitly + + * arlad/adir.c: removed lots of magic, clean-up. + (adir_lookup): add a one-entry cache of directories + (adir_readdir): return entries in order stored in directory instead of + hash table order (. and .. are always the two first entries) + +1998-09-13 Johan Danielsson <root@chowder.pdc.kth.se> + + * configure.in: use AC_ELF_OBJECT_FORMAT, add -D_LKM to CFLAGS + when checking for vfssw, (NetBSD) try to figure out KERNEL_CFLAGS + in a more intelligent way, and make sure we have -mno-fp-regs on + alpha + +Sat Sep 12 23:34:14 1998 Assar Westerlund <assar@sics.se> + + * xfs/solaris/xfs_vnodeops.c (xfs_setattr): clear tokens before + rpc + (xfs_link): arguments in correct order. call lookup correctly + (xfs_map): verify that the attributes are there. fake handling the + MAP_SHARED, PROT_WRITE-case + + * xfs/solaris/xfs_syscalls.c: solaris' uprintf doesn't understand + %p + + * arlad/messages.c (xfs_message_putattr): install the new + attributes + + * arlad/fcache.c (truncate_file): send (size, 0, size) to + StartRXAFS_StoreData. + +1998-09-12 Love <lha@s3.kth.se> + + * ydr/output.c: Added missing adding of total_len for strings. + Added RCSID to the generated files. + +Sat Sep 12 03:01:36 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_vfsops.h (xfs_mount_common): new prototype + + * xfs/bsd/xfs_vfsops-common.c (xfs_mount_common): const-ize + user_path + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): more debugging + + * xfs/bsd/xfs_syscalls-common.c (fhget_call, fhopen_call): new + prototypes + + * xfs/bsd/xfs_syscalls-freebsd.c (xfs_syscallent): correct number + of arguments + + * xfs/bsd/xfs_syscalls-bsd.c (xfs_syscallent): correct number of + arguments + + * arlad/fcache.c (fcache_fhget): check fhopen_working + +Fri Sep 11 04:27:35 1998 Magnus Ahltorp <map@lroken.stacken.kth.se> + + * milko/{ptserver.c,pr.c}: First version of ptserver + +Wed Sep 9 22:15:09 1998 Assar Westerlund <assar@sics.se> + + * xfs/bsd/xfs_syscalls.h (SCARG): better definition + + * xfs/bsd/xfs_syscalls-common.c: now even compiles + + * xfs/bsd/xfs_message.c (xfs_messge_installdata): don't use + non-existing variable `tmp' + + * rx: compilable without RXDEBUG + + * arlad/messages.c: remove unused variables + + * lib/ko/gensysname.c: add freebsd2.2 + + * arlad/arla.c (arla_rx_status): conditionalize on RXDEBUG + + * arlad/Makefile.in (REALCFLAGS): add RXDEBUG + +Tue Sep 8 01:21:25 1998 Assar Westerlund <assar@sics.se> + + * arlad/adir.c: new fcache_open_file + + * xfs/bsd/xfs_vfsops.h (xfs_fhopen): prototype + + * xfs/bsd/xfs_vfsops-bsd.c (xfs_fhopen): new function + + * xfs/bsd/xfs_syscalls-common.c (fhget_call, fhopen_call): new + functions + (pioctl_call): restructure + + * xfs/solaris/bin/umount_xfs.c: include <config.h> + add ID + + * xfs/solaris/bin/mount_xfs.c: include <config.h> + add ID + + * xfs/solaris/bin/test-fhopen.c: new file + + * xfs/solaris/bin/Makefile.in (test-fhopen): add + + * xfs/solaris/xfs_vnodeops.c (xfs_space): implement for cmd == + F_FREESP, fl->l_len == 0 + + * xfs/solaris/xfs_vfsops.c (xfs_fhlookup, xfs_fhopen): new + functions + + * xfs/solaris/xfs_syscalls.h (xfs_fh_args): add + + * xfs/solaris/xfs_syscalls.c (fhget_call, fhopen_call): new + functions + (pioctl_call): restructure + + * xfs/solaris/xfs_message.c (xfs_message_installdata): update to + new message. use xfs_fhlookup + + * xfs/solaris/xfs_deb.h (XDEBLKM, XDEBSYS): define + + * xfs/sunos/xfs_message.c (xfs_message_installdata): update to new + message + + * xfs/rhapsody/xfs_message.c (xfs_message_installdata): update to + new message + + * xfs/linux/xfs_message.c (xfs_message_installdata): update to new + message + + * xfs/irix/xfs_message.c (xfs_message_installdata): update to new + message + + * xfs/include/xfs_message.h (CACHEHANDLESIZE): make fsid_t + + fhandle_t in size + (xfs_message_installdata): add cache_name + + * xfs/bsd/xfs_message.c (xfs_message_installdata): update to new + message + + * xfs/aix/xfs_message.c (xfs_message_installdata): update to new + message + + * include/kafs.h (VIOC_FHGET, VIOCE_FHOPEN): define + + * arlad/inter.h (cm_open): update prototype + + * arlad/inter.c (cm_open): return cache_name and cache_handle + + * arlad/arla.c: update to new fcache_open_file + + * arlad/fcache.h (FCacheEntry): 32-ize. replace `inode' with + index and cache-handle + + * arlad/fcache.c (fhopen, fcache_fhget): new functions + (fcache_create_file): new function. use. + (fcache_open_file): use fhopen if it's working + (fcache_open_file): remove mode argument. change all callers. + (find_entry): handle the case of being called from volcache before the + fcache is initialized. + (read_data, write_data): only call copyrx2fd/copyfd2rx if sizefs > 0 + + * arlad/subr.h (conv_dir): update prototype + + * arlad/*-subr.c (conv_dir): return cache_name and handle. + + * arlad/Makefile.in (KAFS_LIBS): set + (LIBS): add KAFS_LIBS + +1998-09-06 Love <lha@s3.kth.se> + + * output.c: - Added bounce checking for memencoding. + - Got rid of fail: label error message. + + * rx/rx.h: Added sys/param.h to get rid of warning. + +Fri Aug 28 22:49:22 1998 Assar Westerlund <assar@sics.se> + + * util/strutil.h (strupr, strlwr): remove prototypes + + * util/strutil.c (strupr, strlwr): remove (they're already in + libroken) + Mon Aug 24 02:48:19 1998 Assar Westerlund <assar@sics.se> * xfs/solaris/xfs_vnodeops.c (xfs_create): truncate the file if diff --git a/usr.sbin/afs/src/INSTALL b/usr.sbin/afs/src/INSTALL index cf276efeab5..bd9e54b6807 100644 --- a/usr.sbin/afs/src/INSTALL +++ b/usr.sbin/afs/src/INSTALL @@ -1,4 +1,4 @@ -$Id: INSTALL,v 1.1.1.1 1998/09/14 21:52:51 art Exp $ ($Name: $) +$Id: INSTALL,v 1.2 1999/04/30 01:59:03 art Exp $ ($Name: $) Building arla @@ -25,6 +25,12 @@ are also some arla-specific arguments to configure: --disable-mmap don't use mmap at all --enable-mmaptime use mmap:ed time from /dev/kmem (known to work in FreeBSD) + --disable-dynamic-afs don't use loaded AFS library with AIX + --enable-smp compile for SMP (currently only on Linux) + --enable-knfs enable code to nfsmount AFS (*BSD only). + --enable-kld build KLD modules (for FreeBSD3-current) + --without-x don't build X code + --with-pthreads=dir use the pthreads library in dir By default configure will use gcc if it finds it. If you want to use a specific compiler or some special options you can specify that when @@ -97,16 +103,19 @@ Linux: mkdir /afs mount -t xfs arla /afs - If you are using Linux 2.1, you may want to copy /usr/arla/lib/getcwd.so - to /lib and add this line to your /etc/ld.so.preload: + If you are using Linux 2.1 or 2.2 and libc4, libc5 or glibc 2.0, + you may want to enable the getcwd syscall, which works much better + than the old way of doing getcwd. In order to do this, follow + these steps: - /lib/getcwd.so - - This enables the getcwd syscall, which works much better than the old - way of doing getcwd. Be careful though, and execute /bin/pwd as a test - before you exit your editor. If /bin/pwd fails with a message like - "/bin/pwd: can't load library '/lib/getcwd.so'", remove the line from - /etc/ld.so.preload, and report the problem. + 1. Copy /usr/arla/lib/libgetcwd.so.X (where X is the arla version) + to /lib. + 2. Run "/sbin/ldconfig". + 3. Run "LD_PRELOAD=/lib/libgetcwd.so.0 /bin/pwd". If this fails + with "/bin/pwd: can't load library '/lib/libgetcwd.so.0'" or + some other error message, report this error. + 4. If the previous step went well, add this line to /etc/ld.so.preload: + /lib/libgetcwd.so.0 DO NOT load the file from /usr/arla/lib, since /usr probably is not part of the root partition of your system. If you do this, your system @@ -114,6 +123,10 @@ Linux: Linux installations, init, sh, mount and other programs are dynamically linked. + If you use glibc 2.1 or later, the above method is unnecessary and + the line /lib/libgetcwd.so.0 should be removed from /etc/ld.so.preload + if present. + SunOS4: modload /usr/arla/bin/libxfs.o @@ -130,24 +143,27 @@ SunOS4: /usr/arla/bin/mount_xfs /dev/xfs0 /afs /usr/arla/bin/arlad -FreeBSD +FreeBSD: -Do like in {Net|Open} except for doing the modload you can just do: +Do like in {Net|Open} except that after the first time (when /dev/xfs0 +exists) you can skip the modload since the module with automatically +be loaded by mount_xfs assuming you have copied xfs_mod.o to /lkm with +something like the following commands: mkdir /lkm cp /usr/arla/bin/xfs_mod.o /lkm/xfs_mod.o -And mount_xfs vill load the filesystem into the kernel. +And mount_xfs will load the filesystem into the kernel. Solaris: -add a line to /etc/name_to_major with (134 should be any unused number) +add a line to /etc/name_to_major with (138 should be any unused number) - xfs 134 + xfs 138 and another one to /etc/name_to_sysnum (105 is the preferred system -call number, if that's already used by Transarc AFS on your machine, -pick some other number) +call number, if that's already used by Transarc AFS on your machine or +you are using Solaris 7 (which uses 105 itself), pick some other number) xfs 105 @@ -163,9 +179,9 @@ and then run: drvconfig -i xfs -Create a device with the name_to_major number and a directory: +Create a /dev link and a directory: - mknod /dev/xfs0 c 134 0 + ln -s "/devices/pseudo/xfs@0:" /dev/xfs0 mkdir /afs Now you can try mounting the file system and start the daemon: @@ -173,6 +189,9 @@ Now you can try mounting the file system and start the daemon: /usr/arla/bin/mount_xfs /dev/xfs0 /afs /usr/arla/bin/arlad +Note that if you are using a syscall other than 105, you have to use a +new kth-krb (with afssys.c 1.59 or newer) and set AFS_SYSCALL=xfs +before starting arlad. If you want to, you can copy the xfs/solaris/xfs module to /kernel/fs and xfs/solaris/bin/mount_xfs to /lib/fs/xfs/mount which enables you to @@ -190,12 +209,15 @@ And add a line like the following to /etc/vfs: Now you can try mounting the file system and start the daemon: + /usr/arla/bin/xfs_load /usr/arla/bin/xfs /usr/arla/bin/mount_xfs /dev/xfs0 /afs /usr/arla/bin/arlad -Digital Unix (aka OSF/1) +Tru64 Unix (aka Digital Unix (aka OSF/1)): -Copy the xfs.mod to /subsystems. +Copy the xfs.mod to some of /subsys, /var/subsys, /sys/BINARY, +or /subsystems. Depending on what your kloadsrv thinks is the +right thing<tm>. Load (configure) the module with sysconfig -c xfs diff --git a/usr.sbin/afs/src/NEWS b/usr.sbin/afs/src/NEWS index d55237ea5e1..a898317a136 100644 --- a/usr.sbin/afs/src/NEWS +++ b/usr.sbin/afs/src/NEWS @@ -1,3 +1,197 @@ +Changes in release 0.23: + +* changed volume cache + +* bsd: lock node when vget + +* updated vos command + +* removed Solaris umount_xfs command + +* flush kernel acl when doing setacl + +* Linux devfs support + +* misc. bugfixes + +Changes in release 0.22: + +* getcwd magic for linux + +* added fallback code for old vl-servers + +* added plwp, LWP on pthreads form Derrick J Brashear <shadow@dementia.org> + +* port to Irix 6.4 + +* random bugfixes + +Changes in release 0.21: + +* improve libgetcwd.so installation procedure + +* correct some bugs with the counting of used bytes + +* return better error codes + +* should work with KLD/LKMs on FreeBSD [34] + +* correct errors when setting and reading sysnames + +* make --with-sys work + +* fix refcount bug in volcache + +* works once again on NT/cygwin + +* add cellstatus and suid cells + +* update tests + +* port to Solaris 2.7 in 64-bit mode + +Changes in release 0.20: + +* more correct error codes + +* fs newcell + +* fs apropos (command locate by keyword) + +* linux getcwd fix from Brandon S. Allbery <allbery@ece.cmu.edu> + +* some code reorganized + +* lots of bug fixes + +Changes in release 0.19: + +* support for Solaris 7 + +* tests: add support for running somewhere else than /afs + +* some more bug fixes + +Changes in release 0.18: + +* implement selection of filservers based on rtts + +* fix bugs related to 8bit characters in filenames + +* revised error messages in vol/fcache + +* lots of new test cases + +* new shell-script run-tests to run tests + +* implement `fs checkservers' and `fs rmm' + +* return correct number of blocks on linux + +* the usual collection of bug fixes + +Changes in release 0.17.1: + +* fixed memory leak bug + +Changes in release 0.17: + +* new graphical program `amon' for monitoring the state of the cache. + +* `fs xfsdebug' and `fs arladebug' for manipulating the details of the + debug output. + +* more warning messages from arla (when credentials expire, hosts go + up and down, volumes are busy, ...) + +* keep track of which servers are up and down, probe them periodically + and fallback to servers that are up. + +* more test-cases + +* work-around a bug in Linux 2.1.131 that made it impossible to have + filenames with 8bit characters + +* correct timestamps (use ClientModTime instead of ServerModTime) + +* bug fixes + +Changes in release 0.16: + +* better handling of large directories + +* even more bug fixes + +Changes in release 0.15: + +* added disconnected mode code from WUWEI SHEN <wwshen@engin.umich.edu> + +* more support for FreeBSD3.0 + +* multiple worker-threads + +* bugfixes + +* more test cases + +Changes in release 0.14.1: + +* now even builds + +Changes in release 0.14: + +* added an experimental pre-greek letter AFS server, milko + +* FreeBSD 3.0 support + +* more Digital UNIX support + +* updated IRIX port + +* transarc compat gc pag support in fs appl + +* new pts functions implemented + +* Linux SMP fixes + +* arlad now supports viocgetcacheparams + +* lwp now supports Fujitsu UXP/V architecture + +* cookies implemented in xfs_readdir + +* many bug fixes + +Changes in release 0.13: + +* irix port much improved + +* smp detection on Linux works better + +* plugged some memory leaks in the linux kernel module + +* random bug fixes + +Changes in release 0.12: + +* works better on OpenBSD and Linux + +* builds SMP-able modules on Linux + +* lwp stack size bumped + +Changes in release 0.11: + +* works better on NetBSD and modern Linux + +* bug fixes + +Changes in release 0.10: + +* cache files are now opened using inode number on BSD and Solaris + +* lots of bug fixes + Changes in release 0.9: * merging of all BSD codes diff --git a/usr.sbin/afs/src/README b/usr.sbin/afs/src/README index 7249ed375ab..0fb700ce630 100644 --- a/usr.sbin/afs/src/README +++ b/usr.sbin/afs/src/README @@ -1,15 +1,15 @@ -README for arla-0.9 ($Name: $) -$Id: README,v 1.1.1.1 1998/09/14 21:52:51 art Exp $ +README for arla-0.23 ($Name: $) +$Id: README,v 1.2 1999/04/30 01:59:03 art Exp $ 1. What is arla? -Arla is a free AFS cache-manager/client implementation. +Arla is a free AFS cache-manager implementation. 2. Where do I find this file? This file is contained inside -ftp://ftp.stacken.kth.se/pub/arla/arla-0.9.tar.gz -(aka /afs/stacken.kth.se/ftp/pub/arla/arla-0.9.tar.gz). +ftp://ftp.stacken.kth.se/pub/arla/arla-0.23.tar.gz +(aka /afs/stacken.kth.se/ftp/pub/arla/arla-0.23.tar.gz). 3. What is AFS? @@ -22,17 +22,20 @@ for more information. There is kernel support (with different level of functionality) for the following operating systems: -- FreeBSD 2.2 -- OpenBSD 2.2 and 2.3 +- FreeBSD 2.2, 3.0, and 4.0 +- OpenBSD 2.2, 2.3 and 2.4 - NetBSD 1.2 and 1.3 -- Linux 2.0.x and 2.1.x +- Linux 2.0.x, 2.1.x, and 2.2.x - SunOS 4 -- Solaris 2.5, 2.6 and 2.7 beta +- Solaris 2.5, 2.6 and 7 - AIX 4.x - IRIX 6.x - Digital Unix 4.0 (OSF/1) - Rhapsody DR2 +Userland only: +- Ultrix 4.4 + A cache manager (arlad) that works both in user-level mode and with the kernel module. The user-level mode is quite portable and has even been working under Windows NT (with the cygwin32 libraries). @@ -42,6 +45,8 @@ Some simple programs (fs, vos and pts). Programs for acquiring tokens (kauth, afslog) are not included but are part of the kth-krb distribution. +An experimental AFS server called milko. + 5. What's the status or arla? This is a snapshot and pre-greek letters. @@ -49,7 +54,7 @@ This is a snapshot and pre-greek letters. Most of the functionality is there. You can read and write files and directories, with or without authentication. It's not as stable or high-performing as we would like, yet. It only does whole-file -caching, but that's probably good enough. +caching, but that's probably good enough for now. 6. What do I need to run arla? @@ -86,13 +91,22 @@ See the file INSTALL Report it with as much detail as possible (including patches) to <arla-drinkers@stacken.kth.se>. +If you find a bug, and do not have a clue what is wrong, please run +arlad with `arlad -n -z --debug=almost-all' and append the output the +the mail. You can also turn on debug on an already running arlad with +`fs arladebug <debug-level>'. To enable debugging in the xfs kernel +module, use `fs xfsdebug <debug-level>'. The output will end up in +your syslog (like /var/log/messages or /var/adm/messages). + +Without this info we are probably as lost as you are. + 9. How do I adjust the amount of debug information? Both arlad and the xfs (the kernel module) has variables for controlling what type of debug messages should be printed. -They are controlled by the `--debug' option to arlad and by setting -the `xfsdeb' variable in xfs (see xfs/<system>/xfs_deb.c). +They are controlled by the `--debug' option to arlad and then by +running `fs arladebug' and `fs xfsdebug'. 10. How hard is it to port arla to a new operating system? @@ -105,10 +119,9 @@ interested in doing the port, send mail to 11. Known problems. -OpenBSD 2.3 (current) and OpenBSD 2.2 on some architectures have -serious problems with mmap. If arlad doesn't seem to work om your -system run configure with `--disable-mmap'. This problem has only -been noticed on sun4m platforms (probably just Microsparc 2). +OpenBSD on some architectures have serious problems with mmap. If arlad +doesn't seem to work om your system run configure with `--disable-mmap'. +This problem has only been noticed on sun4m platforms. If you have problems with stale data cached or arlad is misbehaving a lot try zapping the entire cache directory (`/usr/arla/cache' per @@ -117,6 +130,10 @@ default) and restarting arlad. If you are using Digital's cc you should probably use the options -std1 (ie setting CC to "cc -std1" when runing configure). +Solaris does not have an `memcpy' in the kernel and gcc can somtimes +generate calls to it. If you get unresolved symbol errors on memcpy, +either compile with Sun's compiler or define memcpy in terms of bcopy. + 12. How can I help? With code. Send us bug-reports and/or patches. @@ -138,11 +155,13 @@ lwp and rx are copyrighted by IBM. We're grateful to Derrick J Brashear <shadow@dementia.org> and Jim Doyle <jrd@bu.edu> for making them available. -the rxkad implementation was written by Björn Grönvall <bg@sics.se> +The rxkad implementation was written by Björn Grönvall <bg@sics.se> and is also part of the kth-krb distribution. editline was written by Simmule Turner and Rich Salz. +The code for disconnected operation was written by Wuwei Shen. + The code for gluing these together were written by ourselves. <arla-drinkers@stacken.kth.se> diff --git a/usr.sbin/afs/src/THANKS b/usr.sbin/afs/src/THANKS index 0781bd93866..4176e515c98 100644 --- a/usr.sbin/afs/src/THANKS +++ b/usr.sbin/afs/src/THANKS @@ -21,3 +21,12 @@ John Hawkinson <jhawk@MIT.EDU> Karl Ramm <kcr@MIT.EDU> Mark Eichin <eichin@kitten.gen.ma.us> Per Boussard T/ED <Per.Boussard@era-t.ericsson.se> +Dima Ruban <dima@best.net> +Max <davros@cyclone.Stanford.EDU> +Andrzej Filinski <andrzej@daimi.aau.dk> +Chuck Lever <chuckl@netscape.com> +WUWEI SHEN <wwshen@engin.umich.edu> +Cheng Jin <chengjin@eecs.umich.edu> +Paul Callaway <pcallawa@umich.edu> +Brandon S. Allbery <allbery@ece.cmu.edu> +Ken Raeburn <raeburn@raeburn.org> diff --git a/usr.sbin/afs/src/TODO b/usr.sbin/afs/src/TODO index edb1cbfb5da..5881e78660f 100644 --- a/usr.sbin/afs/src/TODO +++ b/usr.sbin/afs/src/TODO @@ -1,16 +1,28 @@ -$Id: TODO,v 1.1.1.1 1998/09/14 21:52:52 art Exp $ +$Id: TODO,v 1.2 1999/04/30 01:59:04 art Exp $ TODO-list, in no particular order. Please mail arla-drinkers@stacken.kth.se if you want to work on any of these things so we don't do double work. +*/Makefile.in: homogenize + +*/Makefile.in: allow creation of shared libraries + +tests: make sure all tests work everywhere + +tests: figure out what output should be sent where and with what options + arlad/xfs: More stable, bugfixes etc xfs/solaris: verify multithreadness xfs+arlad: implement advisory locking +xfs: support building as part of the kernel + +xfs/irix: port to Irix 6.5 + arlad: disconnected mode arlad: remove unused stuff from FCacheEntry @@ -20,16 +32,21 @@ arlad: fallback to disconnected mode if networking is not working arlad/xfs: return from open before fetching the whole file -test suite +arlad: more consistency checks before recovering state + +more tests in test suite + +cache in blocks (iff ?) file to large to fit in cache ? + +rewrite milko (vfs-switch ?) + +autoconf -j OPTIMIZATIONS This is a list of posible optimizations that could be done to different parts of arla. - - Store cache files in inodes. Bypass the upper layer of VFS to read and - write cache. - - Delay reads and writes to cache and AFS-servers. Make the more operations in one batch. (possible with rx?) Especially directories don't have to be synced for every operation. diff --git a/usr.sbin/afs/src/appl/appl_locl.h b/usr.sbin/afs/src/appl/appl_locl.h index bdbcd698c8c..978fac8b5ad 100644 --- a/usr.sbin/afs/src/appl/appl_locl.h +++ b/usr.sbin/afs/src/appl/appl_locl.h @@ -1,6 +1,7 @@ -/* $OpenBSD: appl_locl.h,v 1.1.1.1 1998/09/14 21:52:52 art Exp $ */ +/* $OpenBSD: appl_locl.h,v 1.2 1999/04/30 01:59:04 art Exp $ */ +/* $OpenBSD: appl_locl.h,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +38,7 @@ * SUCH DAMAGE. */ -/* $KTH: appl_locl.h,v 1.24 1998/07/19 23:50:16 mattiasa Exp $ */ +/* $KTH: appl_locl.h,v 1.26 1999/03/03 15:34:48 assar Exp $ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -90,13 +91,18 @@ #include <getarg.h> #include <err.h> +#include <assert.h> + #include <cb.h> #include <time.h> #include <lock.h> #include <ip.h> #include <ctype.h> +#include <rx/rx.h> +#include <rx/rx_null.h> +#include <rx/rxgencon.h> #ifdef KERBEROS -#include <kerberosIV/krb.h> +#include <krb.h> #include <des.h> #include <rxkad.h> #endif diff --git a/usr.sbin/afs/src/appl/arlalib.c b/usr.sbin/afs/src/appl/arlalib.c index 6b6c85f1535..16e187c7155 100644 --- a/usr.sbin/afs/src/appl/arlalib.c +++ b/usr.sbin/afs/src/appl/arlalib.c @@ -1,6 +1,6 @@ -/* $OpenBSD: arlalib.c,v 1.1.1.1 1998/09/14 21:52:52 art Exp $ */ +/* $OpenBSD: arlalib.c,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,7 +39,7 @@ #include "appl_locl.h" -RCSID("$KTH: arlalib.c,v 1.12 1998/07/19 23:58:58 mattiasa Exp $"); +RCSID("$KTH: arlalib.c,v 1.19 1999/04/06 18:31:30 lha Exp $"); static struct rx_securityClass *secureobj = NULL ; @@ -47,40 +47,55 @@ int secureindex = -1 ; int rx_initlizedp = 0; #ifdef KERBEROS + static int -arlalib_get_cred(const char *host, CREDENTIALS *c) +get_cred(const char *princ, const char *inst, const char *krealm, + CREDENTIALS *c) +{ + KTEXT_ST foo; + int k_errno; + + k_errno = krb_get_cred((char*)princ, (char*)inst, (char*)krealm, c); + + if(k_errno != KSUCCESS) { + k_errno = krb_mk_req(&foo, (char*)princ, (char*)inst, (char*)krealm, 0); + if (k_errno == KSUCCESS) + k_errno = krb_get_cred((char*)princ, (char*)inst, (char*)krealm, c); + } + return k_errno; +} + +static int +arlalib_get_cred(const char *cell, const char *host, CREDENTIALS *c, + arlalib_authflags_t auth) { char krealm[REALM_SZ]; char *rrealm; - char *princ = "afs"; - char *inst = "" ; - KTEXT_ST foo; int k_errno; + int ret; - rrealm = krb_realmofhost(host); - strncpy(krealm, rrealm, REALM_SZ); - krealm[REALM_SZ-1] = '\0'; - - - k_errno = krb_get_cred(princ, inst, krealm, c); - - if(k_errno != KSUCCESS) { - k_errno = krb_mk_req(&foo, princ, inst, krealm, 0); - if (k_errno == KSUCCESS) - k_errno = krb_get_cred(princ, inst, krealm, c); + if (auth & (AUTHFLAGS_TICKET|AUTHFLAGS_ANY)) { + rrealm = krb_realmofhost(host); + strncpy(krealm, rrealm, REALM_SZ); + krealm[REALM_SZ-1] = '\0'; + + k_errno = get_cred("afs", cell ? cell : "", krealm, c); + if (k_errno != KSUCCESS) + k_errno = get_cred("afs", "", krealm, c); + + if (k_errno != KSUCCESS) { + fprintf(stderr, + "Can't get a ticket for realm %s: %s\n", + krealm, krb_get_err_text(k_errno)); + return -1; + } + ret = k_errno; } - - if (k_errno != KSUCCESS) { - fprintf(stderr, "Can't get a ticket for realm %s\n", krealm); - return -1; - } - - return k_errno; + return ret; } #endif /* KERBEROS */ - int arlalib_getservername(u_int32_t serverNumber, char **servername) { @@ -90,15 +105,20 @@ arlalib_getservername(u_int32_t serverNumber, char **servername) if (he != NULL) *servername = strdup(he->h_name); - else - *servername = strdup(""); + else { + struct in_addr addr; + addr.s_addr = serverNumber; + + *servername = strdup(inet_ntoa(addr)); + } return (*servername == NULL); } -static struct rx_securityClass* -arlalib_getsecurecontext(const char *host, int noauth) +struct rx_securityClass* +arlalib_getsecurecontext(const char *cell, const char *host, + arlalib_authflags_t auth) { #ifdef KERBEROS CREDENTIALS c; @@ -110,15 +130,15 @@ arlalib_getsecurecontext(const char *host, int noauth) #ifdef KERBEROS - if (!noauth && - arlalib_get_cred(host, &c) == KSUCCESS) { + if (auth && + arlalib_get_cred(cell, host, &c, auth) == KSUCCESS) { sec = rxkad_NewClientSecurityObject(rxkad_auth, &c.session, c.kvno, c.ticket_st.length, c.ticket_st.dat); - secureindex = 2 ; + secureindex = 2; } else { #endif /* KERBEROS */ @@ -137,9 +157,9 @@ arlalib_getsecurecontext(const char *host, int noauth) struct rx_connection * -arlalib_getconnbyaddr(int32_t addr, +arlalib_getconnbyaddr(const char *cell, int32_t addr, const char *host, int32_t port, int32_t servid, - int noauth) + arlalib_authflags_t auth) { struct rx_connection *conn; int allocedhost = 0; @@ -156,7 +176,7 @@ arlalib_getconnbyaddr(int32_t addr, host = serv; } - if (arlalib_getsecurecontext(host, noauth)== NULL) + if (arlalib_getsecurecontext(cell, host, auth)== NULL) return NULL; conn = rx_NewConnection (addr, @@ -175,8 +195,9 @@ arlalib_getconnbyaddr(int32_t addr, } struct rx_connection * -arlalib_getconnbyname(const char *host, - int32_t port, int32_t servid, int noauth) +arlalib_getconnbyname(const char *cell, const char *host, + int32_t port, int32_t servid, + arlalib_authflags_t auth) { struct in_addr server; @@ -185,8 +206,8 @@ arlalib_getconnbyname(const char *host, return NULL; } - return arlalib_getconnbyaddr(server.s_addr, host, port, servid, noauth); - + return arlalib_getconnbyaddr(cell, server.s_addr, host, port, servid, + auth); } int @@ -214,7 +235,7 @@ arlalib_destroyconn(struct rx_connection *conn) int arlalib_getsyncsite(const char *cell, const char *host, int32_t port, - u_int32_t *synchost, int noauth) + u_int32_t *synchost, arlalib_authflags_t auth) { struct rx_connection *conn; ubik_debug db; @@ -225,15 +246,22 @@ arlalib_getsyncsite(const char *cell, const char *host, int32_t port, if (cell == NULL && host != NULL) cell = cell_getcellbyhost(host); - if (cell == NULL) + if (cell == NULL) { cell = cell_getthiscell(); - if (host == NULL) + if (cell == NULL) + return ENOENT; + } + if (host == NULL) { host = cell_findnamedbbyname (cell); + if (host == NULL) + return ENOENT; + } - conn = arlalib_getconnbyname(host, + conn = arlalib_getconnbyname(cell, + host, port, VOTE_SERVICE_ID, - noauth); + auth); if (conn == NULL) return ENETDOWN; @@ -246,3 +274,33 @@ arlalib_getsyncsite(const char *cell, const char *host, int32_t port, return error; } + +/* + * get a arlalib_authflags_t type + */ + +arlalib_authflags_t +arlalib_getauthflag (int noauth, + int localauth, + int ticket, + int token) +{ + arlalib_authflags_t ret = AUTHFLAGS_ANY; + + if (noauth) + ret = AUTHFLAGS_NOAUTH; + if (localauth) + ret |= AUTHFLAGS_LOCALAUTH; + if (ticket) + ret |= AUTHFLAGS_TICKET; + if (token) + ret |= AUTHFLAGS_TOKEN; + + return ret; +} + +/* + * + */ + + diff --git a/usr.sbin/afs/src/appl/arlalib.h b/usr.sbin/afs/src/appl/arlalib.h index b0b9e8430dc..f33bf1dbc0e 100644 --- a/usr.sbin/afs/src/appl/arlalib.h +++ b/usr.sbin/afs/src/appl/arlalib.h @@ -1,6 +1,6 @@ -/* $OpenBSD: arlalib.h,v 1.1.1.1 1998/09/14 21:52:52 art Exp $ */ +/* $OpenBSD: arlalib.h,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,35 +37,52 @@ * SUCH DAMAGE. */ -/* $KTH: arlalib.h,v 1.8 1998/07/24 19:55:48 lha Exp $ */ +/* $KTH: arlalib.h,v 1.21 1999/03/04 09:17:30 lha Exp $ */ #ifndef ARLALIB_H #define ARLALIB_H 1 -#ifdef KERBEROS -int get_cred(char *host, CREDENTIALS *c); -#endif /* KERBEROS */ +/* + * Credentinals + */ + +typedef enum { AUTHFLAGS_NOAUTH = 0, + AUTHFLAGS_ANY = 1, + AUTHFLAGS_LOCALAUTH = 2, + AUTHFLAGS_TICKET = 4, + AUTHFLAGS_TOKEN = 8 } arlalib_authflags_t; + +arlalib_authflags_t +arlalib_getauthflag (int noauth, + int localauth, + int ticket, + int token); + +/* + * Connections + */ struct rx_connection * -arlalib_getconnbyaddr(int32_t addr, const char *host, - int32_t port, int32_t servid, int noauth); +arlalib_getconnbyaddr(const char *cell, int32_t addr, const char *host, + int32_t port, int32_t servid, + arlalib_authflags_t auth); struct rx_connection * -arlalib_getconnbyname(const char *host, int32_t port, int32_t servid, - int noauth); +arlalib_getconnbyname(const char *cell, const char *host, + int32_t port, int32_t servid, + arlalib_authflags_t auth); int arlalib_destroyconn(struct rx_connection *conn); int arlalib_getservername(u_int32_t serverNumber, char **servername); int arlalib_getsyncsite(const char *cell, const char *host, int32_t port, - u_int32_t *synchost, int notauth); - + u_int32_t *synchost, arlalib_authflags_t auth); /* * Wrappers around pioctl calls */ -void fserr(char *progname, int error, char *realpath); +void fserr(const char *progname, int error, const char *realpath); int fs_getfid (char *path, VenusFid *fid); int fs_getfilecellname (char *path, char *cell, size_t len); @@ -85,6 +102,47 @@ int fs_getfprio(VenusFid fid, int16_t *prio); int fs_setmaxfprio(int16_t maxprio); int fs_getmaxfprio(int16_t *maxprio); +int fs_gcpags(void); + +int fs_getfilecachestats(u_int32_t *max_kbytes, u_int32_t *used_kbytes, + u_int32_t *max_vnodes, u_int32_t *used_vnodes); + +int fs_getaviatorstats(u_int32_t *max_workers, + u_int32_t *used_workers); + +int fs_checkservers(char *cell, int32_t flags, + u_int32_t *hosts, int numhosts); + +int +fs_set_sysname (const char *sys); + +int +fs_get_sysname (char *sys, size_t sys_sz); + +int +fs_setcache(int lv, int hv, int lb, int hb); + +int +fs_wscell (char *cell, size_t cell_sz); + +int +fs_flushvolume (const char *path); + +int +fs_flush (const char *path); + +int +fs_venuslog (void); + +int +fs_newcell (const char *cell, int nservers, char **servers); + +int +fs_getcells (int32_t num, u_int32_t *server, size_t server_sz, + char *cell, size_t cell_sz); + +int +fs_getcellstatus (char *cellname, u_int32_t *flags); #endif /* ARLALIB_H */ diff --git a/usr.sbin/afs/src/appl/fs.c b/usr.sbin/afs/src/appl/fs.c index 96cd25f8ff9..46e447c4bcc 100644 --- a/usr.sbin/afs/src/appl/fs.c +++ b/usr.sbin/afs/src/appl/fs.c @@ -1,6 +1,6 @@ -/* $OpenBSD: fs.c,v 1.1.1.1 1998/09/14 21:52:52 art Exp $ */ +/* $OpenBSD: fs.c,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -40,14 +40,63 @@ #include <sl.h> #include "appl_locl.h" -#include <kerberosIV/kafs.h> +#include <kafs.h> +#include <parse_units.h> +#include <xfs/xfs_debug.h> +#include <xfs/xfs_deb.h> #include "fs_local.h" - -RCSID("$KTH: fs.c,v 1.41 1998/07/28 14:35:06 assar Exp $"); +#include <arladeb.h> + +RCSID("$KTH: fs.c,v 1.65 1999/03/06 14:36:37 lha Exp $"); + +static int empty_cmd (int argc, char **argv); +static int apropos_cmd (int argc, char **argv); +static int arladebug_cmd (int argc, char **argv); +static int checkservers_cmd (int argc, char **argv); +static int diskfree_cmd (int argc, char **argv); +static int examine_cmd (int argc, char **argv); +static int flush_cmd (int argc, char **argv); +static int flushvolume_cmd (int argc, char **argv); +static int gc_cmd (int argc, char **argv); +static int getcache_cmd (int argc, char **argv); +static int getcrypt_cmd (int argc, char **argv); +static int getcellstatus_cmd (int argc, char **argv); +static int getfid_cmd (int argc, char **argv); +static int getprio_cmd (int argc, char **argv); +static int getmaxprio_cmd (int argc, char **argv); +static int help_cmd (int argc, char **argv); +static int listacl_cmd (int argc, char **argv); +static int listcells_cmd (int argc, char **argv); +static int suidcells_cmd (int argc, char **argv); +static int listquota_cmd (int argc, char **argv); +static int lsmount_cmd (int argc, char **argv); +static int mkmount_cmd (int argc, char **argv); +static int connect_cmd (int argc, char **argv); +static int newcell_cmd (int argc, char **argv); +static int nop_cmd (int argc, char **argv); +static int quit_cmd (int argc, char **argv); +static int quota_cmd (int argc, char **argv); +static int rmmount_cmd (int argc, char **argv); +static int rmprio_cmd (int argc, char **argv); +static int setacl_cmd (int argc, char **argv); +static int setcache_cmd (int argc, char **argv); +static int setprio_cmd (int argc, char **argv); +static int setmaxprio_cmd (int argc, char **argv); +static int setquota_cmd (int argc, char **argv); +static int setcrypt_cmd (int argc, char **argv); +static int sysname_cmd (int argc, char **argv); +static int fsversion_cmd (int argc, char **argv); +static int venuslog_cmd (int argc, char **argv); +static int whereis_cmd (int argc, char **argv); +static int whichcell_cmd (int argc, char **argv); +static int wscell_cmd (int argc, char **argv); +static int xfsdebug_cmd (int argc, char **argv); +static int xfsdebug_print_cmd (int argc, char **argv); static SL_cmd cmds[] = { - {"apropos", empty_cmd, "locate commands by keyword"}, - {"checkservers", empty_cmd, "check servers in servers"}, + {"apropos", apropos_cmd, "locate commands by keyword"}, + {"arladebug", arladebug_cmd, "tweek arla-debugging flags"}, + {"checkservers", checkservers_cmd,"check if servers is up"}, {"checkvolumes", empty_cmd, "lookup mappings between volume-Id's and names"}, {"cleanacl", empty_cmd, "clear out numeric acl-entries"}, {"copyacl", empty_cmd, "copy acl"}, @@ -55,7 +104,8 @@ static SL_cmd cmds[] = { {"examine", examine_cmd, "examine volume status"}, {"flush", flush_cmd, "remove file from cache"}, {"flushvolume", flushvolume_cmd, "remove volumedata (and files in volume) from cache"}, - {"getcacheparms", empty_cmd, "get cache usage"}, + {"gcpags", gc_cmd, "garbage collect pags"}, + {"getcacheparms", getcache_cmd, "get cache usage"}, {"getcrypt", getcrypt_cmd, "get encrypt status"}, {"getcellstatus", getcellstatus_cmd, "get suid cell status"}, {"getfid", getfid_cmd, "get fid"}, @@ -75,8 +125,8 @@ static SL_cmd cmds[] = { {"mkmount", mkmount_cmd, "create mount point"}, {"connect", connect_cmd, "connect mode"}, {"monitor", empty_cmd, "set remote logging host"}, - {"newcell", empty_cmd, "add new cell"}, - {"nop", nop_cmd, "do a picol-nop"}, + {"newcell", newcell_cmd, "add new cell"}, + {"nop", nop_cmd, "do a pioctl-nop"}, {"quit", quit_cmd, "leave interactive mode"}, {"exit"}, {"quota", quota_cmd, "show quota"}, @@ -97,12 +147,15 @@ static SL_cmd cmds[] = { {"setcrypt", setcrypt_cmd, "set encryption on/off"}, {"setvol", empty_cmd, "change status of volume"}, /* {"storebehind", empty_cmd, ""}, */ + {"suidcells", suidcells_cmd, "list status of cells"}, {"sysname", sysname_cmd, "read/change sysname"}, {"version", fsversion_cmd, "get version of fs and fs_lib"}, {"venuslog", venuslog_cmd, "make arlad print status"}, {"whereis", whereis_cmd, "show server(s) of file"}, {"whichcell", whichcell_cmd, "show cell of file"}, {"wscell", wscell_cmd, "display cell of workstation"}, + {"xfsdebug", xfsdebug_cmd, "tweek xfs-debugging flags"}, + {"xfsprint", xfsdebug_print_cmd,"make xfs print debug info"}, {NULL} }; @@ -131,6 +184,7 @@ main(int argc, char **argv) return ret; } + static int nop_cmd(int argc, char **argv) { @@ -149,6 +203,75 @@ connect_usage(void) return 0; } +static int +checkservers_cmd (int argc, char **argv) +{ + char *cell = NULL; + int flags = 0; + int nopoll = 0; + int onlyfs = 0; + int optind = 0; + u_int32_t hosts[CKSERV_MAXSERVERS + 1]; + int ret; + int i; + + struct getargs cksargs[] = { + {"cell", 0, arg_string, NULL, "cell", NULL}, + {"onlyfs", 0, arg_flag, NULL, "poll only fs-servers", NULL}, + {"nopoll", 0, arg_flag, NULL, "dont ping each server, " + "use internal info", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = cksargs; + arg->value = &cell; arg++; + arg->value = &onlyfs; arg++; + arg->value = &nopoll; arg++; + + if (getarg (cksargs, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(cksargs, "checkservers", NULL, ARG_AFSSTYLE); + return 0; + } + + if (onlyfs) + flags |= CKSERV_FSONLY; + if (nopoll) + flags |= CKSERV_DONTPING; + + ret = fs_checkservers(cell, flags, hosts, sizeof(hosts)/sizeof(hosts[0])); + if (ret) { + if (ret == ENOENT) + fprintf (stderr, "%s: cell `%s' doesn't exist\n", + PROGNAME, cell); + else + fserr (PROGNAME, ret, NULL); + return 0; + } + + if (hosts[0] == 0) + printf ("All servers are up"); + + for (i = 1; i < min(CKSERV_MAXSERVERS, hosts[0]) + 1; ++i) { + if (hosts[i]) { + struct hostent *he; + + he = gethostbyaddr ((char *)&hosts[i], sizeof(hosts[i]), AF_INET); + + if (he != NULL) { + printf ("%s ", he->h_name); + } else { + struct in_addr in; + + in.s_addr = hosts[i]; + printf ("%s ", inet_ntoa(in)); + + } + } + } + printf("\n"); + return 0; +} + static int connect_cmd(int argc, char **argv) { @@ -179,7 +302,7 @@ connect_cmd(int argc, char **argv) printf("Unknown or error\n"); break; } - return flags; + return 0; } if (strncmp("dis", *argv, 3) == 0) @@ -244,16 +367,16 @@ examine_cmd (int argc, char **argv) static int flushvolume_cmd (int argc, char **argv) { - int i; + int i; argc--; argv++; if (argc == 0) - afs_flushvolume ("."); + fs_flushvolume ("."); else for (i = 0; i < argc; i++) - afs_flushvolume (argv[i]); + fs_flushvolume (argv[i]); return 0; } @@ -267,10 +390,28 @@ flush_cmd (int argc, char **argv) argv++; if (argc == 0) - afs_flush ("."); + fs_flush ("."); else for (i = 0; i < argc; i++) - afs_flush (argv[i]); + fs_flush (argv[i]); + + return 0; +} + +static int +gc_cmd (int argc, char **argv) +{ + int ret; + + argc--; + argv++; + + if (argc != 0) + printf ("gcpags: extraneous arguments ignored\n"); + + ret = fs_gcpags(); + if (ret) + fserr(PROGNAME, ret, NULL); return 0; } @@ -443,14 +584,24 @@ setprio_cmd (int argc, char **argv) static int help_cmd (int argc, char **argv) { - SL_cmd *cmd = cmds; + SL_cmd *cmd; - while (cmd->name != NULL) { + for (cmd = cmds; cmd->name != NULL; ++cmd) if (cmd->usage != NULL) - printf ("%-20s%s\n", cmd->name, cmd->usage); - cmd++; + printf ("%-20s%s\n", cmd->name, cmd->usage); + + return 0; +} + +static int +apropos_cmd (int argc, char **argv) +{ + if (argc == 0) { + printf ("apropos: missing topic\n"); + return 0; } + sl_apropos (cmds, argv[1]); return 0; } @@ -504,7 +655,97 @@ listacl_cmd (int argc, char **argv) static int listcells_cmd (int argc, char **argv) { - afs_listcells (); + int printhosts = 1; + int resolve = 1; + int printsuid = 0; + int optind = 0; + + struct getargs lcargs[] = { + {"servers", 's', arg_negative_flag, + NULL,"print servers in cell", NULL}, + {"resolve", 'r', arg_negative_flag, + NULL,"resolve hostnames", NULL}, + {"suid", 'p', arg_flag, + NULL,"print if cell is suid", NULL }, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = lcargs; + arg->value = &printhosts; arg++; + arg->value = &resolve; arg++; + arg->value = &printsuid; arg++; + + if (getarg (lcargs, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(lcargs, "listcells", NULL, ARG_AFSSTYLE); + return 0; + } + + printf ("%d %d %d\n", printhosts, resolve, printsuid); + + afs_listcells (printhosts,resolve,printsuid); + + return 0; +} + +static int +suidcells_cmd (int argc, char **argv) +{ + afs_listcells (0, 0, 1); + + return 0; +} + +static int +newcell_cmd (int argc, char **argv) +{ + char *cell = NULL; + getarg_strings servers = { 0, NULL }; + int ret, help = 0; + int optind = 0; + + struct getargs ncargs[] = { + {"cell", 'c', arg_string, + NULL, "new cell", NULL}, + {"servers", 's', arg_strings, + NULL, "server in cell", "one server"}, + {"help", 'h', arg_flag, + NULL, "get help", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = ncargs; + arg->value = &cell; arg++; + arg->value = &servers; arg++; + arg->value = &help; arg++; + + if (getarg (ncargs, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(ncargs, "newcell", NULL, ARG_AFSSTYLE); + return 0; + } + + if (help) { + arg_printusage(ncargs, "newcell", NULL, ARG_AFSSTYLE); + goto out; + } + + if (cell == NULL) { + fprintf (stderr, "You have to give a cell\n"); + goto out; + } + + if (servers.num_strings == 0) { + fprintf (stderr, "You didn't give servers, will use DNS\n"); + goto out; + } + + ret = fs_newcell (cell, servers.num_strings, servers.strings); + if (ret) + fprintf (stderr, "fs_newcell failed with %s (%d)\n", + koerr_gettext(ret), ret); + + out: + if (servers.strings) + free (servers.strings); return 0; } @@ -588,10 +829,10 @@ getmaxprio_cmd (int argc, char **argv) ret = fs_getmaxfprio(&prio); if (ret) { fserr(PROGNAME, ret, NULL); - return ret; + return 0; } - return ret; + return 0; } @@ -653,14 +894,15 @@ setcache_cmd (int argc, char **argv) sscanf(argv[1], "%d", &hv) && sscanf(argv[2], "%d", &lb) && sscanf(argv[3], "%d", &hb)) - return afs_setcache(lv, hv, lb, hb); + afs_setcache(lv, hv, lb, hb); else setcache_usage(); - } else + } else { if (sscanf(argv[0], "%d", &lv)) afs_setcache(lv, 0, 0, 0); else setcache_usage(); + } return 0; } @@ -766,9 +1008,9 @@ sysname_cmd (int argc, char **argv) argc--; argv++; if (argc == 0) - afs_sysname (NULL); + afs_print_sysname (); else - afs_sysname (argv[0]); + afs_set_sysname (argv[0]); return 0; } @@ -818,8 +1060,9 @@ wscell_cmd (int argc, char **argv) static int venuslog_cmd (int argc, char **argv) { - afs_venuslog(); - + int ret = fs_venuslog(); + if (ret) + fserr (PROGNAME, ret, NULL); return 0; } @@ -830,12 +1073,231 @@ fsversion_cmd(int argc, char **argv) printf ("version: extraneous arguments ignored\n"); printf("fs: %s\nfs_lib: %s\n", - "$KTH: fs.c,v 1.41 1998/07/28 14:35:06 assar Exp $", + "$KTH: fs.c,v 1.65 1999/03/06 14:36:37 lha Exp $", fslib_version()); return 0; } -void afs_getfid(char *path) +static const unsigned all = (0 +#ifdef HAVE_XDEBDEV + | XDEBDEV +#endif +#ifdef HAVE_XDEBMSG + | XDEBMSG +#endif +#ifdef HAVE_XDEBDNLC + | XDEBDNLC +#endif +#ifdef HAVE_XDEBNODE + | XDEBNODE +#endif +#ifdef HAVE_XDEBVNOPS + | XDEBVNOPS +#endif +#ifdef HAVE_XDEBVFOPS + | XDEBVFOPS +#endif +#ifdef HAVE_XDEBLKM + | XDEBLKM +#endif +#ifdef HAVE_XDEBSYS + | XDEBSYS +#endif +#ifdef HAVE_XDEBMEM + | XDEBMEM +#endif +#ifdef HAVE_XDEBREADDIR + | XDEBREADDIR +#endif +#ifdef HAVE_XDEBLOCK + | XDEBLOCK +#endif +#ifdef HAVE_XDEBCACHE + | XDEBCACHE +#endif + ); + +static const unsigned almost_all_mask = (0 +#ifdef HAVE_XDEBDEV + | XDEBDEV +#endif +#ifdef HAVE_XDEBMEM + | XDEBMEM +#endif +#ifdef HAVE_XDEBREADDIR + | XDEBREADDIR +#endif + ); + +static struct units xfsdebug_units[] = { + {"all", 0}, + {"almost-all", 0}, +#ifdef HAVE_XDEBCACHE + {"cache", XDEBCACHE}, +#endif +#ifdef HAVE_XDEBLOCK + {"lock", XDEBLOCK}, +#endif +#ifdef HAVE_XDEBREADDIR + {"readdir", XDEBREADDIR}, +#endif +#ifdef HAVE_XDEBMEM + {"mem", XDEBMEM}, +#endif +#ifdef HAVE_XDEBSYS + {"sys", XDEBSYS}, +#endif +#ifdef HAVE_XDEBLKM + {"lkm", XDEBLKM}, +#endif +#ifdef HAVE_XDEBVFOPS + {"vfsops", XDEBVFOPS}, +#endif +#ifdef HAVE_XDEBVNOPS + {"vnops", XDEBVNOPS}, +#endif +#ifdef HAVE_XDEBNODE + {"node", XDEBNODE}, +#endif +#ifdef HAVE_XDEBDNLC + {"dnlc", XDEBDNLC}, +#endif +#ifdef HAVE_XDEBMSG + {"msg", XDEBMSG}, +#endif +#ifdef HAVE_XDEBDEV + {"dev", XDEBDEV}, +#endif + {"none", 0 }, + { NULL, 0 } +}; + +static int +xfsdebug_cmd (int argc, char **argv) +{ + int ret; + int flags; + + xfsdebug_units[0].mult = all; + xfsdebug_units[1].mult = all & ~almost_all_mask; + + if (argc != 1 && argc != 2) { + fprintf (stderr, "usage: xfsdebug ["); + print_flags_table (xfsdebug_units, stderr); + fprintf (stderr, "]\n"); + return 0; + } + + ret = xfs_debug (-1, &flags); + if (ret) { + fprintf (stderr, "xfs_debug: %s\n", strerror(ret)); + return 0; + } + + if (argc == 1) { + char buf[1024]; + + unparse_flags (flags, xfsdebug_units, buf, sizeof(buf)); + printf("xfsdebug is: %s\n", buf); + } else if (argc == 2) { + char *textflags; + + textflags = argv[1]; + + ret = parse_flags (textflags, xfsdebug_units, flags); + + if (ret < 0) { + fprintf (stderr, "xfsdebug: unknown/bad flags `%s'\n", + textflags); + return 0; + } + + flags = ret; + ret = xfs_debug(flags, NULL); + if (ret) + fprintf (stderr, "xfs_debug: %s\n", strerror(ret)); + } + return 0; +} + +static int +xfsdebug_print_cmd (int argc, char **argv) +{ + int ret; + int flags = 0; + char *textflags; + + xfsdebug_units[0].mult = all; + xfsdebug_units[1].mult = all & ~almost_all_mask; + + if (argc != 2) { + fprintf (stderr, "usage: xfsprint <"); + print_flags_table (xfsdebug_units, stderr); + fprintf (stderr, ">\n"); + return 0; + } + + textflags = argv[1]; + + ret = parse_flags (textflags, xfsdebug_units, flags); + + if (ret < 0) { + fprintf (stderr, "xfsprint: unknown/bad flags `%s'\n", + textflags); + return 0; + } + + flags = ret; + ret = xfs_debug_print(flags); + if (ret) + fprintf (stderr, "xfsprint: %s\n", strerror(ret)); + return 0; +} + +static int +arladebug_cmd (int argc, char **argv) +{ + int ret; + int flags; + + if (argc != 1 && argc != 2) { + fprintf (stderr, "usage: arladebug ["); + arla_log_print_levels (stderr); + fprintf (stderr, "]\n"); + return 0; + } + + ret = arla_debug (-1, &flags); + if (ret) { + fprintf (stderr, "arla_debug: %s\n", strerror(ret)); + return 0; + } + + if (argc == 1) { + char buf[1024]; + + unparse_flags (flags, arla_deb_units, buf, sizeof(buf)); + printf ("arladebug is: %s\n", buf); + } else if (argc == 2) { + const char *textflags = argv[1]; + + ret = parse_flags (textflags, arla_deb_units, flags); + if (ret < 0) { + fprintf (stderr, "arladebug: unknown/bad flags `%s'\n", + textflags); + return 0; + } + + flags = ret; + ret = arla_debug (flags, NULL); + if (ret) + fprintf (stderr, "arla_debug: %s\n", strerror(ret)); + } + return 0; +} + +void +afs_getfid(char *path) { VenusFid fid; int ret; @@ -858,7 +1320,8 @@ void afs_getfid(char *path) } -void afs_listacl(char *path) +void +afs_listacl(char *path) { struct Acl *acl; struct AclEntry *position; @@ -918,7 +1381,8 @@ void afs_listacl(char *path) } } -void afs_setacl(char *path, char *user, char *rights) +void +afs_setacl(char *path, char *user, char *rights) { struct Acl *acl; struct AclEntry *position; @@ -1018,7 +1482,8 @@ void afs_setacl(char *path, char *user, char *rights) /* free(oldacl); and its contents */ } -struct Acl *afs_getacl(char *path) +struct Acl * +afs_getacl(char *path) { struct Acl *oldacl; struct ViceIoctl a_params; @@ -1099,53 +1564,41 @@ struct Acl *afs_getacl(char *path) return oldacl; } -void afs_sysname(char *name) +/* + * Print current sysname. + */ + +void +afs_print_sysname (void) { - struct ViceIoctl a_params; - int32_t get; - char *space=malloc(MAXSIZE); - char *curptr; + int ret; + char buf[2048]; - if(space == NULL) { - printf("fs: Out of memory\n"); - return; - } + ret = fs_get_sysname (buf, sizeof(buf)); + if (ret) + fserr (PROGNAME, ret, NULL); + else + printf ("Current sysname is `%s'\n", buf); +} - if(!name) { - get=0; - memcpy(space,&get,sizeof(int32_t)); - a_params.in_size=sizeof(int32_t); - } - else { - char *ptr=space; - get=1; - memcpy(space,&get,sizeof(int32_t)); - ptr+=sizeof(int32_t); - strncpy(ptr,name,100-sizeof(int32_t)); - a_params.in_size=sizeof(int32_t)+strlen(ptr)+1; - } - - a_params.out_size=MAXSIZE; - a_params.in=space; - a_params.out=space; - - if(k_pioctl(NULL,VIOC_AFS_SYSNAME,&a_params,1)==-1) { - fserr(PROGNAME, errno, NULL); - free(space); - return; - } +/* + * Set sysname + */ - curptr=a_params.out; - if(!name) { - curptr+=sizeof(int32_t); - printf("Current sysname is '%s'\n",curptr); - } +void +afs_set_sysname (const char *sys) +{ + int ret; + + ret = fs_set_sysname (sys); + if (ret) + fserr (PROGNAME, ret, NULL); else - printf("fs: new sysname set.\n"); - free(space); + printf ("fs: new sysname set to `%s'\n", sys); } -void afs_listquota(char *path) +void +afs_listquota(char *path) { struct ViceIoctl a_params; struct VolumeStatus *vs; @@ -1198,7 +1651,8 @@ void afs_listquota(char *path) free(a_params.out); } -void afs_setmaxquota(char *path, int32_t maxquota) +void +afs_setmaxquota(char *path, int32_t maxquota) { struct ViceIoctl a_params; struct VolumeStatus *vs; @@ -1240,7 +1694,8 @@ void afs_setmaxquota(char *path, int32_t maxquota) free(a_params.in); } -void afs_whereis(char *path) +void +afs_whereis(char *path) { struct ViceIoctl a_params; struct in_addr addr; @@ -1268,10 +1723,10 @@ void afs_whereis(char *path) while(curptr[i] && i<8) { struct hostent *h; - addr.s_addr=curptr[i]; + addr.s_addr=htonl(curptr[i]); h=gethostbyaddr((const char *) &addr, sizeof(addr), AF_INET); if (h == NULL) - printf ("%s", inet_ntoa (addr)); + printf (" %s", inet_ntoa (addr)); else { printf(" %s",h->h_name); } @@ -1281,7 +1736,13 @@ void afs_whereis(char *path) free(a_params.out); } -void afs_lsmount (char *path) +/* + * Separate `path' into directory and last component and call + * pioctl with `pioctl_cmd'. + */ + +static int +internal_mp (const char *path, int pioctl_cmd, char **res) { struct ViceIoctl a_params; char *last; @@ -1291,86 +1752,80 @@ void afs_lsmount (char *path) path_bkp = strdup (path); if (path_bkp == NULL) { printf ("fs: Out of memory\n"); - return; + return ENOMEM; } a_params.out = malloc (MAXSIZE); if (a_params.out == NULL) { printf ("fs: Out of memory\n"); free (path_bkp); + return ENOMEM; } /* If path contains more than the filename alone - split it */ last = strrchr (path_bkp, '/'); - if (last) { + if (last != NULL) { *last = '\0'; a_params.in = last + 1; - } - else - a_params.in = path; + } else + a_params.in = (char *)path; a_params.in_size = strlen (a_params.in) + 1; a_params.out_size = MAXSIZE; error = k_pioctl (last ? path_bkp : "." , - VIOC_AFS_STAT_MT_PT, &a_params, 0); - if ((error == -1) && (errno != EINVAL)) { - fserr(PROGNAME, errno, path); - free (a_params.out); - free (path_bkp); - return; - } else if ((error == -1) && (errno == EINVAL)) { - printf ("'%s' is not a mount point.\n", path); + pioctl_cmd, &a_params, 0); + if (error < 0) { + if (errno == EINVAL) { + fserr(PROGNAME, errno, path); + } else { + printf ("'%s' is not a mount point.\n", path); + } free (a_params.out); free (path_bkp); - return; + return errno; } - printf ("'%s' is a mount point for volume '%s'\n", path, a_params.out); - free (a_params.out); + if (res != NULL) + *res = a_params.out; + else + free (a_params.out); free (path_bkp); + return 0; } -void afs_rmmount (char *path) +void +afs_lsmount (const char *path) { - struct ViceIoctl a_params; - - a_params.in_size = strlen (path) + 1; - a_params.out_size = 0; - a_params.in = path; - a_params.out = NULL; + char *res; + int error = internal_mp (path, VIOC_AFS_STAT_MT_PT, &res); - if (k_pioctl (".", VIOC_AFS_DELETE_MT_PT, &a_params, 0) == -1) { - fserr(PROGNAME, errno, path); - return; + if (error == 0) { + printf ("'%s' is a mount point for volume '%s'\n", path, res); + free (res); } } +void +afs_rmmount (const char *path) +{ + internal_mp (path, VIOC_AFS_DELETE_MT_PT, NULL); +} + int afs_setcache(int lv, int hv, int lb, int hb) { - struct ViceIoctl a_params; - u_int32_t s[4]; - - s[0] = lv; - s[1] = hv; - s[2] = lb; - s[3] = hb; - - a_params.in_size = ((hv == 0) ? 1 : 4) * sizeof(u_int32_t); - a_params.out_size = 0; - a_params.in = (void *)s; - a_params.out = NULL; + int ret; - if (k_pioctl(NULL, VIOCSETCACHESIZE, &a_params, 0) == -1) { - fserr(PROGNAME, errno, "."); - return 0; - } - return 0; + ret = fs_setcache (lv, hv, lb, hb); + if (ret) + fserr(PROGNAME, ret, "."); + return ret; } -void afs_examine (char *path) +void +afs_examine (char *path) { struct ViceIoctl a_params; struct VolumeStatus *status; @@ -1385,7 +1840,7 @@ void afs_examine (char *path) return; } - if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 0) == -1) { + if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 1) == -1) { fserr(PROGNAME, errno, path); free(a_params.out); return; @@ -1405,76 +1860,20 @@ void afs_examine (char *path) void afs_wscell (void) { - struct ViceIoctl a_params; - - a_params.in_size = 0; - a_params.out_size = MAXSIZE; - a_params.in = NULL; - a_params.out = malloc (MAXSIZE); - - if (a_params.out == NULL) { - printf ("fs: Out of memory\n"); - return; - } + char buf[2048]; + int ret; - if (k_pioctl (NULL, VIOC_GET_WS_CELL, &a_params, 0) == -1) { - fserr(PROGNAME, errno, NULL); - free(a_params.out); + ret = fs_wscell (buf, sizeof(buf)); + if (ret) { + fserr (PROGNAME, ret, NULL); return; } - printf ("This workstation belongs to cell '%s'\n", a_params.out); - - free (a_params.out); -} - -void afs_flushvolume (char *path) -{ - struct ViceIoctl a_params; - - a_params.in_size = 0; - a_params.out_size = 0; - a_params.in = NULL; - a_params.out = NULL; - - if (k_pioctl (path, VIOC_FLUSHVOLUME, &a_params, 0) == -1) { - perror ("fs"); - exit (1); - } -} - -void afs_flush (char *path) -{ - struct ViceIoctl a_params; - - a_params.in_size = 0; - a_params.out_size = 0; - a_params.in = NULL; - a_params.out = NULL; - - if (k_pioctl (path, VIOCFLUSH, &a_params, 0) == -1) { - perror ("fs"); - exit (1); - } + printf ("This workstation belongs to cell '%s'\n", buf); } -void afs_venuslog (void) -{ - struct ViceIoctl a_params; - int32_t status = 0; /* XXX not really right, but anyway */ - - a_params.in_size = sizeof(int32_t); - a_params.out_size = 0; - a_params.in = (caddr_t) &status; - a_params.out = NULL; - - if (k_pioctl (NULL, VIOC_VENUSLOG, &a_params, 0) == -1) { - perror ("fs"); - exit (1); - } -} - -void afs_whichcell (char *path) +void +afs_whichcell (char *path) { struct ViceIoctl a_params; @@ -1498,7 +1897,8 @@ void afs_whichcell (char *path) free (a_params.out); } -void afs_diskfree (char *path) +void +afs_diskfree (char *path) { struct ViceIoctl a_params; struct VolumeStatus *status; @@ -1513,7 +1913,7 @@ void afs_diskfree (char *path) return; } - if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 0) == -1) { + if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 1) == -1) { fserr(PROGNAME, errno, path); free(a_params.out); return; @@ -1531,7 +1931,8 @@ void afs_diskfree (char *path) free (a_params.out); } -void afs_quota (char *path) +void +afs_quota (char *path) { struct ViceIoctl a_params; struct VolumeStatus *status; @@ -1546,7 +1947,7 @@ void afs_quota (char *path) return; } - if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 0) == -1) { + if (k_pioctl (path, VIOCGETVOLSTAT, &a_params, 1) == -1) { fserr(PROGNAME, errno, path); free(a_params.out); return; @@ -1555,12 +1956,13 @@ void afs_quota (char *path) status = (struct VolumeStatus *) a_params.out; printf("%.0f%% of quota used.\n", - (1.0 - (float) status->BlocksInUse / status->MaxQuota) * 100); + ((float) status->BlocksInUse / status->MaxQuota) * 100); free(a_params.out); } -void afs_getcellstatus (char *cell) +void +afs_getcellstatus (char *cell) { struct ViceIoctl a_params; int32_t flags; @@ -1578,60 +1980,94 @@ void afs_getcellstatus (char *cell) printf ("Cell %s status: %ssetuid allowed\n", cell, NO_SETUID_HONORED(flags) ? "no " : ""); } -void afs_listcells (void) +/* + * List all the known cells, with servers iff printservers, resolving + * IP addresses to names iff resolve and printing suid status iff + * suid. + */ + +int +afs_listcells (int printservers, int resolve, int suid) { - struct ViceIoctl a_params; struct in_addr addr; - int32_t *ip; - int32_t i, j; - - a_params.in_size = sizeof (int32_t); - a_params.out_size = MAXSIZE; - a_params.in = (char *) &i; - a_params.out = malloc (MAXSIZE); - - if (a_params.out == NULL) { - printf ("fs: Out of memory\n"); - return; - } - - i = 0; - - while (k_pioctl (NULL, VIOCGETCELL, &a_params, 0) != -1) { - ip = (int32_t *) a_params.out; - printf ("Cell %s on hosts", a_params.out + 8 * sizeof (int32_t)); - - j = 0; - - while (ip[j] && j<8) { - struct hostent *h; - addr.s_addr = ip[j]; - h = gethostbyaddr ((const char *) &addr, sizeof(addr), AF_INET); - if (h == NULL) { - printf (" %s", inet_ntoa (addr)); + int i, j; + char cellname[MAXSIZE]; + u_int32_t servers[8]; + int ret; + unsigned max_servers = sizeof(servers)/sizeof(servers[0]); + + for (i = 0; + (ret = fs_getcells (i, servers, + max_servers, + cellname, sizeof (cellname))) == 0; + ++i) { + printf ("%s", cellname); + + if (printservers) { + printf (": "); + + for (j = 0; j < max_servers && servers[j]; ++j) { + struct hostent *h = NULL; + addr.s_addr = servers[j]; + if (resolve) + h = gethostbyaddr ((const char *) &addr, + sizeof(addr), + AF_INET); + if (h == NULL) { + printf (" %s", inet_ntoa (addr)); + } else { + printf (" %s", h->h_name); + } } + } + if (suid) { + ret = fs_getcellstatus (cellname, &j); + if (ret) + fserr (PROGNAME, ret, NULL); else { - printf (" %s", h->h_name); + if (!(j & CELLSTATUS_SETUID)) + printf (", suid cell"); } - j++; } printf (".\n"); - i++; } - if (errno) { + if (errno != EDOM) fserr(PROGNAME, errno, NULL); - free(a_params.out); - return; - } - free (a_params.out); + return 0; } -void skipline(char **curptr) +void +skipline(char **curptr) { while(**curptr!='\n') (*curptr)++; (*curptr)++; } +/* + * + */ + +static int +getcache_cmd (int argc, char **argv) +{ + int ret; + u_int32_t max_kbytes, used_kbytes, max_vnodes, used_vnodes; + + ret = fs_getfilecachestats (&max_kbytes, + &used_kbytes, + &max_vnodes, + &used_vnodes); + if (ret) { + fserr (PROGNAME, ret, NULL); + return 0; + } + printf("Arla is using %lu of the cache's available %lu 1K byte blocks\n", + (unsigned long)used_kbytes, (unsigned long)max_kbytes); + if (max_vnodes) + printf("(and %lu of the cache's available %lu vnodes)\n", + (unsigned long)used_vnodes, (unsigned long)max_vnodes); + return 0; +} diff --git a/usr.sbin/afs/src/appl/fs_lib.c b/usr.sbin/afs/src/appl/fs_lib.c index 5658f07b332..4141788e9ab 100644 --- a/usr.sbin/afs/src/appl/fs_lib.c +++ b/usr.sbin/afs/src/appl/fs_lib.c @@ -1,6 +1,6 @@ -/* $OpenBSD: fs_lib.c,v 1.1.1.1 1998/09/14 21:52:53 art Exp $ */ +/* $OpenBSD: fs_lib.c,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,9 +38,9 @@ */ #include "appl_locl.h" -#include <kerberosIV/kafs.h> +#include <kafs.h> -RCSID("$KTH: fs_lib.c,v 1.4 1998/07/24 19:55:51 lha Exp $"); +RCSID("$KTH: fs_lib.c,v 1.22 1999/01/10 02:46:10 assar Exp $"); /* * @@ -49,7 +49,7 @@ RCSID("$KTH: fs_lib.c,v 1.4 1998/07/24 19:55:51 lha Exp $"); const char * fslib_version(void) { - return "$KTH: fs_lib.c,v 1.4 1998/07/24 19:55:51 lha Exp $"; + return "$KTH: fs_lib.c,v 1.22 1999/01/10 02:46:10 assar Exp $"; } /* @@ -57,37 +57,36 @@ fslib_version(void) */ void -fserr(char *progname, int error, char *realpath) +fserr(const char *progname, int error, const char *realpath) { - char *path = realpath ? realpath : "[unknown path]"; + const char *path = realpath ? realpath : "[unknown path]"; switch(error) { case EACCES: - printf("%s: You don't have the required access rights on" - " '%s'\n",progname, path); return ; + fprintf(stderr, "%s: You don't have the required access rights on" + " '%s'\n", progname, path); break; case EINVAL: - printf("%s: Invalid argument; it is possible that %s is" - " not in AFS.\n", progname, path); return ; + fprintf(stderr, "%s: Invalid argument; it is possible that %s is" + " not in AFS.\n", progname, path); break; case ENOENT: - printf("%s: '%s' doesn't exist\n",progname, path); + fprintf(stderr, "%s: '%s' doesn't exist\n", progname, path); break; case EPERM: - printf("%s: You do not have the required rights to do" - " this operation\n", progname); + fprintf(stderr, "%s: You do not have the required rights to do" + " this operation\n", progname); break; case ESRCH: - printf ("%s: Home cell information not available\n", progname); + fprintf (stderr, "%s: Home cell information not available\n", + progname); break; case EDOM: - break; default: - printf("%s: error %s (%d) return from pioctl\n", - progname, koerr_gettext(error), error); + fprintf(stderr, "%s: error %s (%d) return from pioctl\n", + progname, koerr_gettext(error), error); break; } - return; } /* @@ -157,6 +156,7 @@ fs_getfilecellname(char *path, char *cell, size_t len) * set the level of crypt */ +#ifdef VIOC_SETRXKCRYPT int fs_setcrypt (u_int32_t n) { @@ -172,11 +172,13 @@ fs_setcrypt (u_int32_t n) return 0; } +#endif /* * get currernt level of crypt */ +#ifdef VIOC_GETRXKCRYPT int fs_getcrypt (u_int32_t *level) { @@ -192,6 +194,7 @@ fs_getcrypt (u_int32_t *level) return 0; } +#endif /* * get and set the connect-mode @@ -217,6 +220,7 @@ fs_connect(int32_t type, int32_t *flags) * */ +#ifdef VIOC_FPRIOSTATUS int fs_setfprio(VenusFid fid, int16_t prio) { @@ -240,7 +244,9 @@ fs_setfprio(VenusFid fid, int16_t prio) return 0; } +#endif +#ifdef VIOC_FPRIOSTATUS int fs_getfprio(VenusFid fid, int16_t *prio) { @@ -263,7 +269,9 @@ fs_getfprio(VenusFid fid, int16_t *prio) return 0; } +#endif +#ifdef VIOC_FPRIOSTATUS int fs_setmaxfprio(int16_t maxprio) { @@ -283,7 +291,9 @@ fs_setmaxfprio(int16_t maxprio) return 0; } +#endif +#ifdef VIOC_FPRIOSTATUS int fs_getmaxfprio(int16_t *maxprio) { @@ -302,5 +312,485 @@ fs_getmaxfprio(int16_t *maxprio) return 0; } +#endif + +/* + * + */ + +int +fs_getfilecachestats(u_int32_t *max_kbytes, + u_int32_t *used_kbytes, + u_int32_t *max_vnodes, + u_int32_t *used_vnodes) +{ + u_int32_t parms[16]; + struct ViceIoctl a_params; + + a_params.in_size = 0; + a_params.out_size = sizeof(parms); + a_params.in = NULL; + a_params.out = (char *) parms; + + memset (parms, 0, sizeof(parms)); + + if (k_pioctl (NULL, VIOCGETCACHEPARAMS , &a_params, 0) == -1) + return errno; + + if (max_kbytes) + *max_kbytes = parms[0]; + if (used_kbytes) + *used_kbytes = parms[1]; + if (max_vnodes) + *max_vnodes = parms[2]; + if (used_vnodes) + *used_vnodes = parms[3]; + + return 0; +} + + +/* + * + */ + +#ifdef VIOC_AVIATOR +int +fs_getaviatorstats(u_int32_t *max_workers, + u_int32_t *used_workers) +{ + u_int32_t parms[16]; + struct ViceIoctl a_params; + + a_params.in_size = 0; + a_params.out_size = sizeof(parms); + a_params.in = NULL; + a_params.out = (char *) parms; + + if (k_pioctl (NULL, VIOC_AVIATOR , &a_params, 0) == -1) + return errno; + + if (max_workers) + *max_workers = parms[0]; + if (used_workers) + *used_workers = parms[1]; + + return 0; +} +#endif + +/* + * + */ + +#ifdef VIOC_GCPAGS +int +fs_gcpags(void) +{ + struct ViceIoctl a_params; + + a_params.in_size = 0; + a_params.out_size = 0; + a_params.in = NULL; + a_params.out = NULL; + + + if (k_pioctl(NULL, VIOC_GCPAGS, &a_params, 0) != 0) + return errno; + + return 0; +} +#endif + +/* + * Get/set debug levels with pioctl_cmd. + * + * inflags == -1 -> don't change + * outflags == NULL -> don't return + */ + +static int +debug (int pioctl_cmd, int inflags, int *outflags) +{ + struct ViceIoctl a_params; + + int32_t rinflags = inflags; + int32_t routflags; + + if (inflags != -1) { + a_params.in_size = sizeof(rinflags); + a_params.in = (char *) &rinflags; + } else { + a_params.in_size = 0; + a_params.in = NULL; + } + + if (outflags) { + a_params.out_size = sizeof(routflags); + a_params.out = (char *) &routflags; + } else { + a_params.out_size = 0; + a_params.out = NULL; + } + + if (k_pioctl (NULL, pioctl_cmd, &a_params, 0) == -1) + return errno; + + if (outflags) + *outflags = routflags; + + return 0; +} + +/* + * xfs_debug + */ + +#ifdef VIOC_XFSDEBUG +int +xfs_debug(int inflags, int *outflags) +{ + return debug (VIOC_XFSDEBUG, inflags, outflags); +} +#endif + +/* + * xfs_debug_print + */ + +#ifdef VIOC_XFSDEBUG_PRINT +int +xfs_debug_print(int inflags) +{ + return debug (VIOC_XFSDEBUG_PRINT, inflags, NULL); +} +#endif + +/* + * arla_debug + */ + +#ifdef VIOC_ARLADEBUG +int +arla_debug (int inflags, int *outflags) +{ + return debug (VIOC_ARLADEBUG, inflags, outflags); +} +#endif + +/* + * checkservers + * + * flags is the same flags as in CKSERV flags + * + */ + +int +fs_checkservers(char *cell, int32_t flags, u_int32_t *hosts, int numhosts) +{ + struct ViceIoctl a_params; + char *in = NULL; + int ret; + size_t insize; + + if (cell != NULL) { + insize = strlen(cell) + sizeof(int32_t) + 1; + in = malloc (insize); + if (in == NULL) + errx (1, "malloc"); + + memcpy (in, &flags, sizeof(flags)); + + memcpy (in + sizeof(int32_t), cell, strlen(cell)); + in[sizeof(int32_t) + strlen(cell)] = '\0'; + + a_params.in_size = insize; + a_params.in = in; + } else { + a_params.in_size = sizeof(flags); + a_params.in = (caddr_t )&flags; + } + + a_params.out_size = numhosts * sizeof(u_int32_t); + a_params.out = (caddr_t)hosts; + + ret = 0; + + if (k_pioctl (NULL, VIOCCKSERV, &a_params, 0) == -1) + ret = errno; + + if (in) + free(in); + + return ret; +} + +/* + * return current sysname in `sys' (of max length `sys_sz') + */ + +int +fs_get_sysname (char *sys, size_t sys_sz) +{ + struct ViceIoctl a_params; + int32_t set = 0; + char *buf; + + buf = malloc (sys_sz + 4); + if (buf == NULL) + return ENOMEM; + + a_params.in = (caddr_t)&set; + a_params.in_size = sizeof(set); + a_params.out = buf; + a_params.out_size = sys_sz + 4; + + if(k_pioctl (NULL, VIOC_AFS_SYSNAME, &a_params, 1) < 0) + return errno; + else { + strncpy (sys, buf + 4, sys_sz - 1); + sys[sys_sz - 1] = '\0'; + return 0; + } +} + +/* + * set current sysname to `sys' + */ + +int +fs_set_sysname (const char *sys) +{ + struct ViceIoctl a_params; + int32_t set = 1; + + a_params.in_size = sizeof(set) + strlen(sys) + 1; + a_params.in = malloc(a_params.in_size); + if (a_params.in == NULL) + return ENOMEM; + a_params.out = NULL; + a_params.out_size = 0; + memcpy (a_params.in, &set, sizeof(set)); + strcpy (a_params.in + sizeof(set), sys); + + if(k_pioctl (NULL, VIOC_AFS_SYSNAME, &a_params, 1) < 0) + return errno; + else + return 0; +} + +/* + * + */ + +int +fs_setcache(int lv, int hv, int lb, int hb) +{ + struct ViceIoctl a_params; + u_int32_t s[4]; + + s[0] = lv; + s[1] = hv; + s[2] = lb; + s[3] = hb; + + a_params.in_size = ((hv == 0) ? 1 : 4) * sizeof(u_int32_t); + a_params.out_size = 0; + a_params.in = (void *)s; + a_params.out = NULL; + + if (k_pioctl(NULL, VIOCSETCACHESIZE, &a_params, 0) < 0) + return errno; + else + return 0; +} + +/* + * return the local cell in `cell' (of size `cell_sz'). + */ + +int +fs_wscell (char *cell, size_t cell_sz) +{ + struct ViceIoctl a_params; + + a_params.in_size = 0; + a_params.in = NULL; + a_params.out_size = cell_sz; + a_params.out = cell; + + if (k_pioctl (NULL, VIOC_GET_WS_CELL, &a_params, 0) < 0) + return errno; + return 0; +} + +/* + * Flush the contents of the volume pointed to by `path'. + */ + +int +fs_flushvolume (const char *path) +{ + struct ViceIoctl a_params; + + a_params.in_size = 0; + a_params.out_size = 0; + a_params.in = NULL; + a_params.out = NULL; + + if (k_pioctl ((char *)path, VIOC_FLUSHVOLUME, &a_params, 0) < 0) + return errno; + else + return 0; +} + +/* + * Flush the file `path' from the cache. + */ + +int +fs_flush (const char *path) +{ + struct ViceIoctl a_params; + + a_params.in_size = 0; + a_params.out_size = 0; + a_params.in = NULL; + a_params.out = NULL; + + if (k_pioctl ((char *)path, VIOCFLUSH, &a_params, 0) < 0) + return errno; + else + return 0; +} +/* + * + */ + +int +fs_venuslog (void) +{ + struct ViceIoctl a_params; + int32_t status = 0; /* XXX not really right, but anyway */ + + a_params.in_size = sizeof(int32_t); + a_params.out_size = 0; + a_params.in = (caddr_t) &status; + a_params.out = NULL; + + if (k_pioctl (NULL, VIOC_VENUSLOG, &a_params, 0) < 0) + return errno; + else + return 0; +} + +/* + * Create a new cell (or change servers for an existing one), with + * name `cell' and `nservers' servers in `servers'. + */ + +int +fs_newcell (const char *cell, int nservers, char **servers) +{ + struct ViceIoctl a_params; + int len; + char *buf; + int i; + u_int32_t *hp; + + nservers = min (nservers, 8); + + len = 8 * sizeof(u_int32_t) + strlen(cell) + 1; + buf = malloc (len); + if (buf == NULL) + return errno; + + memset (buf, 0, len); + strcpy (buf + 8 * sizeof(u_int32_t), cell); + hp = (u_int32_t *)buf; + for (i = 0; i < nservers; ++i) { + struct in_addr addr; + + if (ipgetaddr (servers[i], &addr) == NULL) { + free (buf); + return EINVAL; + } + hp[i] = addr.s_addr; + } + + a_params.in_size = len; + a_params.out_size = 0; + a_params.in = (caddr_t)buf; + a_params.out = NULL; + + if (k_pioctl (NULL, VIOCNEWCELL, &a_params, 0) < 0) + return errno; + else + return 0; +} + +/* + * Fetch cell status for cell `num', and put the ip-numbers to the servers + * in the array `server' of length `server_sz'. `Cell' is the name + * of the cell and has length `sell_sz'. + */ + +int +fs_getcells (int32_t num, u_int32_t *server, size_t server_sz, + char *cell, size_t cell_sz) +{ + struct ViceIoctl a_params; + int32_t *server_list; + int i; + + if (server == NULL && server_sz != 0) + return EINVAL; + +#define GETCELL_MAXSERVER 8 + a_params.in_size = sizeof (num); + a_params.out_size = sizeof (u_int32_t) * GETCELL_MAXSERVER + cell_sz; + a_params.in = (char *) # + a_params.out = malloc (a_params.out_size); + + if (a_params.out == NULL) + return ENOMEM; + + server_list = (int32_t *) a_params.out; + + if (k_pioctl (NULL, VIOCGETCELL, &a_params, 0) != 0) + return errno; + + for (i = 0 ; i < server_sz; i++) + server[i] = server_list[i]; + + i = a_params.out_size - GETCELL_MAXSERVER * sizeof(u_int32_t); + + strncpy (cell, + (char *) a_params.out + GETCELL_MAXSERVER * sizeof(u_int32_t), + i); + cell[i-1] = '\0'; + + return 0; +} + +/* + * Get status for `cell' and put the flags in `flags'. + */ + +int +fs_getcellstatus (char *cellname, u_int32_t *flags) +{ + struct ViceIoctl a_params; + + a_params.in_size = strlen (cellname) + 1; + a_params.out_size = sizeof (u_int32_t); + a_params.in = cellname; + a_params.out = (caddr_t) flags; + + if (k_pioctl (NULL, VIOC_GETCELLSTATUS, &a_params, 0) < 0) + return errno; + else + return 0; +} diff --git a/usr.sbin/afs/src/appl/fs_local.h b/usr.sbin/afs/src/appl/fs_local.h index d5e2ba5bc95..d4dd5686b19 100644 --- a/usr.sbin/afs/src/appl/fs_local.h +++ b/usr.sbin/afs/src/appl/fs_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fs_local.h,v 1.1.1.1 1998/09/14 21:52:53 art Exp $ */ +/* $OpenBSD: fs_local.h,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -38,7 +38,7 @@ */ /* - * $KTH: fs_local.h,v 1.17 1998/07/24 19:55:52 lha Exp $ + * $KTH: fs_local.h,v 1.27 1999/01/03 08:09:18 lha Exp $ */ #define MAXNAME 100 @@ -84,62 +84,28 @@ void afs_sysname(char *name); void afs_listquota(char *path); void afs_setmaxquota(char *path, int32_t maxquota); void afs_whereis(char *path); -void afs_lsmount(char *path); -void afs_rmmount(char *path); +void afs_lsmount(const char *path); +void afs_rmmount(const char *path); void afs_examine(char *path); -void afs_wscell(void); -void afs_flushvolume(char *path); -void afs_flush(char *path); -void afs_venuslog(void); int afs_setcache(int, int, int, int); void afs_whichcell (char *path); void afs_diskfree (char *path); void afs_quota (char *path); void afs_getcellstatus (char *cell); void afs_getfid(char *path); -void afs_listcells (void); +int afs_listcells (int printservers, int resolve, int suid); int afs_connect(int32_t type); int afs_getcrypt (void); int afs_setcrypt (int n); +void afs_print_sysname (void); +void afs_set_sysname (const char *sys); +void afs_wscell (void); +int xfs_debug(int inflags, int *outflags); +int xfs_debug_print(int inflags); +int arla_debug(int inflags, int *outflags); void skipline(char **curptr); -static int connect_cmd (int argc, char **argv); -static int diskfree_cmd (int argc, char **argv); -static int empty_cmd (int argc, char **argv); -static int examine_cmd (int argc, char **argv); -static int flushvolume_cmd (int argc, char **argv); -static int flush_cmd (int argc, char **argv); -static int getcellstatus_cmd (int argc, char **argv); -static int getfid_cmd(int argc, char **argv); -static int help_cmd (int argc, char **argv); -static int mkmount_cmd (int argc, char **argv); -static int listacl_cmd (int argc, char **argv); -static int listcells_cmd (int argc, char **argv); -static int listquota_cmd (int argc, char **argv); -static int setquota_cmd (int argc, char **argv); -static int lsmount_cmd (int argc, char **argv); -static int quit_cmd (int argc, char **argv); -static int quota_cmd (int argc, char **argv); -static int rmmount_cmd (int argc, char **argv); -static int setacl_cmd (int argc, char **argv); -static int sysname_cmd (int argc, char **argv); -static int whereis_cmd (int argc, char **argv); -static int whichcell_cmd (int argc, char **argv); -static int wscell_cmd (int argc, char **argv); -static int venuslog_cmd (int argc, char **argv); -static int setcache_cmd (int argc, char **argv); -static int getcrypt_cmd (int argc, char **argv); -static int setcrypt_cmd (int argc, char **argv); -static int setprio_cmd (int argc, char **argv); -static int getprio_cmd (int argc, char **argv); -static int rmprio_cmd (int argc, char **argv); -static int fsversion_cmd(int argc, char **argv); -static int setmaxprio_cmd (int argc, char **argv); -static int getmaxprio_cmd (int argc, char **argv); -static int nop_cmd (int argc, char **argv); - - /* this program needs __progname defined as a macro */ #define __progname "fs" #define PROGNAME (fs_interactive ? "" : __progname" ") diff --git a/usr.sbin/afs/src/appl/pts.c b/usr.sbin/afs/src/appl/pts.c index 7441a91d34d..6328caeddbb 100644 --- a/usr.sbin/afs/src/appl/pts.c +++ b/usr.sbin/afs/src/appl/pts.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pts.c,v 1.1.1.1 1998/09/14 21:52:53 art Exp $ */ +/* $OpenBSD: pts.c,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -42,41 +42,15 @@ #include <pts.h> #include <pts.cs.h> #include <err.h> -#include <kerberosIV/kafs.h> +#include <kafs.h> #include <ctype.h> -RCSID("$KTH: pts.c,v 1.6 1998/07/30 18:36:22 rb Exp $"); +RCSID("$KTH: pts.c,v 1.21 1999/03/04 09:17:30 lha Exp $"); +static int help_cmd (int argc, char **argv); -static int empty_cmd(int, char **); -static int help_cmd(int, char **); -static int dump_cmd(int, char **); -static int examine_cmd(int, char **); -static int listmax_cmd(int, char **); -static int member_cmd(int, char **); -static int listowned_cmd(int, char **); - -static SL_cmd cmds[] = { - {"adduser", empty_cmd, "not yet implemented"}, - {"chown", empty_cmd, "not yet implemented"}, - {"creategroup", empty_cmd, "not yet implemented"}, - {"cg"}, - {"createuser", empty_cmd, "not yet implemented"}, - {"dump", dump_cmd, "dump pts database"}, - {"delete", empty_cmd, "not yet implemented"}, - {"examine", examine_cmd, "examine a user or a group"}, - {"help", help_cmd, "get help on pts"}, - {"?"}, - {"listmax", listmax_cmd, "print largest uid and gid"}, - {"listowned", listowned_cmd, "list groups owned by a user or group, or orphaned groups"}, - {"membership", member_cmd, "list group or user membership"}, - {"groups"}, - {"removeuser", empty_cmd, "not yet implemented"}, - {"rename", empty_cmd, "not yet implemented"}, - {"setfields", empty_cmd, "not yet implemented"}, - {"setmax", empty_cmd, "not yet implemented"}, - {NULL} -}; +/* Debugging on/off */ +static int prdebug = 0; static int empty_cmd (int argc, char **argv) @@ -85,20 +59,6 @@ empty_cmd (int argc, char **argv) return 0; } -static int -help_cmd (int argc, char **argv) -{ - SL_cmd *cmd = cmds; - - while (cmd->name != NULL) { - if (cmd->usage != NULL) - printf ("%-20s%s\n", cmd->name, cmd->usage); - cmd++; - } - - return 0; -} - void dump_usage () { @@ -126,10 +86,11 @@ dump_cmd (int argc, char **argv) host = argv[0]; - connptdb = arlalib_getconnbyname(host, + connptdb = arlalib_getconnbyname(cell_getcellbyhost(host), + host, afsprport, PR_SERVICE_ID, - noauth); + arlalib_getauthflag (noauth, 0, 0, 0)); if (connptdb == NULL) return 0; @@ -265,6 +226,760 @@ examine_id(struct rx_connection *conn, int32_t id, char *idname) return 0; } + +/* + * convert a `name' to `id' + */ + +static int +pr_name2id(struct rx_connection *conn, char *name, int32_t *id) +{ + int error; + namelist nlist; + idlist ilist; + char rname[PR_MAXNAMELEN]; + + assert(id); + + if (prdebug) + printf("pr_name2id(%s, x)", name); + + strncpy(rname, name, sizeof(rname)); + rname[sizeof(rname)-1] = '\0'; + + nlist.len = 1; + nlist.val = &rname; + + error = PR_NameToID(conn, &nlist, &ilist); + + if (error || ilist.len != 1) + *id = 0; + else + *id = *ilist.val; + + if (prdebug) + printf(" id = %d, error= %d\n", *id, error); + + free(ilist.val); + + return error; +} + + +/* + * add `user' to `group' + */ + +static int +pr_adduser(char *cell, char *user, char *group, arlalib_authflags_t auth) +{ + int error; + char *host; + struct rx_connection *conn; + int32_t uid; + int32_t gid; + + host = (char *) cell_findnamedbbyname (cell); + + conn = arlalib_getconnbyname(cell, host, + afsprport, + PR_SERVICE_ID, + auth); + if (conn == NULL) + return ENETDOWN; + + error = pr_name2id(conn, user, &uid); + if (error) { + if (prdebug) + warn("Problems finding user %s, error %s (%d)", + user, koerr_gettext(error), error); + goto err_out; + } + + error = pr_name2id(conn, group, &gid); + if (error) { + if (prdebug) + warn("Problems finding group %s, error %s (%d)", + user, koerr_gettext(error), error); + goto err_out; + } + + if (prdebug) + printf("PR_AddToGroup(conn, uid = %d, gid = %d);\n", uid, gid); + + error = PR_AddToGroup(conn, uid, gid); + + err_out: + arlalib_destroyconn(conn); + return error; +} + + +/* + * create user/group + * if you want the id returned + * set *id = 0 + * if you want to decide what the userid is set the *id != 0, + * id is still returned in this variable. + * + */ + +#define PR_CREATE_USER 0 +#define PR_CREATE_GROUP 2 + +static int +pr_create(char *cell, char *name, int32_t *id, int flag, arlalib_authflags_t auth) +{ + int error; + char *host; + struct rx_connection *conn; + int32_t save_id; + int32_t *rid = &save_id; + + if (id) + rid = id; + + host = (char *) cell_findnamedbbyname (cell); + + conn = arlalib_getconnbyname(cell, host, + afsprport, + PR_SERVICE_ID, + auth); + if (conn == NULL) + return ENETDOWN; + + if (prdebug) + printf("PR_NewEntry(%s, %d, %d, OUT)\n", + name, flag, *rid); + + error = PR_NewEntry(conn, name, flag, *rid, rid); + + arlalib_destroyconn(conn); + return error; +} + +/* + * + */ + +static int +pr_delete(char *cell, char *name, arlalib_authflags_t auth) +{ + int error; + char *host; + struct rx_connection *conn; + int32_t id; + + host = (char *) cell_findnamedbbyname (cell); + + conn = arlalib_getconnbyname(cell, host, + afsprport, + PR_SERVICE_ID, + auth); + if (conn == NULL) + return ENETDOWN; + + error = pr_name2id(conn, name, &id); + if (error) { + if (prdebug) + warn("Problems finding name: %s, error %s (%d)", + name, koerr_gettext(error), error); + goto err_out; + } + + + if (prdebug) + printf("PR_Delete(%s, %d)\n", + name, id); + + error = PR_Delete(conn, id); + err_out: + arlalib_destroyconn(conn); + return error; +} + + +/* + * + */ + +static int +pr_removeuser(char *cell, char *user, char *group, arlalib_authflags_t auth) +{ + int error; + char *host; + struct rx_connection *conn; + int32_t uid; + int32_t gid; + + host = (char *) cell_findnamedbbyname (cell); + + conn = arlalib_getconnbyname(cell, host, + afsprport, + PR_SERVICE_ID, + auth); + if (conn == NULL) + return ENETDOWN; + + error = pr_name2id(conn, user, &uid); + if (error) { + if (prdebug) + warn("Problems finding name: %s, error %s (%d)", + user, koerr_gettext(error), error); + goto err_out; + } + + error = pr_name2id(conn, group, &gid); + if (error) { + if (prdebug) + warn("Problems finding name: %s, error %s (%d)", + group, koerr_gettext(error), error); + goto err_out; + } + + if (prdebug) + printf("PR_RemoveFromGroup(%d, %d)\n", + uid, gid); + + error = PR_RemoveFromGroup(conn, uid, gid); + err_out: + arlalib_destroyconn(conn); + return error; +} + + +/* + * + */ + +static int +pr_rename(char *cell, char *fromname, char *toname, arlalib_authflags_t auth) +{ + int error; + char *host; + struct rx_connection *conn; + int32_t id; + + host = (char *) cell_findnamedbbyname (cell); + + conn = arlalib_getconnbyname(cell, host, + afsprport, + PR_SERVICE_ID, + auth); + if (conn == NULL) + return ENETDOWN; + + error = pr_name2id(conn, fromname, &id); + if (error) { + if (prdebug) + warn("Problems finding name: %s, error %s (%d)", + fromname, koerr_gettext(error), error); + goto err_out; + } + + if (prdebug) + printf("PR_ChangeEntry(%d, %s, 0, 0)\n", + id, toname); + + error = PR_ChangeEntry(conn, id, toname, 0, 0); + err_out: + arlalib_destroyconn(conn); + return error; +} + +/* + * + */ + +static int +pr_setfields(char *cell, char *name, int flags, int ngroup, + int nusers, arlalib_authflags_t auth) +{ + int error; + char *host; + struct rx_connection *conn; + int32_t id; + int mask = 0; + + host = (char *) cell_findnamedbbyname (cell); + + conn = arlalib_getconnbyname(cell, host, + afsprport, + PR_SERVICE_ID, + auth); + if (conn == NULL) + return ENETDOWN; + + if (flags != -1) + mask |= PR_SF_ALLBITS; + if (ngroup != -1) + mask |= PR_SF_NGROUPS; + if (nusers != -1) + mask |= PR_SF_NUSERS; + + error = pr_name2id(conn, name, &id); + if (error) { + if (prdebug) + warn("Problems finding name: %s, error %s (%d)", + name, koerr_gettext(error), error); + goto err_out; + } + + if (prdebug) + printf("PR_ChangeFields(%d, %d, %d, %d, %d, 0, 0)\n", + id, mask, flags, ngroup, nusers); + + error = PR_SetFieldsEntry(conn, id, mask, flags, ngroup, nusers, 0, 0); + err_out: + arlalib_destroyconn(conn); + return error; +} + +/* + * + */ + +static int +pr_chown(char *cell, char *name, char *owner, arlalib_authflags_t auth) +{ + int error; + char *host; + struct rx_connection *conn; + int32_t id; + int32_t ownerid; + + host = (char *) cell_findnamedbbyname (cell); + + conn = arlalib_getconnbyname(cell, host, + afsprport, + PR_SERVICE_ID, + auth); + if (conn == NULL) + return ENETDOWN; + + error = pr_name2id(conn, name, &id); + if (error) { + if (prdebug) + warn("Problems finding name: %s, error %s (%d)", + name, koerr_gettext(error), error); + goto err_out; + } + + error = pr_name2id(conn, owner, &ownerid); + if (error) { + if (prdebug) + warn("Problems finding name: %s, error %s (%d)", + name, koerr_gettext(error), error); + goto err_out; + } + + if (prdebug) + printf("PR_ChangeEntry(%d, \"\", %d, 0)\n", + id, ownerid); + + error = PR_ChangeEntry(conn, id, "", ownerid, 0); + err_out: + arlalib_destroyconn(conn); + return error; +} + + +/* + * create user + */ + +static int +create_cmd(int argc, char **argv, int groupp) +{ + char *name; + char *cell = (char *) cell_getthiscell(); + int32_t id = 0; + int noauth = 0; + int error; + int optind = 0; + + struct getargs createuserarg[] = { + {"name", 0, arg_string, NULL, NULL, NULL, arg_mandatory}, + {"id", 0, arg_integer, NULL, "id of user", NULL}, + {"cell", 0, arg_string, NULL, "what cell to use", NULL}, + {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = createuserarg; + if (groupp) + arg->help = "name of user"; + else + arg->help = "name of group"; + arg->value = &name; arg++; + arg->value = &id; arg++; + arg->value = &cell; arg++; + arg->value = &noauth; arg++; + + if (getarg (createuserarg, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(createuserarg, NULL, "createuser", ARG_AFSSTYLE); + return 0; + } + + error = pr_create(cell, name, &id, groupp, + arlalib_getauthflag (noauth, 0, 0, 0)); + if (error) { + printf("pr_create failed with: %s (%d)\n", + koerr_gettext(error), error); + } else + printf("%s %s created with id %d\n", + groupp ? "Group": "User", name, id); + + return 0; +} + +/* + * + */ + +static int +createuser_cmd(int argc, char **argv) +{ + return create_cmd(argc, argv, PR_CREATE_USER); +} + +/* + * + */ + +static int +creategroup_cmd(int argc, char **argv) +{ + return create_cmd(argc, argv, PR_CREATE_GROUP); +} + +/* + * + */ + +static int +adduser_cmd(int argc, char **argv) +{ + char *user; + char *group; + char *cell = (char *) cell_getthiscell(); + int noauth = 0; + int error; + int optind = 0; + + struct getargs addarg[] = { + {"name", 0, arg_string, NULL, "username", NULL, arg_mandatory}, + {"group", 0, arg_string, NULL, "groupname",NULL, arg_mandatory}, + {"cell", 0, arg_string, NULL, "what cell to use", NULL}, + {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = addarg; + arg->value = &user; arg++; + arg->value = &group; arg++; + arg->value = &cell; arg++; + arg->value = &noauth; arg++; + + if (getarg (addarg, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(addarg, NULL, "adduser", ARG_AFSSTYLE); + return 0; + } + + error = pr_adduser(cell, user, group, + arlalib_getauthflag (noauth, 0, 0, 0)); + if (error) { + printf("pr_adduser failed with: %s (%d)\n", + koerr_gettext(error), error); + } + + return 0; +} + +/* + * + */ + +static int +delete_cmd(int argc, char **argv) +{ + char *user; + char *cell = (char *) cell_getthiscell(); + int noauth = 0; + int error; + int optind = 0; + + struct getargs deletearg[] = { + {"name", 0, arg_string, NULL, "username", NULL, arg_mandatory}, + {"cell", 0, arg_string, NULL, "what cell to use", NULL}, + {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = deletearg; + arg->value = &user; arg++; + arg->value = &cell; arg++; + arg->value = &noauth; arg++; + + if (getarg (deletearg, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(deletearg, NULL, "delete", ARG_AFSSTYLE); + return 0; + } + + error = pr_delete(cell, user, + arlalib_getauthflag (noauth, 0, 0, 0)); + if (error) { + printf("pr_delete failed with: %s (%d)\n", + koerr_gettext(error), error); + } else + if (prdebug) + printf("Entry %s deleted successful\n", user); + + return 0; +} + +/* + * + */ + +static int +removeuser_cmd(int argc, char **argv) +{ + char *user; + char *group; + char *cell = (char *) cell_getthiscell(); + int noauth = 0; + int error; + int optind = 0; + + struct getargs removearg[] = { + {"user", 0, arg_string, NULL, "username", NULL, arg_mandatory}, + {"group", 0, arg_string, NULL, "group", NULL, arg_mandatory}, + {"cell", 0, arg_string, NULL, "what cell to use", NULL}, + {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = removearg; + arg->value = &user; arg++; + arg->value = &group; arg++; + arg->value = &cell; arg++; + arg->value = &noauth; arg++; + + if (getarg (removearg, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(removearg, NULL, "remove", ARG_AFSSTYLE); + return 0; + } + + error = pr_removeuser(cell, user, group, + arlalib_getauthflag (noauth, 0, 0, 0)); + if (error) { + printf("pr_remove failed with: %s (%d)\n", + koerr_gettext(error), error); + } else + if (prdebug) + printf("User %s removed from group %s.\n", user, group); + + return 0; +} + +/* + * + */ + +static int +rename_cmd(int argc, char **argv) +{ + char *fromname; + char *toname; + char *cell = (char *) cell_getthiscell(); + int noauth = 0; + int error; + int optind = 0; + + struct getargs renamearg[] = { + {"from", 0, arg_string, NULL, "from name",NULL, arg_mandatory}, + {"to", 0, arg_string, NULL, "to name", NULL, arg_mandatory}, + {"cell", 0, arg_string, NULL, "what cell to use", NULL}, + {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = renamearg; + arg->value = &fromname;arg++; + arg->value = &toname; arg++; + arg->value = &cell; arg++; + arg->value = &noauth; arg++; + + if (getarg (renamearg, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(renamearg, NULL, "rename", ARG_AFSSTYLE); + return 0; + } + + error = pr_rename(cell, fromname, toname, + arlalib_getauthflag (noauth, 0, 0, 0)); + if (error) { + printf("pr_rename failed with: %s (%d)\n", + koerr_gettext(error), error); + } else + if (prdebug) + printf("Changed name from %s to %s.\n", fromname, toname); + + return 0; +} + + +/* + * + */ + +static int +setfields_error() +{ + printf("text must be a union of the sets 'SOMA-' and 's-mar'\n"); + return 0; +} + +/* + * + */ + +static int +setfields_cmd(int argc, char **argv) +{ + char *name; + char *strflags = NULL; + int flags = -1; + int gquota = -1; + int uquota = -1; + char *cell = (char *) cell_getthiscell(); + int noauth = 0; + int error; + int optind = 0; + + struct getargs setfieldarg[] = { + {"name", 0, arg_string, NULL, "name of user/group", + NULL, arg_mandatory}, + {"flags", 0, arg_string, NULL, "flags", NULL}, + {"groupquota", 0, arg_integer, NULL, "groupquota",NULL}, + {"cell", 0, arg_string, NULL, "what cell to use", NULL}, + {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = setfieldarg; + arg->value = &name; arg++; + arg->value = &flags; arg++; + arg->value = &gquota; arg++; + arg->value = &cell; arg++; + arg->value = &noauth; arg++; + + if (getarg (setfieldarg, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(setfieldarg, NULL, "setfields", ARG_AFSSTYLE); + return 0; + } + + if(strflags) { + if (strlen(strflags) != 5) + return setfields_error(); + + flags = 0; + + if (strflags[0] == 'S') + flags |= PRP_STATUS_ANY; + else if (strflags[0] == 's') + flags |= PRP_STATUS_MEM; + else if (strflags[0] != '-') + return setfields_error(); + + if (strflags[1] == 'O') + flags |= PRP_OWNED_ANY; + else if (strflags[1] != '-') + return setfields_error(); + + if (strflags[2] == 'M') + flags |= PRP_MEMBER_ANY; + else if (strflags[2] == 'm') + flags |= PRP_MEMBER_MEM; + else if (strflags[2] != '-') + return setfields_error(); + + if (strflags[3] == 'A') { + flags |= PRP_ADD_ANY; + } else if (strflags[3] == 'a') + flags |= PRP_ADD_MEM; + else if (strflags[3] != '-') + return setfields_error(); + + if (strflags[4] == 'r') + flags |= PRP_REMOVE_MEM; + else if (strflags[4] != '-') + return setfields_error(); + } + + error = pr_setfields(cell, name, flags, gquota, uquota, + arlalib_getauthflag (noauth, 0, 0, 0)); + if (error) { + printf("pr_setfields failed with: %s (%d)\n", + koerr_gettext(error), error); + } else + if (prdebug) + printf("Changed fields for %s.\n", name); + + return 0; +} + +/* + * + */ + +static int +chown_cmd(int argc, char **argv) +{ + char *name; + char *owner; + char *cell = (char *) cell_getthiscell(); + int noauth = 0; + int error; + int optind = 0; + + struct getargs chownarg[] = { + {"name", 0, arg_string, NULL, "user or group name", + NULL, arg_mandatory}, + {"owner", 0, arg_string, NULL, "new owner", + NULL, arg_mandatory}, + {"cell", 0, arg_string, NULL, "what cell to use", NULL}, + {"noauth", 0, arg_flag, NULL, "don't authenticate", NULL}, + {NULL, 0, arg_end, NULL}}, + *arg; + + arg = chownarg; + arg->value = &name; arg++; + arg->value = &owner; arg++; + arg->value = &cell; arg++; + arg->value = &noauth; arg++; + + if (getarg (chownarg, argc, argv, &optind, ARG_AFSSTYLE)) { + arg_printusage(chownarg, NULL, "chown", ARG_AFSSTYLE); + return 0; + } + + error = pr_chown(cell, name, owner, + arlalib_getauthflag (noauth, 0, 0, 0)); + if (error) { + printf("pr_chown failed with: %s (%d)\n", + koerr_gettext(error), error); + } else + if (prdebug) + printf("Changed owner of %s to %s.\n", name, owner); + + return 0; +} + +/* + * + */ + static int examine_cmd (int argc, char **argv) { @@ -317,10 +1032,10 @@ examine_cmd (int argc, char **argv) if(host == NULL) errx(1, "Can't find cell %s", cell); - connptdb = arlalib_getconnbyname(host, - 7002, + connptdb = arlalib_getconnbyname(cell, host, + afsprport, PR_SERVICE_ID, - noauth); + arlalib_getauthflag (noauth, 0, 0, 0)); if (connptdb == NULL) errx(1, "Could not connect to ptserver"); @@ -398,8 +1113,8 @@ listmax_cmd (int argc, char **argv) host = cell_findnamedbbyname (cell); - connptdb = arlalib_getconnbyname(host, - 7002, + connptdb = arlalib_getconnbyname(cell, host, + afsprport, PR_SERVICE_ID, 1); /* XXX this means no auth */ if (connptdb == NULL) @@ -447,7 +1162,7 @@ pts_name_to_id(struct rx_connection *conn, char *name, int *id) int isdig = 1; char *ptr = name; while(*ptr && isdig) { - if(!isdigit(*ptr)) + if(!isdigit((unsigned char)*ptr)) isdig = 0; ptr++; } @@ -582,10 +1297,11 @@ member_cmd (int argc, char **argv) host = cell_findnamedbbyname (cell); - connptdb = arlalib_getconnbyname(host, - 7002, + connptdb = arlalib_getconnbyname(cell, + host, + afsprport, PR_SERVICE_ID, - noauth); + arlalib_getauthflag (noauth, 0, 0, 0)); if (connptdb == NULL) errx(1, "Could not connect to ptserver"); @@ -652,10 +1368,12 @@ listowned_cmd(int argc, char **argv) host = cell_findnamedbbyname (listowned_cell); - connptdb = arlalib_getconnbyname(host, - 7002, + connptdb = arlalib_getconnbyname(listowned_cell, + host, + afsprport, PR_SERVICE_ID, - listowned_noauth); + arlalib_getauthflag (listowned_noauth, + 0, 0, 0)); if (connptdb == NULL) errx(1, "Could not connect to ptserver"); @@ -701,23 +1419,94 @@ listowned_cmd(int argc, char **argv) return 0; } +static int +syncdb_cmd(int argc, char **argv) +{ + printf("sync...not implemented\n"); + return 0; +} + +static void +pts_usage(void) +{ + printf("pts - an arla tool for administrating AFS users" + " and groups.\n"); + printf("Type \"pts help\" to get a list of commands.\n"); + exit(1); +} + + +/* + * SL - switch + */ + +static SL_cmd cmds[] = { + {"adduser", adduser_cmd, "add a user to a group"}, + {"chown", chown_cmd, "change owner of user/group"}, + {"creategroup", creategroup_cmd,"create a group"}, + {"cg"}, + {"createuser", createuser_cmd, "create a user"}, + {"dump", dump_cmd, "dump pts database"}, + {"delete", delete_cmd, "delete entry"}, + {"examine", examine_cmd, "examine a user or a group"}, + {"help", help_cmd, "get help on pts"}, + {"?"}, + {"listmax", listmax_cmd, "print largest uid and gid"}, + {"listowned", listowned_cmd, "list groups owned by a user or group, or orphaned groups"}, + {"membership", member_cmd, "list group or user membership"}, + {"groups"}, + {"removeuser", removeuser_cmd, "remove user from group"}, + {"rename", rename_cmd, "rename user/group"}, + {"setfields", setfields_cmd, "not yet implemented"}, + {"setmax", empty_cmd, "not yet implemented"}, + {"syncdb", syncdb_cmd, "sync ptsdb with /etc/passwd"}, + {NULL} +}; + + +static int +help_cmd (int argc, char **argv) +{ + SL_cmd *cmd = cmds; + + while (cmd->name != NULL) { + if (cmd->usage != NULL) + printf ("%-20s%s\n", cmd->name, cmd->usage); + cmd++; + } + + return 0; +} + int main(int argc, char **argv) { int ret = 0; + char **myargv; + int pos = 0; - initports(); + ports_init(); cell_init(0); /* XXX */ + myargv = malloc(argc * sizeof(char *)); + if (myargv == NULL) + err(1, "malloc"); + + memcpy(myargv, argv, sizeof(char *) * argc); + if(argc > 1) { - ret = sl_command(cmds, argc - 1, argv + 1); + if (strcmp(myargv[1], "-debug") == 0) { + prdebug = 1; + argc--; + myargv[pos+1] = myargv[pos]; + ++pos; + } + ret = sl_command(cmds, argc - 1, &myargv[pos+1]); if (ret == -1) - printf("%s: Unknown command\n", argv[1]); - } - else { - printf("pts - an arla tool for administrating AFS users" - " and groups.\n"); - printf("Type \"pts help\" to get a list of commands.\n"); + printf("%s: Unknown command\n", myargv[pos+1]); } + else + pts_usage(); + return ret; } diff --git a/usr.sbin/afs/src/appl/udebug.c b/usr.sbin/afs/src/appl/udebug.c index 206dadf18d9..5e848245b6d 100644 --- a/usr.sbin/afs/src/appl/udebug.c +++ b/usr.sbin/afs/src/appl/udebug.c @@ -1,4 +1,5 @@ -/* $OpenBSD: udebug.c,v 1.1.1.1 1998/09/14 21:52:53 art Exp $ */ +/* $OpenBSD: udebug.c,v 1.2 1999/04/30 01:59:04 art Exp $ */ +/* $OpenBSD: udebug.c,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* * Copyright (c) 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). diff --git a/usr.sbin/afs/src/appl/vos.c b/usr.sbin/afs/src/appl/vos.c index 87e499daaf0..a506007bb0e 100644 --- a/usr.sbin/afs/src/appl/vos.c +++ b/usr.sbin/afs/src/appl/vos.c @@ -1,6 +1,6 @@ -/* $OpenBSD: vos.c,v 1.1.1.1 1998/09/14 21:52:53 art Exp $ */ +/* $OpenBSD: vos.c,v 1.2 1999/04/30 01:59:04 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -41,66 +41,15 @@ #include <sl.h> #include "vos_local.h" -RCSID("$KTH: vos.c,v 1.46 1998/08/23 22:50:21 assar Exp $"); +RCSID("$KTH: vos.c,v 1.55 1999/03/06 14:38:38 lha Exp $"); -static int empty_cmd (int, char **); -static int exa_cmd (int, char **); -static int help_cmd (int, char **); -static int quit_cmd (int, char **); -static int listp_cmd (int, char **); -static int livol_cmd (int, char **); -static int parti_cmd (int, char **); -static int stat_cmd (int, char **); -static int syncsite_cmd (int, char **); +int vos_interactive = 0; -static SL_cmd cmds[] = { - {"addsite", empty_cmd, "not yet implemented"}, - {"apropos", empty_cmd, "not yet implemented"}, - {"backup", empty_cmd, "not yet implemented"}, - {"backupsys", empty_cmd, "not yet implemented"}, - {"changeaddr", empty_cmd, "not yet implemented"}, - {"create", empty_cmd, "not yet implemented"}, - {"delentry", empty_cmd, "not yet implemented"}, - {"dump", empty_cmd, "not yet implemented"}, - {"examine", exa_cmd, "print information about a volume"}, - {"volinfo"}, - {"help", help_cmd, "print help"}, - {"?"}, - {"listpart", listp_cmd, "list partitions on a server"}, - {"listvldb", empty_cmd, "not yet implemented"}, - {"listvol", livol_cmd, "list volumes on a server"}, - {"lock", empty_cmd, "not yet implemented"}, - {"move", empty_cmd, "not yet implemented"}, - {"partinfo", parti_cmd, "print partition information on a server"}, - {"release", empty_cmd, "not yet implemented"}, - {"remove", empty_cmd, "not yet implemented"}, - {"remsite", empty_cmd, "not yet implemented"}, - {"rename", empty_cmd, "not yet implemented"}, - {"restore", empty_cmd, "not yet implemented"}, - {"status", stat_cmd, "Show volume server transactions"}, - {"syncserv", empty_cmd, "not yet implemented"}, - {"syncvldb", empty_cmd, "not yet implemented"}, - {"syncsite", syncsite_cmd, "print the syncsite"}, - {"unlock", empty_cmd, "not yet implemented"}, - {"unlockvldb", empty_cmd, "not yet implemented"}, - {"zap", empty_cmd, "not yet implemented"}, - {"quit", quit_cmd, "exit interactive mode"}, - {NULL} -}; - - - -int printlistparts(char *server); -int printvolstat(char *volname, - const char *cell, const char *host, int noauth); - -#define LISTVOL_PART 0x1 -#define LISTVOL_NOAUTH 0x2 -#define LISTVOL_LOCALAUTH 0x4 +static SL_cmd cmds[]; -int printlistvol(char *server, int part, int flags); -int printpartinfo(char *server, char *partition); -int printstatus(char *server); +/* + * Dummy command + */ static int empty_cmd(int argc, char **argv) @@ -109,6 +58,10 @@ empty_cmd(int argc, char **argv) return 0; } +/* + * quit + */ + static int quit_cmd(int argc, char **argv) { @@ -116,6 +69,10 @@ quit_cmd(int argc, char **argv) return 1; } +/* + * help + */ + static int help_cmd(int argc, char **argv) { @@ -124,776 +81,66 @@ help_cmd(int argc, char **argv) } /* - * volume_name2num - * convert a char string that might be a partition to a - * number. - * - * returns -1 is there is an error - * + * apropos */ -int -volume_name2num(char *name) -{ - int ret; - - if (strncmp(name, "/vicep", 6) == 0) - name += 6; - else if (strncmp(name, "vicep", 5) == 0) - name += 5; - - if (*name == '\0') - return -1; - - if(*(name+1) == '\0') { - if(isalpha(*name)) { - ret = tolower(*name) - 'a'; - } else - return -1; - } else if (*(name+2) == '\0') { - if (isalpha(*name) && isalpha(*name+1)) { - ret = 26 * (tolower(*(name)) - 'a' + 1) + tolower(*(name+1)) - 'a'; - } else - return -1; - } else - return -1; - - if(ret > 255) - return -1; - - return ret; - -} - - -static int exa_helpflag; -static char *exa_host; -static char *exa_cell; -static char *exa_vol; -static int exa_noauth; -static int exa_localauth; - -static struct getargs exa_args[] = { - {"id", 0, arg_string, &exa_vol, "id of volume", NULL, arg_mandatory}, - {"host", 0, arg_string, &exa_host, "what host to use", NULL}, - {"cell", 0, arg_string, &exa_cell, "what cell to use", NULL}, - {"noauth", 0, arg_flag, &exa_noauth, "what cell to use", NULL}, - {"localauth",0,arg_flag, &exa_localauth, "localauth", NULL}, - {"help", 0, arg_flag, &exa_helpflag, NULL, NULL}, - {NULL, 0, arg_end, NULL} -}; - - -int -exa_usage() -{ - arg_printusage(exa_args, NULL, "examine"); - return 0; -} - - static int -exa_cmd(int argc, char **argv) +apropos_cmd(int argc, char **argv) { - int optind = 0; - exa_noauth = exa_helpflag = 0; - exa_vol = NULL; - - exa_cell = NULL; - exa_host = NULL; - exa_noauth = 0; - - if (getarg (exa_args, argc, argv, &optind, ARG_AFSSTYLE)) - return exa_usage(); - - argc -= optind; - argv += optind; - - if (argc) { - printf("unknown option %s\n", *argv); + if (argc == 0) { + fprintf (stderr, "apropos: missing topic"); return 0; } - /* don't allow any bogus volname */ - if (exa_vol == NULL || exa_vol[0] == '\0') - return exa_usage(); - - printvolstat(exa_vol, exa_cell, exa_host, exa_noauth); + sl_apropos(cmds, argv[1]); return 0; } -static int listp_helpflag; -static char *listp_server; -static int listp_noauth; - -static struct getargs listp_args[] = { - {"server", 0, arg_string, &listp_server, "server", NULL, arg_mandatory}, - {"noauth", 0, arg_flag, &listp_noauth, "what cell to use", NULL}, - {"help", 0, arg_flag, &listp_helpflag, NULL, NULL} -}; - -int -listp_usage() -{ - arg_printusage(listp_args, NULL, "listpart"); - return 0; -} - - -static int -listp_cmd(int argc, char **argv) -{ - int optind = 0; - exa_noauth = exa_helpflag = 0; - exa_vol = NULL; - - - if (getarg (listp_args,argc, argv, &optind, ARG_AFSSTYLE)) - return listp_usage(); - - argc -= optind; - argv += optind; - - if (argc) { - printf("unknown option %s\n", *argv); - return 0; - } - - if (listp_server == NULL || listp_server[0] == '\0') - return listp_usage(); - - printlistparts(listp_server); - return 0; -} /* - * list volume on a afs-server + * command table */ -char *listvol_server; -char *listvol_partition; -int listvol_machine; -char *listvol_cell; -char *listvol_noauth; -char *listvol_localauth; -char *listvol_help; - -static struct getargs listvol_args[] = { - {"server", 0, arg_string, &listvol_server, - "server to probe", NULL, arg_mandatory}, - {"partition", 0, arg_string, &listvol_partition, - "partition to probe", NULL}, - {"machine", 'm', arg_flag, &listvol_machine, - "machineparseableform", NULL}, - {"cell", 0, arg_string, &listvol_cell, - "what cell to use", NULL}, - {"noauth", 0, arg_flag, &listvol_noauth, - "don't authenticate", NULL}, - {"localauth", 0, arg_flag, &listvol_localauth, - "use local authentication", NULL}, - {"help", 0, arg_flag, &listvol_help, - NULL, NULL}, - {NULL, 0, arg_end, NULL} +static SL_cmd cmds[] = { + {"addsite", empty_cmd, "not yet implemented"}, + {"apropos", apropos_cmd, "apropos"}, + {"backup", empty_cmd, "not yet implemented"}, + {"backupsys", empty_cmd, "not yet implemented"}, + {"changeaddr", empty_cmd, "not yet implemented"}, + {"create", vos_create, "create a volume"}, + {"createentry",vos_createentry, "create a vldb entry"}, + {"delentry", empty_cmd, "not yet implemented"}, + {"dump", vos_dump, "dump a volume"}, + {"endtrans", vos_endtrans, "end a transaction"}, + {"examine", vos_examine, "print information about a volume"}, + {"volinfo"}, + {"help", help_cmd, "print help"}, + {"?"}, + {"listpart", vos_listpart, "list partitions on a server"}, + {"listvldb", vos_listvldb, "list volumes in volume-location-database"}, + {"listvol", vos_listvol, "list volumes on a server"}, + {"lock", empty_cmd, "not yet implemented"}, + {"move", empty_cmd, "not yet implemented"}, + {"partinfo", vos_partinfo, "print partition information on a server"}, + {"release", empty_cmd, "not yet implemented"}, + {"remove", empty_cmd, "not yet implemented"}, + {"remsite", empty_cmd, "not yet implemented"}, + {"rename", empty_cmd, "not yet implemented"}, + {"restore", empty_cmd, "not yet implemented"}, + {"status", vos_status, "Show volume server transactions"}, + {"syncserv", empty_cmd, "not yet implemented"}, + {"syncvldb", empty_cmd, "not yet implemented"}, + {"syncsite", vos_syncsite, "print the syncsite"}, + {"unlock", empty_cmd, "not yet implemented"}, + {"unlockvldb", empty_cmd, "not yet implemented"}, + {"zap", empty_cmd, "not yet implemented"}, + {"quit", quit_cmd, "exit interactive mode"}, + {NULL} }; -void -listvol_usage() -{ - printf("Usage: %slistvol [-server] servername [[-partition] part ] [[-cell] cell] [-noauth] [-localauth] [-machine] [-help]\n", PROGNAME); -} - -static int -livol_cmd(int argc, char **argv) -{ - int optind = 0; - int flags = 0; - int part; - - if (getarg (listvol_args, argc, argv, &optind, ARG_AFSSTYLE)) { - listvol_usage(); - return 0; - } - - if(listvol_help) { - listvol_usage(); - return 0; - } - - argc -= optind; - argv += optind; - - if (listvol_server == NULL) { - listvol_usage(); - return 0; - } - - if (listvol_partition == NULL) { - part = -1; - } else { - part = volume_name2num(listvol_partition); - if (part == -1) { - listvol_usage(); - return 0; - } - } - - if (listvol_machine) - flags |= LISTVOL_PART; - if (listvol_noauth) - flags |= LISTVOL_NOAUTH; - if (listvol_localauth) - flags |= LISTVOL_LOCALAUTH; - - printlistvol(listvol_server, part, flags ); - return 0; -} - -void -parti_usage() -{ - printf("Usage: %spartinfo <server name> [partition name]\n", PROGNAME); -} - -static int -parti_cmd(int argc, char **argv) -{ - char *server; - char *partition = NULL; - - /* remove command name */ - argc--; - argv++; - - if (argc < 1) { - parti_usage(); - return 0; - } - - /* dinosaur protection */ - if (strcmp(argv[0], "-server") == 0) { - argc--; - argv++; - } - - server = argv[0]; - - argc--; - argv++; - - /* sanity check (assumes that argv[argc] == NULL)*/ - if (server == NULL || server[0] == '-' || server[0] == '\0') { - parti_usage(); - return 0; - } - - /* there could be a partition specified */ - if (argc > 0) { - /* dinosaur protection */ - if (strcmp(argv[0], "-partition") == 0) { - argc--; - argv++; - partition = argv[0]; - argc--; - argv++; - } else - /* this could be the partition */ - if (argv[0][0] != '-') { - partition = argv[0]; - argc--; - argv++; - } - } - - printpartinfo(server, partition); - return 0; -} - -void -stat_usage() -{ - printf("Usage: %sstatus <server name>\n", PROGNAME); -} - -static int -stat_cmd(int argc, char **argv) -{ - char *server; - - /* remove command name */ - argc--; - argv++; - - if (argc < 1) { - stat_usage(); - return 0; - } - - /* dinosaur protection */ - if (strcmp(argv[0], "-server") == 0) { - argc--; - argv++; - } - - server = argv[0]; - - argc--; - argv++; - - if (server == NULL || server[0] == '-' || server[0] == '\0') { - stat_usage(); - return 0; - } - - printstatus(server); - return 0; -} - -static int -syncsite_cmd (int argc, char **argv) -{ - struct in_addr saddr; - int error; - - error = arlalib_getsyncsite(NULL, NULL, afsvldbport, &saddr.s_addr, 0); - if (error) { - fprintf(stderr, "syncsite: %s (%d)\n", koerr_gettext(error), error); - return 0; - } - - printf("Our vldb syncsite is %s.\n", inet_ntoa(saddr)); - - return 0; -} - -static char* -getvolumetype(int32_t flag) -{ - char *str ; - if (flag & VLSF_RWVOL) - str = "RW"; - else if (flag & VLSF_ROVOL) - str = "RO"; - else if (flag & VLSF_BACKVOL) - str = "BACKUP"; - else - str = "FOO!"; - - return str; -} - -static char* -getvolumetype2(int32_t type) -{ - char *str = NULL; - switch (type) { - case RWVOL: - str = "RW"; - break; - case ROVOL: - str = "RO"; - break; - case BACKVOL: - str = "BK"; - break; - default: - str = "FOO!"; - } - return str; -} - -int -printvolstat(char *volname, const char *cell, const char *host, int noauth) -{ - struct rx_connection *connvolser = NULL; - struct rx_connection *connvldb = NULL; - int error; - int i; - char *servername; - char timestr[30]; - volEntries volint ; - vldbentry vlentry; - - if (cell == NULL && host != NULL) - cell = cell_getcellbyhost(host); - if (cell == NULL) - cell = cell_getthiscell(); - if (host == NULL) - host = cell_findnamedbbyname (cell); - - - connvldb = arlalib_getconnbyname(host, - afsvldbport, - VLDB_SERVICE_ID, - noauth); - if (connvldb == NULL) - return -1; - - - error = VL_GetEntryByName(connvldb, volname, &vlentry); - if (error) { - fprintf(stderr, "VLDB: no such entry\n"); - return -1; - } - - connvolser = arlalib_getconnbyaddr(htonl(vlentry.serverNumber[0]), - NULL, - afsvolport, - VOLSERVICE_ID, - noauth); - if (connvolser == NULL) - return -1 ; - - volint.val = NULL; - if ((error = VOLSER_AFSVolListOneVolume(connvolser, - vlentry.serverPartition[0], - vlentry.volumeId[0], - &volint)) != 0) { - printf("ListOneVolume failed with: %s (%d)\n", - koerr_gettext(error), - error); - return -1; - } - - printf("%s\t\t\t%10u %s %8d K %s\n", - vlentry.name, - vlentry.volumeId[0], - getvolumetype(vlentry.serverFlags[0]), - volint.val->size, - volint.val->status == VOK ? "On-line" : "Busy"); - - if (volint.val->status == VOK) { - - arlalib_getservername(htonl(vlentry.serverNumber[0]), &servername); - printf(" %s /vicep%c\n", servername, - 'a' + vlentry.serverPartition[0]); - printf(" "); - free(servername); - - if (vlentry.flags & VLF_RWEXISTS) - printf("RWrite %u\t", vlentry.volumeId[RWVOL]); - - if (vlentry.flags & VLF_ROEXISTS ) - printf("ROnly %u\t", vlentry.volumeId[ROVOL]); - - if (vlentry.flags & VLF_BACKEXISTS) - printf("Backup %u\t", vlentry.volumeId[BACKVOL]); - - printf("\n MaxQuota %10d K\n", volint.val->maxquota); - - /* Get and format date */ - strncpy(timestr, - ctime( (time_t*) &volint.val->creationDate), - sizeof(timestr)); - timestr[strlen(timestr)-1] = '\0'; - printf(" Creation %s\n", timestr); - - /* Get and format date */ - strncpy(timestr, - ctime((time_t *) &volint.val->updateDate), - sizeof(timestr)); - timestr[strlen(timestr)-1] = '\0'; - printf(" Last Update %s\n", timestr); - - printf(" %d accesses in the past day (i.e., vnode references)\n\n", - volint.val->dayUse); - - } - - /* Print volume stats */ - printf(" "); - printf("RWrite: %u\t", vlentry.flags & VLF_RWEXISTS ? vlentry.volumeId[RWVOL] : 0); - printf("ROnly: %u\t", vlentry.flags & VLF_ROEXISTS ? vlentry.volumeId[ROVOL] : 0); - printf("Backup: %u\t", vlentry.flags & VLF_BACKEXISTS ? vlentry.volumeId[BACKVOL] : 0); - - printf("\n number of sites -> %d\n", vlentry.nServers ); - - for ( i = 0 ; i < vlentry.nServers ; i++) { - printf(" "); - - if (vlentry.serverNumber[i] != 0) - arlalib_getservername(htonl(vlentry.serverNumber[i]), &servername); - else - servername = strdup("error"); - - printf("server %s partition /vicep%c %s Site\n", - servername, - 'a' + vlentry.serverPartition[i], - getvolumetype(vlentry.serverFlags[i])); - free(servername); - - } - - free(volint.val); - arlalib_destroyconn(connvolser); - arlalib_destroyconn(connvldb); - return 0; -} - - -int -getlistparts(char *host, struct pIDs *partIDs) -{ - struct rx_connection *connvolser = NULL; - int error ; - - connvolser = arlalib_getconnbyname(host, - afsvolport, - VOLSERVICE_ID, - 0); /* XXX this means try auth */ - if (connvolser == NULL) - return -1 ; - - if ((error = VOLSER_AFSVolListPartitions(connvolser, - partIDs)) != 0) { - printf("getlistparts: ListPartitions failed with: %s (%d)\n", - koerr_gettext(error), - error); - return -1; - } - - arlalib_destroyconn(connvolser); - return 0; -} - -int -printlistparts(char *host) -{ - struct pIDs partIDs; - int i,j ; - - if ((i = getlistparts(host, &partIDs)) != 0) - return i; - - j = 0 ; - - printf("The partitions on the server are:\n "); - for (i = 0 ; i < 26 ; i++) { - if (partIDs.partIds[i] != -1) { - j++; - printf(" /vicep%c%c", i + 'a', j % 6 == 0 ? '\n':' '); - } - } - - printf("\nTotal: %d\n", j); - return 0; -} - - -int -printlistvol(char *host, int part, int flags) -{ - struct rx_connection *connvolser = NULL; - volEntries volint ; - struct pIDs partIDs; - volintInfo *vi; - int32_t partnum = 0; - int32_t vol; - int online, busy, offline; - int error ; - - connvolser = arlalib_getconnbyname(host, - afsvolport, - VOLSERVICE_ID, - flags & LISTVOL_NOAUTH); - if (connvolser == NULL) - return -1 ; - - if (part == -1) { - if ((error = getlistparts(host, &partIDs)) != 0) - return -1; - } else { - for (partnum = 0 ; partnum < 26 ; partnum++) - partIDs.partIds[partnum] = -1 ; - partIDs.partIds[0] = part ; - } - - partnum = 0; - while(1) { - while(partIDs.partIds[partnum] == -1 && partnum < 26 ) partnum++; - if (partnum >= 26) - break; - - volint.val = NULL; - if ((error = VOLSER_AFSVolListVolumes(connvolser, - partIDs.partIds[partnum], - 1, /* We want full info */ - &volint)) != 0) { - printf("printlistvol: PartitionInfo failed with: %s (%d)\n", - koerr_gettext(error), - error); - return -1; - } - online = busy = offline = 0; - - printf("Total number of volumes on server %s partition /vicep%c: %d\n", - host, - partIDs.partIds[partnum] + 'a', - volint.len); - - for (vol = 0 ; vol < volint.len ; vol ++) { - vi = &volint.val[vol]; - - if (vi->status == VBUSY) - busy++; - else if (vi->inUse) - online++; - else - offline++; - - if(vi->status == VOK) { - printf("%-38s %10u %s %10u K %s %s%c\n", - vi->name, - vi->volid, - getvolumetype2(vi->type), - vi->size, - vi->inUse ? "On-line" : "Off-line", - flags&LISTVOL_PART?"/vicep":"", - flags&LISTVOL_PART?partIDs.partIds[partnum] + 'a':' '); - - } - } - - for (vol = 0 ; vol < volint.len ; vol ++) { - vi = &volint.val[vol]; - - if(vi->status == VBUSY) - printf("Volume with id number %u is currently busy\n", - vi->volid); - } - - printf("\nTotal volumes onLine %d ; Total volumes offLine %d " \ - "; Total busy %d\n\n", - online, offline, busy); - - free(volint.val); - partnum++; - } - - arlalib_destroyconn(connvolser); - return 0; -} - -int -printpartinfo(char *host, char *part) -{ - struct rx_connection *connvolser = NULL; - struct diskPartition partinfo ; - struct pIDs partIDs; - int iter = 0; - int partnum = 0; - char name[30]; - int error ; - - connvolser = arlalib_getconnbyname(host, - afsvolport, - VOLSERVICE_ID, - 0); /* XXX This means try auth */ - if (connvolser == NULL) - return -1 ; - - if (part == NULL) { - iter = 1; - if ((error = getlistparts(host, &partIDs)) != 0) - return error; - } else { - if (strlen(part) <= 2) { - snprintf(name, sizeof(name), "/vicep%s", part); - part = name; - } - } - - while(part != NULL || iter) { - - if (iter) { - while(partIDs.partIds[partnum] == -1 && partnum < 26 ) partnum++; - if (partnum < 26) { - snprintf(name, sizeof(name), "/vicep%c", 'a' + partnum); - part = name; - partnum++; - } else { - iter = 0 ; - continue; - } - } - - if ((error = VOLSER_AFSVolPartitionInfo(connvolser, - part, - &partinfo)) != 0) { - printf("printpartinfo: PartitionInfo failed with: %s (%d)\n", - koerr_gettext(error), - error); - return -1; - } - printf("Free space on partition %s %d K blocks out of total %d\n", - partinfo.name, - partinfo.free, - partinfo.minFree -/* XXX - partinfo.totalUsable */ - ); - part = NULL; - } - - arlalib_destroyconn(connvolser); - return 0; -} - -int -printstatus(char *host) -{ - struct rx_connection *connvolser = NULL; - struct transDebugInfo *entries; - transDebugEntries info; - unsigned int entries_len, i; - int error; - - connvolser = arlalib_getconnbyname(host, - afsvolport, - VOLSERVICE_ID, - 0); - - if (connvolser == NULL) - return -1; - - if ((error = VOLSER_AFSVolMonitor(connvolser, - &info)) != 0) { - printf("printstatus: GetStat failed with: %s (%d)\n", - koerr_gettext(error), - error); - return -1; - } - - entries_len = info.len; - entries = info.val; - - if (entries_len == 0) - printf ("No active transactions on %s\n", host); - else { - for (i = 0; i < entries_len; i--) { - printf("--------------------------------------\n"); - printf("transaction: %d created: %s", entries->tid, ctime((time_t *) &entries->creationTime)); - printf("attachFlags: "); - - if ((entries->iflags & ITOffline) == ITOffline) - printf(" offline"); - if ((entries->iflags & ITBusy) == ITBusy) - printf(" busy"); - if ((entries->iflags & ITReadOnly) == ITReadOnly) - printf("read-only"); - if ((entries->iflags & ITCreate) == ITCreate) - printf("create"); - if ((entries->iflags & ITCreateVolID) == ITCreateVolID) - printf("create-VolID"); - - printf("\nvolume: %d partition: <insert partition name here> procedure: %s\n", entries->volid, entries->lastProcName); - printf("packetRead: %d lastReceiveTime: %d packetSend: %d lastSendTime: %d\n", entries->readNext, entries->lastReceiveTime, entries->transmitNext, entries->lastSendTime); - entries++; - } - printf("--------------------------------------\n"); - } - - arlalib_destroyconn(connvolser); - return 0; -} +/* + * Main program + */ int main(int argc, char **argv) @@ -901,7 +148,7 @@ main(int argc, char **argv) int ret = 0; cell_init(0); - initports(); + ports_init(); if (argc > 1) ret = sl_command(cmds, argc - 1, argv + 1); @@ -909,7 +156,7 @@ main(int argc, char **argv) vos_interactive = 1; printf("vos - an arla tool for administrating AFS volumes.\n"); printf("Type \"help\" to get a list of commands.\n"); - ret = sl_loop(cmds, __progname": "); + ret = sl_loop(cmds, __progname": "); } return ret; } diff --git a/usr.sbin/afs/src/appl/vos_common.c b/usr.sbin/afs/src/appl/vos_common.c new file mode 100644 index 00000000000..2b4f78fa66f --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_common.c @@ -0,0 +1,412 @@ +/* $OpenBSD: vos_common.c,v 1.1 1999/04/30 01:59:04 art Exp $ */ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_common.c,v 1.7 1999/03/14 19:02:53 assar Exp $"); + +/* + * partition_num2name + * + * write the string of the partition number `id' in `str' (which is of + * size `sz') and return the number of characters written. + */ + +int +partition_num2name (int id, char *str, size_t sz) +{ + if (id < 26) + return snprintf (str, sz, "/vicep%c", 'a' + id); + else + return snprintf (str, sz, "/vicep%c%c", + 'a' + id / 26 - 1, 'a' + id % 26); +} + +/* + * partition_name2num + * convert a char string that might be a partition to a + * number. + * + * returns -1 is there is an error + * + */ + +int +partition_name2num(const char *name) +{ + int ret; + + if (strncmp(name, "/vicep", 6) == 0) + name += 6; + else if (strncmp(name, "vicep", 5) == 0) + name += 5; + + if (*name == '\0') + return -1; + + if(*(name+1) == '\0') { + if(isalpha((unsigned char)*name)) { + ret = tolower(*name) - 'a'; + } else + return -1; + } else if (name[2] == '\0') { + if (isalpha((unsigned char)name[0]) + && isalpha((unsigned char)name[1])) { + ret = 26 * (tolower(*(name)) - 'a' + 1) + tolower(*(name+1)) - 'a'; + } else + return -1; + } else + return -1; + + if(ret > 255) + return -1; + + return ret; +} + +/* + * Print the first of RW, RO, or BACKUP that there's a clone of + * according to serverFlag. + */ + +const char * +getvolumetype(int32_t flag) +{ + const char *str; + + if (flag & VLSF_RWVOL) + str = "RW"; + else if (flag & VLSF_ROVOL) + str = "RO"; + else if (flag & VLSF_BACKVOL) + str = "BACKUP"; + else if (flag & VLSF_NEWREPSITE) + str = "NewRepSite"; + else + str = "FOO!"; + + return str; +} + +/* + * Convert a volume `type' to a string. + */ + +const char * +getvolumetype2(int32_t type) +{ + const char *str; + + switch (type) { + case RWVOL: + str = "RW"; + break; + case ROVOL: + str = "RO"; + break; + case BACKVOL: + str = "BK"; + break; + default: + str = "FOO!"; + } + return str; +} + +/* + * Get the list of partitions from the server `host' in cell `cell' + * and store them in `parts'. Use authentication as specifined in `auth'. + */ + +int +getlistparts(const char *cell, const char *host, + part_entries *parts, arlalib_authflags_t auth) +{ + struct rx_connection *connvolser; + int error; + + connvolser = arlalib_getconnbyname(cell, + host, + afsvolport, + VOLSERVICE_ID, + auth); + if (connvolser == NULL) + return -1 ; + + error = VOLSER_AFSVolXListPartitions(connvolser, parts); + if (error == RXGEN_OPCODE) { + pIDs old_parts; + + error = VOLSER_AFSVolListPartitions(connvolser, &old_parts); + if (error == 0) { + int n, i; + + for (n = 0, i = 0; i < 26; ++i) + if (old_parts.partIds[i] != -1) + ++n; + parts->len = n; + parts->val = emalloc(n * sizeof(*parts->val)); + + for (n = 0, i = 0; i < 26; ++i) + if (old_parts.partIds[i] != -1) + parts->val[n++] = old_parts.partIds[i]; + } + } + + if (error != 0) { + printf("getlistparts: ListPartitions failed with: %s (%d)\n", + koerr_gettext(error), error); + return -1; + } + + arlalib_destroyconn(connvolser); + return 0; +} + +static void +print_fast_vols (volEntries ve) +{ + int i; + + for (i = 0; i < ve.len; ++i) + printf ("%d\n", ve.val[i].volid); +} + +static void +print_slow_vols (volEntries ve, const char *part_name, int flags) +{ + int i; + int busy = 0, online = 0, offline = 0; + + for (i = 0; i < ve.len; i++) { + volintInfo *vi = &ve.val[i]; + + if (vi->status == VBUSY) + busy++; + else if (vi->inUse) + online++; + else + offline++; + + if(vi->status == VOK) { + printf("%-38s %10u %s %10u K %s %s\n", + vi->name, + vi->volid, + getvolumetype2(vi->type), + vi->size, + vi->inUse ? "On-line" : "Off-line", + flags & LISTVOL_PART ? part_name : ""); + } + } + + for (i = 0; i < ve.len; i++) { + volintInfo *vi = &ve.val[i]; + + if(vi->status == VBUSY) + printf("Volume with id number %u is currently busy\n", + vi->volid); + } + + printf("\nTotal volumes onLine %d ; Total volumes offLine %d " \ + "; Total busy %d\n\n", + online, offline, busy); +} + +/* + * print all the volumes of host `host' in cell `cell' and partition `part'. + */ + +int +printlistvol(const char *cell, const char *host, int part, int flags, + arlalib_authflags_t auth) +{ + struct rx_connection *connvolser; + part_entries parts; + int error; + int i; + + connvolser = arlalib_getconnbyname(cell, + host, + afsvolport, + VOLSERVICE_ID, + auth); + if (connvolser == NULL) + return -1 ; + + if (part == -1) { + if ((error = getlistparts(cell, host, &parts, + auth)) != 0) + return -1; + } else { + parts.len = 1; + parts.val = emalloc (sizeof(*parts.val)); + parts.val[0] = part; + } + + for (i = 0; i < parts.len; ++i) { + char part_name[17]; + volEntries volint; + + volint.val = NULL; + if ((error = VOLSER_AFSVolListVolumes(connvolser, + parts.val[i], + 1, /* We want full info */ + &volint)) != 0) { + printf("printlistvol: PartitionInfo failed with: %s (%d)\n", + koerr_gettext(error), + error); + return -1; + } + partition_num2name (parts.val[i], part_name, sizeof(part_name)); + + printf("Total number of volumes on server %s partition %s: %d\n", + host, part_name, volint.len); + + if (flags & LISTVOL_FAST) + print_fast_vols (volint); + else + print_slow_vols (volint, part_name, flags); + free(volint.val); + } + + arlalib_destroyconn(connvolser); + return 0; +} + +/* + * Return the volume entry for `volname' in `cell' by asking the DB + * server at `host', with the auth flags in `auth' and returning the + * result in `nvldbentry'. Returns 0 or error. + */ + +int +get_vlentry (const char *cell, const char *host, const char *volname, + arlalib_authflags_t auth, nvldbentry *nvldbentry) +{ + struct rx_connection *conn; + int error; + + conn = arlalib_getconnbyname(cell, host, afsvldbport, VLDB_SERVICE_ID, + auth); + if (conn == NULL) + return -1; + + error = VL_GetEntryByNameN (conn, volname, nvldbentry); + + if (error == RXGEN_OPCODE) { + vldbentry vlentry; + + error = VL_GetEntryByName (conn, volname, &vlentry); + if (error == 0) + vldb2vldbN (&vlentry, nvldbentry); + } + arlalib_destroyconn(conn); + return error; +} + + +/* + * insert `nvldbentry' to the dbserver using `conn' or it `conn' == + * NULL use `cell' (and if specified `host') to get a new conn. If the + * db-server is old, use old method. + */ + +int +new_vlentry (struct rx_connection *conn, const char *cell, const char *host, + nvldbentry *nvldbentry, arlalib_authflags_t auth) +{ + int error; + int freeconnp = 0; + + if (conn == NULL) { + find_db_cell_and_host (&cell, &host); + + if (cell == NULL) { + fprintf (stderr, "Unable to find cell of host '%s'\n", host); + return -1; + } + + if (host == NULL) { + fprintf (stderr, "Unable to find DB server in cell '%s'\n", cell); + return -1; + } + + conn = arlalib_getconnbyname(cell, host, afsvldbport, VLDB_SERVICE_ID, + auth); + freeconnp = 1; + if (conn == NULL) + return -1; + } + + error = VL_CreateEntryN (conn, nvldbentry); + + if (error == RXGEN_OPCODE) { +#if 0 + vldbentry vlentry; + + vldbN2vldb (nvldbentry, &vlentry); + error = VL_CreateEntry (conn, volname, &vlentry); +#endif + abort(); + } + if (freeconnp) + arlalib_destroyconn(conn); + return error; +} + +/* + * Try to set *cell and *host to reasonable values. + */ + +void +find_db_cell_and_host (const char **cell, const char **host) +{ + if (*cell == NULL && *host != NULL) { + *cell = cell_getcellbyhost (*host); + return; + } + if (*cell == NULL) { + *cell = cell_getthiscell(); + } + if (*host == NULL) { + *host = cell_findnamedbbyname (*cell); + } +} diff --git a/usr.sbin/afs/src/appl/vos_createentry.c b/usr.sbin/afs/src/appl/vos_createentry.c new file mode 100644 index 00000000000..7b4877457b0 --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_createentry.c @@ -0,0 +1,163 @@ +/* $OpenBSD: vos_createentry.c,v 1.1 1999/04/30 01:59:05 art Exp $ */ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_createentry.c,v 1.2 1999/03/04 09:17:31 lha Exp $"); + +static int helpflag; +static char *vol; +static char *host; +static char *fsserver; +static char *partition; +static int noauth; +static int localauth; +static int rw_number; +static int ro_number; +static int bk_number; + +static struct getargs args[] = { + {"id", 0, arg_string, &vol, "id of volume", NULL, arg_mandatory}, + {"host", 0, arg_string, &host, "what host to use", NULL, arg_mandatory}, + {"fsserver",0, arg_string, &fsserver, "fsserver where the volume resides", NULL, arg_mandatory}, + {"partition",0, arg_string, &partition, "partition where the volume resides", NULL, arg_mandatory}, + {"rw", 0, arg_integer, &rw_number, "volume RW number", NULL}, + {"ro", 0, arg_integer, &ro_number, "volume RO number", NULL}, + {"bk", 0, arg_integer, &bk_number, "volume BK number", NULL}, + {"noauth", 0, arg_flag, &noauth, "what cell to use", NULL}, + {"localauth",0,arg_flag, &localauth, "localauth", NULL}, + {"help", 0, arg_flag, &helpflag, NULL, NULL}, + {NULL, 0, arg_end, NULL} +}; + +static void +usage(void) +{ + arg_printusage(args, "vos createentry", "", ARG_AFSSTYLE); +} + +int +vos_createentry(int argc, char **argv) +{ + int optind = 0; + struct rx_connection *connvldb = NULL; + struct nvldbentry newentry; + struct hostent *he; + int error; + + helpflag = 0; + vol = NULL; + host = NULL; + fsserver = NULL; + partition = NULL; + noauth = 0; + localauth = 0; + rw_number = 0; + ro_number = 0; + bk_number = 0; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage (); + } + + argc -= optind; + argv += optind; + + if (argc) { + printf("unknown option %s\n", *argv); + return 0; + } + + if (vol == NULL || + host == NULL || + fsserver == NULL || + partition == NULL) { + usage (); + return 0; + } + + connvldb = arlalib_getconnbyname(/* cell */ NULL, + host, + afsvldbport, + VLDB_SERVICE_ID, + arlalib_getauthflag (noauth, localauth, + 0, 0)); + if (connvldb == NULL) + return -1; + strncpy(newentry.name, vol, VLDB_MAXNAMELEN); + newentry.nServers = 1; + he = gethostbyname(fsserver); + if (he == NULL) { + fprintf(stderr, "unknown host: %s\n", fsserver); + return -1; + } + + memcpy (&newentry.serverNumber[0], he->h_addr_list[0], 4); + newentry.serverNumber[0] = ntohl(newentry.serverNumber[0]); + newentry.serverPartition[0] = partition_name2num(partition); + if (newentry.serverPartition[0] == -1) { + fprintf(stderr, "incorrect partition\n"); + usage(); + return 0; + } + + newentry.flags = 0; + newentry.flags |= rw_number ? VLF_RWEXISTS : 0; + newentry.flags |= ro_number ? VLF_ROEXISTS : 0; + newentry.flags |= bk_number ? VLF_BOEXISTS : 0; + + newentry.serverFlags[0] = 0; + newentry.serverFlags[0] |= rw_number ? VLSF_RWVOL : 0; + newentry.serverFlags[0] |= ro_number ? VLSF_ROVOL : 0; + newentry.serverFlags[0] |= bk_number ? VLSF_BACKVOL : 0; + + newentry.volumeId[0] = rw_number; + newentry.volumeId[1] = ro_number; + newentry.volumeId[2] = bk_number; + newentry.cloneId = 0; + error = VL_CreateEntryN(connvldb, &newentry); + if (error) { + fprintf(stderr, "VLDB: no such entry\n"); + return -1; + } + + return 0; +} diff --git a/usr.sbin/afs/src/appl/vos_createvolume.c b/usr.sbin/afs/src/appl/vos_createvolume.c new file mode 100644 index 00000000000..091081bb949 --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_createvolume.c @@ -0,0 +1,292 @@ +/* $OpenBSD: vos_createvolume.c,v 1.1 1999/04/30 01:59:05 art Exp $ */ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include "vos_local.h" + +RCSID("$KTH: vos_createvolume.c,v 1.1 1999/03/06 14:34:10 lha Exp $"); + +/* + * create volume + */ + + +int +vos_createvolume (char *host, int32_t part, char *cell, + arlalib_authflags_t auth, + char *name, int verbose) +{ + struct rx_connection *connvldb = NULL; + struct rx_connection *volser = NULL; + nvldbentry entry; + int32_t dbhost; + int32_t fshost; + int32_t volid; + int32_t rcode; + int32_t trans; /* transaction id */ + int error; + + if (host == NULL && name == NULL) + return EINVAL; + + if (cell == NULL) + cell = (char *)cell_getthiscell(); + + error = arlalib_getsyncsite (cell, NULL, afsvldbport, + &dbhost, auth); + if (error) { + fprintf (stderr, "vos_createvolume: arla_getsyncsite: %s\n", + koerr_gettext(error)); + return -1; + } + + connvldb = arlalib_getconnbyaddr(cell, dbhost, NULL, + afsvldbport, + VLDB_SERVICE_ID, + auth); + if (connvldb == NULL) { + fprintf (stderr, + "vos_createvolume: arlalib_getconnbyaddr: vldb-host: 0x%x\n", + dbhost); + return -1; + } + + volser = arlalib_getconnbyname (cell, host, + afsvolport, + VOLSERVICE_ID, + auth); + if (volser == NULL) { + fprintf (stderr,"vos_createvolume: arlalib_getconnbyname: volser: %s\n", + host); + arlalib_destroyconn (connvldb); + return -1; + } + + fshost = rx_HostOf(rx_PeerOf(volser)); + if (fshost == 0) { + fprintf (stderr, "vos_createvolume: address of 0 is not permited\n"); + goto errout; + } + + /* + * Get three (3) new Id's from the vldb server's + */ + + error = VL_GetNewVolumeId (connvldb, 3, &volid); + if (error) { + fprintf (stderr, "vos_createvolume: VL_GetNewVolumeID: %s\n", + koerr_gettext (error)); + goto errout; + } + if (verbose) + printf ("vos_createvolume: got a VolumeID: %d\n", volid); + + /* + * Create new volume on the server + */ + + error = VOLSER_AFSVolCreateVolume (volser, part, name, + RWVOL, + /* parent */ 0, &volid, + &trans); + if (error) { + fprintf (stderr, "vosler_createvolume: VOLSER_AFSVolCreateVolume: %s\n", + koerr_gettext (error)); + goto errout; + } + if (verbose) + printf ("vos_createvolume: created volume on %s, got trans %d\n", + host, trans); + + /* + * Bring the volume on-line + */ + + error = VOLSER_AFSVolSetFlags(volser, trans, 0); + if (error) { + fprintf (stderr, "vos_createvolume: VOLSER_AFSVolSetFlags: %s\n", + koerr_gettext (error)); + goto errout; + } + if (verbose) + printf ("vos_createvolume: updated flag for trans %d\n", trans); + + /* + * Create vldb-entry for the volume, if that failes, remove the volume + * from the server. + */ + + memset (&entry, 0, sizeof (entry)); + strncpy (entry.name, name, sizeof(entry.name)); + entry.nServers = 1; + entry.serverNumber[0] = ntohl(fshost); + entry.serverPartition[0] = part; + entry.serverFlags[0] = VLSF_RWVOL; + entry.volumeId[RWVOL] = volid; + entry.volumeId[ROVOL] = volid+1; + entry.volumeId[BACKVOL] = volid+2; + entry.cloneId = 0; + entry.flags = VLF_RWEXISTS; + + error = new_vlentry (connvldb, NULL, NULL, &entry, auth); + if (error) { + fprintf (stderr, "vos_createvolume: new_vlentry: %s\n", + koerr_gettext (error)); + + fprintf (stderr, "vos_createvolume: removing new volume"); + error = VOLSER_AFSVolDeleteVolume (volser, trans); + if (error) + fprintf (stderr, "vos_createvolume: failed to remove volume: %s\n", + koerr_gettext (error)); + else + fprintf (stderr, "vos_createvolume: removed volume\n"); + + } else if (verbose) + printf ("vos_createvolume: added entry to vldb\n"); + + /* + * End transaction to volumeserver + */ + + errout: + error = VOLSER_AFSVolEndTrans(volser, trans, &rcode); + if (error) { + fprintf (stderr, + "vos_createvolume: VOLSER_AFSVolEndTrans: %s, rcode: %d\n", + koerr_gettext (error), + rcode); + return -1; + } + if (verbose) + printf ("vos_createvolume: ending transaction %d, rcode %d\n", + trans, rcode); + + arlalib_destroyconn(volser); + arlalib_destroyconn(connvldb); + return error; +} + +/* + * list vldb + */ + +static char *server; +static char *part; +static char *volume; +static char *cell; +static int noauth; +static int localauth; +static int helpflag; +static int verbose; + +static struct getargs args[] = { + {"server", 0, arg_string, &server, + "server", NULL, arg_mandatory}, + {"part", 0, arg_string, &part, + "part", NULL, arg_mandatory}, + {"volume", 0, arg_string, &volume, + "volume", NULL, arg_mandatory}, + {"cell", 0, arg_string, &cell, + "cell", NULL}, + {"noauth", 0, arg_flag, &noauth, + "do not authenticate", NULL}, + {"localauth", 0, arg_flag, &localauth, + "use local authentication", NULL}, + {"verbose", 0, arg_flag, &verbose, + "verbose output", NULL}, + {"help", 0, arg_flag, &helpflag, + NULL, NULL}, + {NULL, 0, arg_end, NULL} +}; + +/* + * print usage + */ + +static void +usage(void) +{ + arg_printusage (args, "vos create", "", ARG_AFSSTYLE); +} + +/* + * createvolume, to be called from libsl + */ + +int +vos_create(int argc, char **argv) +{ + int optind = 0; + int npart = -1; + int error; + + server = cell = NULL; + noauth = localauth = helpflag = 0; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage(); + return 0; + } + + if(helpflag) { + usage(); + return 0; + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + fprintf (stderr, "create volume: unparsed arguments\n"); + return 0; + } + + npart = partition_name2num (part); + + error = vos_createvolume (server, npart, cell, + arlalib_getauthflag (noauth, localauth, 0, 0), + volume, verbose); + if (error) { + fprintf (stderr, "vos_createvolume failed (%d)\n", error); + return 0; + } + + return 0; +} + diff --git a/usr.sbin/afs/src/appl/vos_dump.c b/usr.sbin/afs/src/appl/vos_dump.c new file mode 100644 index 00000000000..c43fda99efa --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_dump.c @@ -0,0 +1,214 @@ +/* $OpenBSD: vos_dump.c,v 1.1 1999/04/30 01:59:05 art Exp $ */ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_dump.c,v 1.1 1999/03/04 10:50:00 assar Exp $"); + +static void +dump_volume (const char *volume, + const char *cell, const char *host, const char *part, + const char *file, arlalib_authflags_t auth) +{ + struct rx_connection *conn_volser = NULL; + struct rx_call *call; + int error; + int fd; + nvldbentry vlentry; + int32_t trans_id; + int ret; + u_int32_t size, nread; + char buf[8192]; + + if (file != NULL) { + fd = open (file, O_WRONLY | O_CREAT, 0666); + if (fd < 0) { + warn ("open %s", file); + return; + } + } else { + fd = STDOUT_FILENO; + } + + if (cell == NULL) + cell = cell_getthiscell (); + + error = get_vlentry (cell, NULL, volume, auth, &vlentry); + if (error) + goto out; + + conn_volser = arlalib_getconnbyaddr(cell, + htonl(vlentry.serverNumber[0]), + NULL, + afsvolport, + VOLSERVICE_ID, + auth); + if (conn_volser == NULL) { + fprintf (stderr, "dump_volume: getconnbyaddr failed\n"); + goto out; + } + + error = VOLSER_AFSVolTransCreate(conn_volser, + vlentry.volumeId[0], /* XXX */ + vlentry.serverPartition[0], + ITReadOnly, + &trans_id); + if (error) { + fprintf (stderr, "dump_volume: VolTransCreate failed: %s\n", + koerr_gettext(error)); + goto out; + } + + call = rx_NewCall (conn_volser); + if (call == NULL) { + fprintf (stderr, "dump_volume: rx_NewCall failed: %s\n", + koerr_gettext(error)); + goto out; + } + + error = StartVOLSER_AFSVolDump(call, trans_id, 0 /* XXX */); + if (error) { + rx_EndCall (call, 0); + fprintf (stderr, "dump_volume: start AFSVolDump failed: %s\n", + koerr_gettext(error)); + goto out; + } + + ret = rx_Read (call, &size, sizeof(size)); + + if (ret != sizeof(size)) { + ret = rx_Error(call); + rx_EndCall (call, 0); + fprintf (stderr, "dump_volume: start AFSVolDump failed: %s\n", + koerr_gettext(ret)); + goto out; + } + size = ntohl(size); + + while (size && (nread = rx_Read (call, buf, min(sizeof(buf), size))) > 0) { + if (write (fd, buf, nread) != nread) { + warn ("write"); + rx_EndCall(call, 0); + goto trans_out; + } + size -= nread; + } + + error = EndVOLSER_AFSVolDump (call); + if (error) { + rx_EndCall (call, 0); + fprintf (stderr, "dump_volume: end AFSVolDump failed: %s\n", + koerr_gettext(error)); + goto out; + } + rx_EndCall (call, 0); + +trans_out: + ret = 0; + + error = VOLSER_AFSVolEndTrans(conn_volser, trans_id, &ret); + if (error) + fprintf (stderr, "dump_volume: VolEndTrans failed: %s\n", + koerr_gettext(error)); + +out: + if (conn_volser != NULL) + arlalib_destroyconn (conn_volser); + + if (file != NULL) + close (fd); +} + +static char *vol; +static char *server; +static char *part; +static char *cell; +static char *file; +static int noauth; +static int localauth; +static int verbose; +static int helpflag; + +static struct getargs args[] = { + {"id", 0, arg_string, &vol, "id of volume", "volume", + arg_mandatory}, + {"server", 0, arg_string, &server, "what server to use", NULL}, + {"partition",0, arg_string, &part, "what partition to use", NULL}, + {"cell", 0, arg_string, &cell, "what cell to use", NULL}, + {"file", 0, arg_string, &file, "file to dump to", NULL}, + {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL}, + {"localauth",0,arg_flag, &localauth, "localauth", NULL}, + {"verbose", 0, arg_flag, &verbose, "be verbose", NULL}, + {"help", 0, arg_flag, &helpflag, NULL, NULL}, + {NULL, 0, arg_end, NULL} +}; + +static void +usage(void) +{ + arg_printusage(args, "vos dump", "", ARG_AFSSTYLE); +} + +int +vos_dump(int argc, char **argv) +{ + int optind = 0; + + noauth = localauth = verbose = 0; + file = cell = server = part = vol = NULL; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage (); + return 0; + } + + if (helpflag) { + usage (); + return 0; + } + + argc -= optind; + argv += optind; + + dump_volume (vol, cell, server, part, file, + arlalib_getauthflag (noauth, localauth, 0, 0)); + return 0; +} diff --git a/usr.sbin/afs/src/appl/vos_endtrans.c b/usr.sbin/afs/src/appl/vos_endtrans.c new file mode 100644 index 00000000000..c9c2fcd9d9f --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_endtrans.c @@ -0,0 +1,171 @@ +/* $OpenBSD: vos_endtrans.c,v 1.1 1999/04/30 01:59:05 art Exp $ */ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include "vos_local.h" + +RCSID("$KTH: vos_endtrans.c,v 1.2 1999/03/14 19:07:06 assar Exp $"); + +/* + * end a transaction on `host' with transaction id `trans' + */ + +int +vos_endtransaction (const char *cell, const char *host, int32_t trans, + arlalib_authflags_t auth, int verbose) +{ + struct rx_connection *volser = NULL; + int error; + int32_t rcode; + + if (host == NULL) + return EINVAL; + + if (cell == NULL) + cell = (char *)cell_getthiscell(); + + volser = arlalib_getconnbyname (cell, host, + afsvolport, + VOLSERVICE_ID, + auth); + if (volser == NULL) { + fprintf (stderr, + "vos_endtransaction: arlalib_getconnbyname: volser: %s\n", + host); + return -1; + } + + + error = VOLSER_AFSVolEndTrans(volser, trans, &rcode); + if (error) { + fprintf (stderr, "vos_createvolume: VOLSER_AFSVolEndTrans: %s\n", + koerr_gettext (error)); + return -1; + } + if (verbose) + printf ("vos_endtransaction: VOLSER_AFSVolEndTrans: rcode = %d", + rcode); + + arlalib_destroyconn(volser); + return error; +} + +/* + * list vldb + */ + +static char *server; +static char *cell; +static int transid; +static int noauth; +static int localauth; +static int helpflag; +static int verbose; + +static struct getargs args[] = { + {"server", 0, arg_string, &server, + "server", NULL, arg_mandatory}, + {"trans", 0, arg_integer, &transid, + "trans", NULL, arg_mandatory}, + {"cell", 0, arg_string, &cell, + "cell", NULL}, + {"noauth", 0, arg_flag, &noauth, + "do not authenticate", NULL}, + {"localauth", 0, arg_flag, &localauth, + "use local authentication", NULL}, + {"verbose", 0, arg_flag, &verbose, + "verbose output", NULL}, + {"help", 0, arg_flag, &helpflag, + NULL, NULL}, + {NULL, 0, arg_end, NULL} +}; + +/* + * print usage + */ + +static void +usage(void) +{ + arg_printusage (args, "vos endtransaction", "", ARG_AFSSTYLE); +} + +/* + * end a transaction, to be called from libsl + */ + +int +vos_endtrans(int argc, char **argv) +{ + int optind = 0; + int error; + + server = cell = NULL; + noauth = localauth = helpflag = 0; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage(); + return 0; + } + + if(helpflag) { + usage(); + return 0; + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + fprintf (stderr, "vos_endtrans: unparsed arguments\n"); + return 0; + } + + error = vos_endtransaction (cell, server, transid, + arlalib_getauthflag (noauth, localauth, 0, 0), + verbose); + if (error) { + fprintf (stderr, "vos_endtrans failed (%d)\n", error); + return 0; + } + + return 0; +} + + diff --git a/usr.sbin/afs/src/appl/vos_examine.c b/usr.sbin/afs/src/appl/vos_examine.c new file mode 100644 index 00000000000..97e97da1cf9 --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_examine.c @@ -0,0 +1,330 @@ +/* $OpenBSD: vos_examine.c,v 1.1 1999/04/30 01:59:05 art Exp $ */ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_examine.c,v 1.5 1999/03/14 19:04:38 assar Exp $"); + +static void +print_extended_stats (const xvolintInfo *v) +{ + printf(" Raw Read/Write Stats\n" + " |-------------------------------------------|\n" + " | Same Network | Diff Network |\n" + " |----------|----------|----------|----------|\n" + " | Total | Auth | Total | Auth |\n" + " |----------|----------|----------|----------|\n"); + printf("Reads |%9d |%9d |%9d |%9d |\n", + v->stat_reads[0], + v->stat_reads[1], + v->stat_reads[2], + v->stat_reads[3]); + printf("Writes |%9d |%9d |%9d |%9d |\n", + v->stat_writes[0], + v->stat_writes[1], + v->stat_writes[2], + v->stat_writes[3]); + printf(" |-------------------------------------------|\n"); + printf("\n"); + printf(" Writes Affecting Authorship\n" + " |-------------------------------------------|\n" + " | File Authorship | Directory Authorship|\n" + " |----------|----------|----------|----------|\n" + " | Same | Diff | Same | Diff |\n" + " |----------|----------|----------|----------|\n"); + printf("0-60 sec |%9d |%9d |%9d |%9d |\n", + v->stat_fileSameAuthor[0], v->stat_fileDiffAuthor[0], + v->stat_dirSameAuthor[0], v->stat_dirDiffAuthor[0]); + printf("1-10 min |%9d |%9d |%9d |%9d |\n", + v->stat_fileSameAuthor[1], v->stat_fileDiffAuthor[1], + v->stat_dirSameAuthor[1], v->stat_dirDiffAuthor[1]); + printf("10min-1hr |%9d |%9d |%9d |%9d |\n", + v->stat_fileSameAuthor[2], v->stat_fileDiffAuthor[2], + v->stat_dirSameAuthor[2], v->stat_dirDiffAuthor[2]); + printf("1hr-1day |%9d |%9d |%9d |%9d |\n", + v->stat_fileSameAuthor[3], v->stat_fileDiffAuthor[3], + v->stat_dirSameAuthor[3], v->stat_dirDiffAuthor[3]); + printf("1day-1wk |%9d |%9d |%9d |%9d |\n", + v->stat_fileSameAuthor[4], v->stat_fileDiffAuthor[4], + v->stat_dirSameAuthor[4], v->stat_dirDiffAuthor[4]); + printf("> 1wk |%9d |%9d |%9d |%9d |\n", + v->stat_fileSameAuthor[5], v->stat_fileDiffAuthor[5], + v->stat_dirSameAuthor[5], v->stat_dirDiffAuthor[5]); + printf(" |-------------------------------------------|\n"); +} + +static void +print_volume (const nvldbentry *nvlentry, const xvolintInfo *v, + const char *server_name, int extended) +{ + char part_name[17]; + char timestr[30]; + + printf("%s\t\t\t%10u %s %8d K %s\n", + nvlentry->name, + nvlentry->volumeId[0], + getvolumetype(nvlentry->serverFlags[0]), + v->size, + v->status == VOK ? "On-line" : "Busy"); + + if (v->status == VOK) { + partition_num2name (nvlentry->serverPartition[0], + part_name, sizeof(part_name)); + + printf(" %s %s\n", server_name, part_name); + printf(" "); + + if (nvlentry->flags & VLF_RWEXISTS) + printf("RWrite %u\t", nvlentry->volumeId[RWVOL]); + + if (nvlentry->flags & VLF_ROEXISTS ) + printf("ROnly %u\t", nvlentry->volumeId[ROVOL]); + + if (nvlentry->flags & VLF_BACKEXISTS) + printf("Backup %u\t", nvlentry->volumeId[BACKVOL]); + + printf("\n MaxQuota %10d K\n", v->maxquota); + + /* Get and format date */ + strncpy(timestr, + ctime( (time_t*) &v->creationDate), + sizeof(timestr)); + timestr[strlen(timestr) - 1] = '\0'; + printf(" Creation %s\n", timestr); + + /* Get and format date */ + strncpy(timestr, + ctime((time_t *) &v->updateDate), + sizeof(timestr)); + timestr[strlen(timestr)-1] = '\0'; + printf(" Last Update %s\n", timestr); + + printf(" %d accesses in the past day (i.e., vnode references)\n\n", + v->dayUse); + } + + if (extended) + print_extended_stats (v); +} + +static int +printvolstat(const char *volname, const char *cell, const char *host, + arlalib_authflags_t auth, int verbose, int extended) +{ + struct rx_connection *connvolser; + int error; + int i; + xvolEntries xvolint; + nvldbentry nvlentry; + struct in_addr server_addr; + char server_name[MAXHOSTNAMELEN]; + char part_name[17]; + int was_xvol = 1; + + find_db_cell_and_host (&cell, &host); + + if (cell == NULL) { + fprintf (stderr, "Unable to find cell of host '%s'\n", host); + return -1; + } + + if (host == NULL) { + fprintf (stderr, "Unable to find DB server in cell '%s'\n", cell); + return -1; + } + + if (verbose) + fprintf (stderr, + "Getting volume `%s' from the VLDB at `%s'...", + volname, host); + + error = get_vlentry (cell, host, volname, auth, &nvlentry); + + if (error) { + fprintf(stderr, "VL_GetEntryByName(%s) failed: %s\n", + volname, koerr_gettext(error)); + return -1; + } + + if (verbose) + fprintf (stderr, "done\n"); + + server_addr.s_addr = htonl(nvlentry.serverNumber[0]); + inaddr2str (server_addr, server_name, sizeof(server_name)); + + connvolser = arlalib_getconnbyaddr(cell, + server_addr.s_addr, + NULL, + afsvolport, + VOLSERVICE_ID, + auth); + if (connvolser == NULL) + return -1; + + if (verbose) { + fprintf (stderr, "getting information on `%s' from %s\n", + volname, server_name); + } + + xvolint.val = NULL; + error = VOLSER_AFSVolXListOneVolume(connvolser, + nvlentry.serverPartition[0], + nvlentry.volumeId[0], + &xvolint); + + if (error == RXGEN_OPCODE) { + volEntries volint; + + was_xvol = 0; + volint.val = NULL; + error = VOLSER_AFSVolListOneVolume(connvolser, + nvlentry.serverPartition[0], + nvlentry.volumeId[0], + &volint); + if (error == 0) { + xvolint.val = emalloc (sizeof (*xvolint.val)); + volintInfo2xvolintInfo (volint.val, xvolint.val); + } + } + + if (error != 0) { + printf("ListOneVolume of %s from %s failed with: %s (%d)\n", + volname, server_name, + koerr_gettext(error), error); + return -1; + } + + if (verbose) { + fprintf (stderr, "done\n"); + } + + print_volume (&nvlentry, xvolint.val, server_name, was_xvol && extended); + + printf(" "); + printf("RWrite: %u\t", nvlentry.flags & VLF_RWEXISTS ? nvlentry.volumeId[RWVOL] : 0); + printf("ROnly: %u\t", nvlentry.flags & VLF_ROEXISTS ? nvlentry.volumeId[ROVOL] : 0); + printf("Backup: %u\t", nvlentry.flags & VLF_BACKEXISTS ? nvlentry.volumeId[BACKVOL] : 0); + + printf("\n number of sites -> %d\n", nvlentry.nServers ); + + for (i = 0; i < nvlentry.nServers; i++) { + printf(" "); + + server_addr.s_addr = htonl(nvlentry.serverNumber[i]); + inaddr2str (server_addr, server_name, sizeof(server_name)); + + partition_num2name (nvlentry.serverPartition[i], + part_name, sizeof(part_name)); + printf("server %s partition %s %s Site\n", + server_name, part_name, + getvolumetype(nvlentry.serverFlags[i])); + } + + free(xvolint.val); + arlalib_destroyconn(connvolser); + return 0; +} + +static int helpflag; +static char *host; +static char *cell; +static char *vol; +static int noauth; +static int localauth; +static int verbose; +static int extended; + +static struct getargs args[] = { + {"id", 0, arg_string, &vol, "id of volume", "volume", + arg_mandatory}, + {"host", 0, arg_string, &host, "what host to use", NULL}, + {"cell", 0, arg_string, &cell, "what cell to use", NULL}, + {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL}, + {"localauth",0,arg_flag, &localauth, "localauth", NULL}, + {"verbose", 0, arg_flag, &verbose, "be verbose", NULL}, + {"extended",0, arg_flag, &extended, "more output", NULL}, + {"help", 0, arg_flag, &helpflag, NULL, NULL}, + {NULL, 0, arg_end, NULL} +}; + +static void +usage(void) +{ + arg_printusage(args, "vos examine", "", ARG_AFSSTYLE); +} + +int +vos_examine(int argc, char **argv) +{ + int optind = 0; + + helpflag = noauth = localauth = verbose = extended = 0; + host = cell = vol = NULL; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage (); + return 0; + } + + if (helpflag) { + usage (); + return 0; + } + + argc -= optind; + argv += optind; + + if (argc) { + printf("unknown option %s\n", *argv); + return 0; + } + + /* don't allow any bogus volname */ + if (vol == NULL || vol[0] == '\0') { + usage (); + return 0; + } + + printvolstat(vol, cell, host, + arlalib_getauthflag (noauth, localauth, 0, 0), + verbose, extended); + return 0; +} diff --git a/usr.sbin/afs/src/appl/vos_listpart.c b/usr.sbin/afs/src/appl/vos_listpart.c new file mode 100644 index 00000000000..9f260624557 --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_listpart.c @@ -0,0 +1,126 @@ +/* $OpenBSD: vos_listpart.c,v 1.1 1999/04/30 01:59:05 art Exp $ */ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_listpart.c,v 1.2 1999/03/04 09:17:31 lha Exp $"); + +static int +printlistparts(const char *cell, const char *server, + arlalib_authflags_t auth, int verbose) +{ + part_entries parts; + int error; + int i; + + if (cell == NULL) + cell = cell_getcellbyhost (server); + + error = getlistparts(cell, server, &parts, auth); + + if (error != 0) + return error; + + printf("The partitions on the server are:\n "); + for (i = 0; i < parts.len; ++i) { + char part_name[17]; + + partition_num2name (parts.val[i], part_name, sizeof(part_name)); + printf(" %s%c", part_name, i % 6 == 5 ? '\n' : ' '); + } + printf("\nTotal: %d\n", parts.len); + free (parts.val); + return 0; +} + +static int helpflag; +static char *server; +static char *cell; +static int noauth; +static int localauth; +static int verbose; + +static struct getargs listp_args[] = { + {"server", 0, arg_string, &server, "server", NULL, arg_mandatory}, + {"cell", 0, arg_string, &cell, "cell", NULL}, + {"noauth", 0, arg_flag, &noauth, "no authentication", NULL}, + {"localauth",0, arg_flag, &localauth, "local authentication", NULL}, + {"verbose", 0, arg_flag, &verbose, "be verbose", NULL}, + {"help", 0, arg_flag, &helpflag, NULL, NULL} +}; + +static void +usage(void) +{ + arg_printusage(listp_args, "vos listpart", "", ARG_AFSSTYLE); +} + +int +vos_listpart(int argc, char **argv) +{ + int optind = 0; + + helpflag = noauth = localauth = verbose = 0; + server = cell = NULL; + + if (getarg (listp_args,argc, argv, &optind, ARG_AFSSTYLE)) { + usage (); + return 0; + } + + argc -= optind; + argv += optind; + + if (argc) { + printf("unknown option %s\n", *argv); + return 0; + } + + if (server == NULL || server[0] == '\0') { + usage (); + return 0; + } + + printlistparts(cell, server, + arlalib_getauthflag (noauth, localauth, 0, 0), + verbose); + return 0; +} diff --git a/usr.sbin/afs/src/appl/vos_listvldb.c b/usr.sbin/afs/src/appl/vos_listvldb.c new file mode 100644 index 00000000000..fb6846bbdee --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_listvldb.c @@ -0,0 +1,193 @@ +/* $OpenBSD: vos_listvldb.c,v 1.1 1999/04/30 01:59:05 art Exp $ */ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_listvldb.c,v 1.6 1999/03/14 19:05:34 assar Exp $"); + +/* + * listvldb iteration over all entries in the DB + */ + +int +vos_listvldb_iter (const char *host, const char *cell, + arlalib_authflags_t auth, + int (*proc)(void *data, struct vldbentry *), void *data) +{ + struct rx_connection *connvldb = NULL; + struct vldbentry entry; + int error; + int32_t num, count; + + find_db_cell_and_host (&cell, &host); + + if (cell == NULL) { + fprintf (stderr, "Unable to find cell of host '%s'\n", host); + return -1; + } + + if (host == NULL) { + fprintf (stderr, "Unable to find DB server in cell '%s'\n", cell); + return -1; + } + + connvldb = arlalib_getconnbyname(cell, host, + afsvldbport, + VLDB_SERVICE_ID, + auth); + num = 0; + do { + error = VL_ListEntry (connvldb, + num, + &count, + &num, + &entry); + if (error) + break; + + entry.name[VLDB_MAXNAMELEN-1] = '\0'; + + error = proc (data, &entry); + if (error) + break; + + } while (num != -1); + + if (error) { + warnx ("listvldb: VL_ListEntry: %s", koerr_gettext(error)); + return -1; + } + + arlalib_destroyconn(connvldb); + return 0; +} + +/* + * Print vldbentry on listvldb style + */ + +static int +listvldb_print (void *data, struct vldbentry *e) +{ + int i; + char *hostname; + + assert (e); + + printf ("%s\n", e->name); + printf (" Number of sites -> %d\n", e->nServers); + for (i = 0 ; i < e->nServers ; i++) { + if (e->serverNumber[i] == 0) + continue; + if (arlalib_getservername(htonl(e->serverNumber[i]), &hostname)) + continue; + printf (" server %s partition /vicep%c Site %s\n", + hostname, + 'a' + e->serverPartition[i], + getvolumetype (e->serverFlags[i])); + free (hostname); + } + + printf ("\n"); + + return 0; +} + + +/* + * list vldb + */ + +char *server; +char *cell; +int noauth; +int localauth; +int helpflag; + +static struct getargs args[] = { + {"server", 0, arg_string, &server, + "server", NULL, arg_mandatory}, + {"cell", 0, arg_string, &cell, + "cell", NULL}, + {"noauth", 0, arg_flag, &noauth, + "do not authenticate", NULL}, + {"localauth", 0, arg_flag, &localauth, + "use local authentication", NULL}, + {"help", 0, arg_flag, &helpflag, + NULL, NULL}, + {NULL, 0, arg_end, NULL} +}; + +static void +usage(void) +{ + arg_printusage (args, "vos listvldb", "", ARG_AFSSTYLE); +} + +int +vos_listvldb(int argc, char **argv) +{ + int optind = 0; + + server = cell = NULL; + noauth = localauth = helpflag = 0; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage(); + return 0; + } + + if(helpflag) { + usage(); + return 0; + } + + argc -= optind; + argv += optind; + + + vos_listvldb_iter (server, cell, + arlalib_getauthflag (noauth, localauth, 0, 0), + listvldb_print, NULL); + + return 0; +} + diff --git a/usr.sbin/afs/src/appl/vos_listvol.c b/usr.sbin/afs/src/appl/vos_listvol.c new file mode 100644 index 00000000000..893a6fb0b62 --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_listvol.c @@ -0,0 +1,133 @@ +/* $OpenBSD: vos_listvol.c,v 1.1 1999/04/30 01:59:05 art Exp $ */ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_listvol.c,v 1.2 1999/03/04 09:17:32 lha Exp $"); + +/* + * list volume on a afs-server + */ + +char *server; +char *partition; +int listvol_machine; +char *cell; +int noauth; +int localauth; +int helpflag; +int fast; + +static struct getargs args[] = { + {"server", 0, arg_string, &server, + "server", NULL, arg_mandatory}, + {"partition", 0, arg_string, &partition, + "partition", NULL}, + {"machine", 'm', arg_flag, &listvol_machine, + "machineparseableform", NULL}, + {"cell", 0, arg_string, &cell, + "cell", NULL}, + {"noauth", 0, arg_flag, &noauth, + "do not authenticate", NULL}, + {"localauth", 0, arg_flag, &localauth, + "use local authentication", NULL}, + {"fast", 0, arg_flag, &fast, + "only list IDs", NULL}, + {"help", 0, arg_flag, &helpflag, + NULL, NULL}, + {NULL, 0, arg_end, NULL} +}; + +static void +usage(void) +{ + arg_printusage (args, "vos listvol", "", ARG_AFSSTYLE); +} + +int +vos_listvol(int argc, char **argv) +{ + int optind = 0; + int flags = 0; + int part; + + server = partition = cell = NULL; + listvol_machine = noauth = localauth = helpflag = fast = 0; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage(); + return 0; + } + + if(helpflag) { + usage(); + return 0; + } + + argc -= optind; + argv += optind; + + if (server == NULL) { + usage(); + return 0; + } + + if (partition == NULL) { + part = -1; + } else { + part = partition_name2num(partition); + if (part == -1) { + usage(); + return 0; + } + } + + if (listvol_machine) + flags |= LISTVOL_PART; + if (localauth) + flags |= LISTVOL_LOCALAUTH; + if (fast) + flags |= LISTVOL_FAST; + + printlistvol(cell, server, part, flags, + arlalib_getauthflag (noauth, 0, 0, 0)); + return 0; +} diff --git a/usr.sbin/afs/src/appl/vos_local.h b/usr.sbin/afs/src/appl/vos_local.h index 9732153919a..90f33b91957 100644 --- a/usr.sbin/afs/src/appl/vos_local.h +++ b/usr.sbin/afs/src/appl/vos_local.h @@ -1,6 +1,6 @@ -/* $OpenBSD: vos_local.h,v 1.1.1.1 1998/09/14 21:52:53 art Exp $ */ +/* $OpenBSD: vos_local.h,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,7 +38,7 @@ */ /* - * RCSID("$KTH: vos_local.h,v 1.1 1998/04/06 18:41:09 mikeee Exp $"); + * RCSID("$KTH: vos_local.h,v 1.7 1999/03/14 19:05:57 assar Exp $"); */ /* Iflags returned by AFSVolMonitor */ @@ -49,9 +49,54 @@ #define ITCreate 0x10 #define ITCreateVolID 0x1000 +#define LISTVOL_PART 0x1 +#define LISTVOL_NOAUTH 0x2 +#define LISTVOL_LOCALAUTH 0x4 +#define LISTVOL_FAST 0x8 + /* this program needs __progname defined as a macro */ #define __progname "vos" #define PROGNAME (vos_interactive ? "" : __progname" ") /* if this is set the program runs in interactive mode */ -static int vos_interactive = 0; +extern int vos_interactive; + +int vos_examine (int, char **); +int vos_listpart (int, char **); +int vos_listvol (int, char **); +int vos_listvldb(int argc, char **argv); +int vos_partinfo (int, char **); +int vos_status (int, char **); +int vos_createentry (int, char **); +int vos_syncsite (int, char **); +int vos_dump (int, char **); +int vos_create(int argc, char **argv); +int vos_endtrans(int argc, char **argv); + +int vos_listvldb_iter (const char *host, const char *cell, + arlalib_authflags_t auth, + int (*proc)(void *data, struct vldbentry *), + void *data); + +int partition_num2name(int id, char *str, size_t sz); +int partition_name2num(const char *name); +const char *getvolumetype(int32_t flag); +const char *getvolumetype2(int32_t type); +int getlistparts(const char *cell, const char *host, + part_entries *parts, arlalib_authflags_t auth); +int printlistvol(const char *cell, const char *host, int part, int flags, + arlalib_authflags_t auth); +int get_vlentry (const char *cell, const char *host, const char *volname, + arlalib_authflags_t auth, nvldbentry *nvlentry); +int new_vlentry (struct rx_connection *conn, const char *cell, const char *host, + nvldbentry *nvldbentry, arlalib_authflags_t auth); + + + +int vos_createvolume (char *host, int32_t part, char *cell, + arlalib_authflags_t auth, + char *name, int verbose); +int vos_endtransaction (const char *cell, const char *host, + int32_t trans, arlalib_authflags_t auth, int verbose); + +void find_db_cell_and_host (const char **cell, const char **host); diff --git a/usr.sbin/afs/src/appl/vos_partinfo.c b/usr.sbin/afs/src/appl/vos_partinfo.c new file mode 100644 index 00000000000..a292ffa45c1 --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_partinfo.c @@ -0,0 +1,168 @@ +/* $OpenBSD: vos_partinfo.c,v 1.1 1999/04/30 01:59:06 art Exp $ */ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_partinfo.c,v 1.1 1999/03/03 15:50:43 assar Exp $"); + +static int +print_one_partition (struct rx_connection *conn, const char *part) +{ + int error; + struct diskPartition partinfo ; + + error = VOLSER_AFSVolPartitionInfo(conn, part, &partinfo); + if (error != 0) { + printf("printpartinfo: PartitionInfo failed with: %s (%d)\n", + koerr_gettext(error), error); + return -1; + } + + printf("Free space on partition %s %d K blocks out of total %d\n", + partinfo.name, + partinfo.free, + partinfo.minFree +/* XXX - partinfo.totalUsable */ + ); + return 0; +} + +static int +printpartinfo(const char *cell, const char *host, const char *part, + int verbose, int noauth) +{ + struct rx_connection *connvolser; + char part_name[30]; + int error; + + connvolser = arlalib_getconnbyname(cell, + host, + afsvolport, + VOLSERVICE_ID, + noauth); + if (connvolser == NULL) + return -1; + + if (part == NULL) { + int i; + part_entries parts; + + error = getlistparts (cell, host, &parts, noauth); + if (error != 0) + return error; + + for (i = 0; i < parts.len; ++i) { + partition_num2name (parts.val[i], part_name, sizeof(part_name)); + error = print_one_partition (connvolser, part_name); + if (error != 0) + return error; + } + } else { + if (strlen(part) <= 2) { + snprintf(part_name, sizeof(part_name), "/vicep%s", part); + part = part_name; + } + error = print_one_partition (connvolser, part); + if (error != 0) + return error; + } + + arlalib_destroyconn(connvolser); + return 0; +} + +static int helpflag; +static char *server; +static char *cell; +static char *part; +static int noauth; +static int verbose; + +static struct getargs args[] = { + {"server", 0, arg_string, &server, "server", NULL, arg_mandatory}, + {"cell", 0, arg_string, &cell, "cell", NULL}, + {"partition",0, arg_string, &part, "partition", NULL}, + {"noauth", 0, arg_flag, &noauth, "no authentication", NULL}, + {"verbose", 0, arg_flag, &verbose, "be verbose", NULL}, + {"help", 0, arg_flag, &helpflag, NULL, NULL} +}; + +static void +usage(void) +{ + arg_printusage(args, "vos partinfo", "", ARG_AFSSTYLE); +} + +int +vos_partinfo(int argc, char **argv) +{ + int optind = 0; + + helpflag = noauth = verbose = 0; + server = cell = part = NULL; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage (); + return 0; + } + + if (helpflag) { + usage (); + return 0; + } + + argc -= optind; + argv += optind; + + if (argc == 1 && part == NULL) { + part = argv[0]; + --argc; + ++argv; + } + + if (argc != 0) { + usage (); + return 0; + } + + printpartinfo(cell, server, part, verbose, noauth); + return 0; +} diff --git a/usr.sbin/afs/src/appl/vos_status.c b/usr.sbin/afs/src/appl/vos_status.c new file mode 100644 index 00000000000..e1943839ddc --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_status.c @@ -0,0 +1,147 @@ +/* $OpenBSD: vos_status.c,v 1.1 1999/04/30 01:59:06 art Exp $ */ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_status.c,v 1.1 1999/03/03 15:50:43 assar Exp $"); + +static int +printstatus(const char *cell, const char *host, + int noauth, int verbose) +{ + struct rx_connection *connvolser = NULL; + struct transDebugInfo *entries; + transDebugEntries info; + unsigned int entries_len, i; + int error; + + connvolser = arlalib_getconnbyname(cell, + host, + afsvolport, + VOLSERVICE_ID, + 0); + + if (connvolser == NULL) + return -1; + + if ((error = VOLSER_AFSVolMonitor(connvolser, + &info)) != 0) { + printf("printstatus: GetStat failed with: %s (%d)\n", + koerr_gettext(error), + error); + return -1; + } + + entries_len = info.len; + entries = info.val; + + if (entries_len == 0) + printf ("No active transactions on %s\n", host); + else { + for (i = 0; i < entries_len; i--) { + printf("--------------------------------------\n"); + printf("transaction: %d created: %s", entries->tid, ctime((time_t *) &entries->creationTime)); + printf("attachFlags: "); + + if ((entries->iflags & ITOffline) == ITOffline) + printf(" offline"); + if ((entries->iflags & ITBusy) == ITBusy) + printf(" busy"); + if ((entries->iflags & ITReadOnly) == ITReadOnly) + printf("read-only"); + if ((entries->iflags & ITCreate) == ITCreate) + printf("create"); + if ((entries->iflags & ITCreateVolID) == ITCreateVolID) + printf("create-VolID"); + + printf("\nvolume: %d partition: <insert partition name here> procedure: %s\n", entries->volid, entries->lastProcName); + printf("packetRead: %d lastReceiveTime: %d packetSend: %d lastSendTime: %d\n", entries->readNext, entries->lastReceiveTime, entries->transmitNext, entries->lastSendTime); + entries++; + } + printf("--------------------------------------\n"); + } + + arlalib_destroyconn(connvolser); + return 0; +} + +static int helpflag; +static char *server; +static char *cell; +static int noauth; +static int verbose; + +static struct getargs args[] = { + {"server", 0, arg_string, &server, "server", NULL, arg_mandatory}, + {"cell", 0, arg_string, &cell, "cell", NULL}, + {"noauth", 0, arg_flag, &noauth, "do not authenticate", NULL}, + {"verbose", 0, arg_flag, &verbose, "be verbose", NULL}, + {"help", 0, arg_flag, &helpflag, NULL, NULL}, + {NULL, 0, arg_end, NULL, NULL, NULL} +}; + +static void +usage (void) +{ + arg_printusage (args, "vos status", "", ARG_AFSSTYLE); +} + +int +vos_status(int argc, char **argv) +{ + int optind = 0; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage (); + return 0; + } + + if (helpflag) { + usage (); + return 0; + } + + argc -= optind; + argv += optind; + + printstatus (cell, server, noauth, verbose); + return 0; +} diff --git a/usr.sbin/afs/src/appl/vos_syncsite.c b/usr.sbin/afs/src/appl/vos_syncsite.c new file mode 100644 index 00000000000..cd16058866c --- /dev/null +++ b/usr.sbin/afs/src/appl/vos_syncsite.c @@ -0,0 +1,98 @@ +/* $OpenBSD: vos_syncsite.c,v 1.1 1999/04/30 01:59:06 art Exp $ */ +/* + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "appl_locl.h" +#include <sl.h> +#include "vos_local.h" + +RCSID("$KTH: vos_syncsite.c,v 1.2 1999/03/06 16:41:02 lha Exp $"); + +static int helpflag; +static char *cell; +static int resolvep = 1; + +static struct getargs args[] = { + {"cell", 'c', arg_string, &cell, "cell", NULL}, + {"help", 'h', arg_flag, &helpflag, NULL, NULL}, + {"resolve", 'n', arg_negative_flag, &resolvep, NULL, NULL} +}; + +static void +usage(void) +{ + arg_printusage(args, "vos syncsite", "", ARG_AFSSTYLE); +} + +int +vos_syncsite (int argc, char **argv) +{ + struct in_addr saddr; + int error; + int optind = 0; + + helpflag = 0; + cell = NULL; + + if (getarg (args, argc, argv, &optind, ARG_AFSSTYLE)) { + usage (); + return 0; + } + + if (helpflag) { + usage (); + return 0; + } + + if (cell == NULL) + cell = (char *)cell_getthiscell(); + + error = arlalib_getsyncsite(cell, NULL, afsvldbport, &saddr.s_addr, 0); + if (error) { + fprintf(stderr, "syncsite: %s (%d)\n", koerr_gettext(error), error); + return 0; + } + + if (!resolvep) + printf("%s's vldb syncsite is %s.\n", cell, inet_ntoa(saddr)); + else { + const char *name = ipgetname(&saddr); + printf("%s's vldb syncsite is %s (%s).\n", cell, name, inet_ntoa(saddr)); + } + return 0; +} diff --git a/usr.sbin/afs/src/arlad/adir.c b/usr.sbin/afs/src/arlad/adir.c index 48c4b439626..e675c3e0468 100644 --- a/usr.sbin/afs/src/arlad/adir.c +++ b/usr.sbin/afs/src/arlad/adir.c @@ -1,4 +1,4 @@ -/* $OpenBSD: adir.c,v 1.1.1.1 1998/09/14 21:52:54 art Exp $ */ +/* $OpenBSD: adir.c,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -43,14 +43,14 @@ #include "arla_local.h" -RCSID("$KTH: adir.c,v 1.33 1998/07/29 14:38:51 assar Exp $") ; +RCSID("$KTH: adir.c,v 1.55 1998/12/25 04:39:55 assar Exp $") ; /* * Hash the filename of one entry. */ static unsigned -hashentry (const char *entry) +hashentry (const unsigned char *entry) { int s = 0, h; @@ -65,220 +65,111 @@ hashentry (const char *entry) } /* - * Return the entry in the directory given the number. - * The directory must be contiounsly in memory after page0. + * Return the number of additional DirEntries used by an entry with + * the filename `name`. + */ + +static unsigned +additional_entries (const char *filename) +{ + static DirEntry dummy; + + return (strlen(filename) - sizeof(dummy.name) + 1 + + sizeof(DirEntry) - 1) + / sizeof(DirEntry); +} + +/* + * Return a pointer to page number `pageno'. + */ + +static DirPage1 * +getpage (DirPage0 *page0, unsigned pageno) +{ + return (DirPage1 *)((char *)page0 + AFSDIR_PAGESIZE * pageno); +} + +/* + * Return the entry `num' in the directory `page0'. + * The directory must be continuous in memory after page0. */ static DirEntry * getentry (DirPage0 *page0, unsigned short num) { - DirPage1 *page; + DirPage1 *page = getpage (page0, num / ENTRIESPERPAGE); - page = (DirPage1 *)((char *)page0 + - AFSDIR_PAGESIZE * (num / ENTRIESPERPAGE)); assert (page->header.pg_tag == htons(AFSDIRMAGIC)); return &page->entry[num % ENTRIESPERPAGE]; } /* - * + * Return a pointer to the entry with name `name' in the directory `page0'. */ -static unsigned -find_by_name (DirPage0 *page0, - const char *name, - VenusFid *fid, - const VenusFid *dir) +static DirEntry * +find_entry(DirPage0 *page0, const char *name) { + DirEntry *entry; unsigned i; - i = ntohs(page0->dheader.hash[hashentry (name)]); - while (i != 0) { - const DirEntry *entry = getentry (page0, i - 1); + for (i = ntohs(page0->dheader.hash[hashentry (name)]); + i != 0; + i = ntohs(entry->next)) { + entry = getentry (page0, i - 1); - if (strcmp (entry->name, name) == 0) { - fid->Cell = dir->Cell; - fid->fid.Volume = dir->fid.Volume; - fid->fid.Vnode = ntohl (entry->fid.Vnode); - fid->fid.Unique = ntohl (entry->fid.Unique); - return i; - } - i = ntohs(entry->next); + if (strcmp (entry->name, name) == 0) + return entry; } - return i; + return NULL; } - /* - * Lookup `name' in the AFS directory identified by `dir' and return - * the Fid in `file'. All operations are done as `cred' and return - * value is 0 or error code. + * Return the fid for the entry with `name' in `page0'. `fid' is set + * to the fid of that file. `dir' should be the fid of the directory. + * Return zero if succesful, and -1 otherwise. */ -int -adir_lookup (VenusFid dir, - const char *name, - VenusFid *file, - CredCacheEntry *ce) +static int +find_by_name (DirPage0 *page0, + const char *name, + VenusFid *fid, + const VenusFid *dir) { - int fd; - DirPage0 *page0; - FCacheEntry *centry; - unsigned ind; - unsigned len; - int ret; - fbuf the_fbuf; - struct stat sb; - - ret = fcache_get (¢ry, dir, ce); - if (ret) { - ReleaseWriteLock (¢ry->lock); - return ret; - } - - ret = fcache_get_data (centry, ce); - if (ret) { - ReleaseWriteLock (¢ry->lock); - return ret; - } - - if (centry->status.FileType != TYPE_DIR) { - ReleaseWriteLock (¢ry->lock); - return ENOTDIR; - } - -#if 0 - len = centry->status.Length; -#endif - - fd = fcache_open_file (centry, O_RDONLY, 0); - if (fd < 0) { - ReleaseWriteLock (¢ry->lock); - return errno; - } - - if (fstat (fd, &sb)) { - close (fd); - ReleaseWriteLock (¢ry->lock); - return errno; - } - - len = sb.st_size; + const DirEntry *entry = find_entry (page0, name); - ret = fbuf_create (&the_fbuf, fd, len, FBUF_READ); - if (ret) { - close (fd); - ReleaseWriteLock (¢ry->lock); - return ret; - } - - page0 = (DirPage0 *)(the_fbuf.buf); - ind = find_by_name (page0, name, file, &dir); - - fbuf_end (&the_fbuf); - ReleaseWriteLock (¢ry->lock); - if (ind != 0) - return 0; - else - return ENOENT; + if (entry == NULL) + return -1; + fid->Cell = dir->Cell; + fid->fid.Volume = dir->fid.Volume; + fid->fid.Vnode = ntohl (entry->fid.Vnode); + fid->fid.Unique = ntohl (entry->fid.Unique); + return 0; } /* - * Read all entries in the AFS directory identified by `dir' and call - * `func' on each entry with the fid, the name, and `arg'. + * Change the fid for `name' to `fid'. Return 0 or -1. */ -int -adir_readdir (VenusFid dir, - void (*func)(VenusFid *, const char *, void *), - void *arg, - CredCacheEntry *ce) +static int +update_fid_by_name (DirPage0 *page0, + const char *name, + const VenusFid *fid, + const VenusFid *dir) { - int fd; - fbuf the_fbuf; - DirPage0 *page0; - unsigned i; - FCacheEntry *centry; - int ret; - unsigned ind, dotind, dotdotind; - VenusFid fid; - unsigned len; - struct stat sb; - - ret = fcache_get (¢ry, dir, ce); - if (ret) - return ret; - - ret = fcache_get_data (centry, ce); - if (ret) { - ReleaseWriteLock (¢ry->lock); - return ret; - } - - if (centry->status.FileType != TYPE_DIR) { - ReleaseWriteLock (¢ry->lock); - return ENOTDIR; - } - - fd = fcache_open_file (centry, O_RDONLY, 0); - if (fd < 0) { - ReleaseWriteLock (¢ry->lock); - return errno; - } - - if (fstat (fd, &sb)) { - ReleaseWriteLock (¢ry->lock); - close (fd); - return errno; - } + DirEntry *entry = find_entry (page0, name); - len = sb.st_size; - - ret = fbuf_create (&the_fbuf, fd, len, FBUF_READ); - if (ret) { - ReleaseWriteLock (¢ry->lock); - close (fd); - return ret; - } - page0 = (DirPage0 *)(the_fbuf.buf); + if (entry == NULL) + return -1; - /* - * Begin with placing `.' and `..' first. (some system seem to need that) - */ - - dotind = find_by_name (page0, ".", &fid, &dir); - assert (dotind != 0); - (*func)(&fid, ".", arg); - - dotdotind = find_by_name (page0, "..", &fid, &dir); - assert (dotind != 0); - (*func)(&fid, "..", arg); - - for (i = 0; i < ADIRHASHSIZE; ++i) { - const DirEntry *entry; - - for(ind = ntohs(page0->dheader.hash[i]); - ind; - ind = ntohs(entry->next)) { - - entry = getentry (page0, ind - 1); - - fid.Cell = dir.Cell; - fid.fid.Volume = dir.fid.Volume; - fid.fid.Vnode = ntohl (entry->fid.Vnode); - fid.fid.Unique = ntohl (entry->fid.Unique); - if (ind != dotind && ind != dotdotind) /* already did them */ - (*func)(&fid, entry->name, arg); - } - } - fbuf_end (&the_fbuf); - ReleaseWriteLock (¢ry->lock); - return 0; + entry->fid.Vnode = htonl (fid->fid.Vnode); + entry->fid.Vnode = htonl (fid->fid.Unique); + return 0; } /* - * + * Return true if slot `off' on `page' is being used. */ static int @@ -288,7 +179,7 @@ used_slot (DirPage1 *page, int off) } /* - * + * Mark slot `off' on `page' as being used. */ static void @@ -298,7 +189,40 @@ set_used (DirPage1 *page, int off) } /* - * Add a new page to a directory. + * Mark slot `off' on `page' as not being used. + */ + +static void +set_unused (DirPage1 *page, int off) +{ + page->header.pg_bitmap[off / 8] &= ~(1 << (off % 8)); +} + +/* + * Is this page `pageno' empty? + */ + +static int +is_page_empty (DirPage0 *page0, unsigned pageno) +{ + DirPage1 *page; + int i; + + if (pageno < MAXPAGES) + return page0->dheader.map[pageno] == ENTRIESPERPAGE - 1; + page = getpage (page0, pageno); + if (page->header.pg_bitmap[0] != 1) + return 0; + for (i = 1; i < sizeof(page->header.pg_bitmap); ++i) + if (page->header.pg_bitmap[i] != 0) + return 0; + return 1; +} + +/* + * Add a new page to the directory in `the_fbuf', returning a pointer + * to the new page in `ret_page'. + * Return 0 iff succesful. */ static int @@ -325,7 +249,9 @@ create_new_page (DirPage1 **ret_page, } /* - * return index into `page' + * Create a new entry with name `filename', fid `fid', and next + * pointer `next' in the page `page' with page number `pageno'. + * Return the index in the page or -1 if unsuccesful. */ static int @@ -336,16 +262,12 @@ add_to_page (DirPage0 *page0, AFSFid fid, unsigned next) { - int len = strlen (filename); int i, j; - unsigned n = 1; + unsigned n; - for (len = strlen(filename), n = 1; - len > 15; - len -= sizeof(DirEntry), ++n) - ; + n = 1 + additional_entries (filename); - if (page0->dheader.map[pageno] < n) + if (pageno < MAXPAGES && page0->dheader.map[pageno] < n) return -1; for (i = 0; i < ENTRIESPERPAGE - n;) { @@ -357,14 +279,15 @@ add_to_page (DirPage0 *page0, for (k = i + 1; k < i + j + 1; ++k) page->header.pg_bitmap[k / 8] |= (1 << (k % 8)); - page->entry[i].flag = 0; + page->entry[i].flag = 1; page->entry[i].length = 0; page->entry[i].next = next; page->entry[i].fid.Vnode = htonl(fid.Vnode); page->entry[i].fid.Unique = htonl(fid.Unique); strcpy (page->entry[i].name, filename); memset(page->entry[i + j - 1].fill, 0, 4); - page0->dheader.map[pageno] -= n; + if (pageno < MAXPAGES) + page0->dheader.map[pageno] -= n; return i; } i += j + 1; @@ -373,7 +296,7 @@ add_to_page (DirPage0 *page0, } /* - * + * Remove the entry `off' from the page `page' (page number `pageno'). */ static int @@ -383,26 +306,351 @@ remove_from_page (DirPage0 *page0, unsigned off) { DirEntry *entry = &page->entry[off]; - int len; - unsigned n = 1, i; + unsigned n, i; - for (len = strlen(entry->name), n = 1; - len > 15; - len -= sizeof(DirEntry), ++n) - ; + n = 1 + additional_entries (entry->name); - page0->dheader.map[pageno] += n; + if (pageno < MAXPAGES) + page0->dheader.map[pageno] += n; entry->next = 0; entry->fid.Vnode = 0; entry->fid.Unique = 0; for (i = off + 1; i < off + n + 1; ++i) - page->header.pg_bitmap[i / 8] &= ~(1 << (i % 8)); + set_unused (page, i); return 0; } /* + * Lookup `name' in the AFS directory identified by `centry' and return + * the Fid in `file'. All operations are done as `cred' and return + * value is 0 or error code. + * + * + * Locking: + * In Out Fail + * centry: Locked Locked Locked + * + */ + +int +adir_lookup_fcacheentry (FCacheEntry *centry, + const char *name, + VenusFid *file, + CredCacheEntry *ce) +{ + int fd; + DirPage0 *page0; + unsigned ind; + unsigned len; + int ret; + int close_ret; + fbuf the_fbuf; + struct stat sb; + + assert (CheckLock (¢ry->lock) == -1); + + if (centry->status.FileType != TYPE_DIR) { + return ENOTDIR; + } + + assert (CheckLock (¢ry->lock) == -1); + + fd = fcache_open_file (centry, O_RDONLY); + if (fd < 0) { + return errno; + } + + assert (CheckLock (¢ry->lock) == -1); + + if (fstat (fd, &sb)) { + close_ret = close (fd); + assert (close_ret == 0); + return errno; + } + + len = sb.st_size; + + assert (CheckLock (¢ry->lock) == -1); + + ret = fbuf_create (&the_fbuf, fd, len, FBUF_READ); + if (ret) + return ret; + + assert (CheckLock (¢ry->lock) == -1); + + page0 = (DirPage0 *)(the_fbuf.buf); + ind = find_by_name (page0, name, file, ¢ry->fid); + fbuf_end (&the_fbuf); + + if (ind == 0) + return 0; + else + return ENOENT; +} + +/* + * Lookup `name' in the AFS directory identified by `dir' and return + * the Fid in `file'. All operations are done as `cred' and return + * value is 0 or error code. + */ + +int +adir_lookup (VenusFid dir, + const char *name, + VenusFid *file, + CredCacheEntry *ce) +{ + FCacheEntry *centry; + int ret; + + ret = fcache_get (¢ry, dir, ce); + if (ret) + return ret; + + assert (CheckLock (¢ry->lock) == -1); + + ret = fcache_get_data (centry, ce); + if (ret) { + fcache_release (centry); + return ret; + } + + ret = adir_lookup_fcacheentry (centry, name, file, ce); + + fcache_release (centry); + + return ret; + +} + +/* + * Lookup `name' in the AFS directory identified by `dir' and change the + * fid to `fid'. + */ + +int +adir_changefid (VenusFid dir, + const char *name, + VenusFid *file, + CredCacheEntry *ce) +{ + int fd; + DirPage0 *page0; + FCacheEntry *centry; + unsigned len; + int ret; + int close_ret; + fbuf the_fbuf; + struct stat sb; + + ret = fcache_get (¢ry, dir, ce); + if (ret) + return ret; + + ret = fcache_get_data (centry, ce); + if (ret) { + fcache_release (centry); + return ret; + } + + if (centry->status.FileType != TYPE_DIR) { + fcache_release(centry); + return ENOTDIR; + } + + fd = fcache_open_file (centry, O_RDWR); + if (fd < 0) { + fcache_release(centry); + return errno; + } + + if (fstat (fd, &sb)) { + close_ret = close (fd); + assert (close_ret == 0); + fcache_release(centry); + return errno; + } + + len = sb.st_size; + + ret = fbuf_create (&the_fbuf, fd, len, FBUF_WRITE); + if (ret) { + fcache_release(centry); + return ret; + } + + page0 = (DirPage0 *)(the_fbuf.buf); + ret = update_fid_by_name (page0, name, file, &dir); + fcache_release(centry); + fbuf_end (&the_fbuf); + + if (ret == 0) + return 0; + else + return ENOENT; +} + +/* + * Return TRUE if dir is empty. + */ + +int +adir_emptyp (VenusFid dir, + CredCacheEntry *ce) +{ + int fd; + DirPage0 *page0; + FCacheEntry *centry; + unsigned len; + int ret; + int close_ret; + fbuf the_fbuf; + struct stat sb; + unsigned npages; + + ret = fcache_get (¢ry, dir, ce); + if (ret) + return ret; + + ret = fcache_get_data (centry, ce); + if (ret) { + fcache_release (centry); + return ret; + } + + if (centry->status.FileType != TYPE_DIR) { + fcache_release (centry); + return ENOTDIR; + } + + fd = fcache_open_file (centry, O_RDONLY); + if (fd < 0) { + fcache_release(centry); + return errno; + } + + if (fstat (fd, &sb)) { + fcache_release(centry); + close_ret = close (fd); + assert (close_ret == 0); + return errno; + } + + len = sb.st_size; + + ret = fbuf_create (&the_fbuf, fd, len, FBUF_READ); + if (ret) { + fcache_release(centry); + return ret; + } + page0 = (DirPage0 *)(the_fbuf.buf); + npages = ntohs(page0->header.pg_pgcount); + + ret = (npages == 1) && (page0->dheader.map[0] == 2); + fbuf_end (&the_fbuf); + fcache_release (centry); + return ret; +} + +/* + * Read all entries in the AFS directory identified by `dir' and call + * `func' on each entry with the fid, the name, and `arg'. + */ + +int +adir_readdir (VenusFid dir, + void (*func)(VenusFid *, const char *, void *), + void *arg, + CredCacheEntry *ce) +{ + int fd; + fbuf the_fbuf; + DirPage0 *page0; + unsigned i, j; + FCacheEntry *centry; + int ret; + int close_ret; + VenusFid fid; + unsigned len; + struct stat sb; + unsigned npages; + + ret = fcache_get (¢ry, dir, ce); + if (ret) + return ret; + + ret = fcache_get_data (centry, ce); + if (ret) { + fcache_release (centry); + return ret; + } + + if (centry->status.FileType != TYPE_DIR) { + fcache_release (centry); + return ENOTDIR; + } + + fd = fcache_open_file (centry, O_RDONLY); + if (fd < 0) { + fcache_release(centry); + return errno; + } + + if (fstat (fd, &sb)) { + fcache_release(centry); + close_ret = close (fd); + assert (close_ret == 0); + return errno; + } + + len = sb.st_size; + + ret = fbuf_create (&the_fbuf, fd, len, FBUF_READ); + if (ret) { + fcache_release(centry); + return ret; + } + page0 = (DirPage0 *)(the_fbuf.buf); + npages = ntohs(page0->header.pg_pgcount); + + if (npages < len / AFSDIR_PAGESIZE) + npages = len / AFSDIR_PAGESIZE; + + for (i = 0; i < npages; ++i) { + DirPage1 *page = getpage (page0, i); + unsigned first_slot; + + if (i == 0) + first_slot = 12; + else + first_slot = 0; + + for (j = first_slot; j < ENTRIESPERPAGE - 1; ++j) { + if (used_slot (page, j + 1)) { + DirEntry *entry = &page->entry[j]; + + assert (entry->flag); + + fid.Cell = dir.Cell; + fid.fid.Volume = dir.fid.Volume; + fid.fid.Vnode = ntohl (entry->fid.Vnode); + fid.fid.Unique = ntohl (entry->fid.Unique); + + (*func)(&fid, entry->name, arg); + + j += additional_entries (entry->name); + } + } + } + + fbuf_end (&the_fbuf); + fcache_release(centry); + return 0; +} + +/* * Create a new directory with only . and .. */ @@ -419,13 +667,20 @@ adir_mkdir (FCacheEntry *dir, int ind; int i; int tmp; + int close_ret; assert (CheckLock(&dir->lock) == -1); - fd = fcache_open_file (dir, O_RDWR | O_CREAT | O_TRUNC, 0666); + fd = fcache_open_file (dir, O_RDWR); if (fd < 0) return errno; + if (ftruncate (fd, 0) < 0) { + close_ret = close (fd); + assert (close_ret == 0); + return errno; + } + ret = fbuf_create (&the_fbuf, fd, 0, FBUF_WRITE); if (ret) return ret; @@ -462,13 +717,13 @@ adir_mkdir (FCacheEntry *dir, page0->dheader.hash[hashentry("..")] = htons(ind + 1); out: - assert (dir->status.Length == the_fbuf.len); + fcache_update_length (dir, fbuf_len(&the_fbuf)); fbuf_end (&the_fbuf); return ret; } /* - * Create a new entry with name `filename' and contents `fid' in `dir. + * Create a new entry with name `filename' and contents `fid' in `dir'. */ int @@ -478,6 +733,7 @@ adir_creat (FCacheEntry *dir, { fbuf the_fbuf; int ret; + int close_ret; int fd; int i; size_t len; @@ -492,12 +748,13 @@ adir_creat (FCacheEntry *dir, assert (dir->flags.datap); - fd = fcache_open_file (dir, O_RDWR, 0); + fd = fcache_open_file (dir, O_RDWR); if (fd < 0) return errno; if(fstat (fd, &statbuf) < 0) { - close (fd); + close_ret = close (fd); + assert (close_ret == 0); return errno; } @@ -507,6 +764,8 @@ adir_creat (FCacheEntry *dir, if (ret) return ret; + assert (the_fbuf.len != 0); + page0 = (DirPage0 *)(the_fbuf.buf); npages = ntohs(page0->header.pg_pgcount); @@ -515,20 +774,20 @@ adir_creat (FCacheEntry *dir, hash_value = hashentry (name); next = page0->dheader.hash[hash_value]; - for (i = 0; i < npages; ++i) - if (page0->dheader.map[i]) { - page = (DirPage1 *)((char *)page0 + i * AFSDIR_PAGESIZE); - ind = add_to_page (page0, page, i, name, fid, next); - if (ind >= 0) - break; - } + for (i = 0; i < npages; ++i) { + page = getpage (page0, i); + ind = add_to_page (page0, page, i, name, fid, next); + if (ind >= 0) + break; + } if (i == npages) { ret = create_new_page (&page, &the_fbuf); if (ret) goto out; page0 = (DirPage0 *)(the_fbuf.buf); page0->header.pg_pgcount = htons(npages + 1); - page0->dheader.map[i] = ENTRIESPERPAGE - 1; + if (i < MAXPAGES) + page0->dheader.map[i] = ENTRIESPERPAGE - 1; ind = add_to_page (page0, page, i, name, fid, next); assert (ind >= 0); } @@ -537,7 +796,7 @@ adir_creat (FCacheEntry *dir, page0->dheader.hash[hash_value] = htons(ind + 1); out: - /* assert (dir->status.Length == the_fbuf.len); */ + fcache_update_length (dir, fbuf_len(&the_fbuf)); fbuf_end (&the_fbuf); return ret; } @@ -552,6 +811,7 @@ adir_remove (FCacheEntry *dir, { fbuf the_fbuf; int ret; + int close_ret; int fd; int i; unsigned len; @@ -569,23 +829,22 @@ adir_remove (FCacheEntry *dir, assert (dir->flags.datap); - fd = fcache_open_file (dir, O_RDWR, 0); + fd = fcache_open_file (dir, O_RDWR); if (fd < 0) return errno; -#if 0 - len = dir->status.Length; -#endif if (fstat (fd, &sb)) { - close (fd); + close_ret = close (fd); + assert (close_ret == 0); return errno; } + assert (dir->status.Length == sb.st_size); + len = sb.st_size; ret = fbuf_create (&the_fbuf, fd, len, FBUF_WRITE); if (ret) { - close (fd); return ret; } @@ -617,17 +876,18 @@ adir_remove (FCacheEntry *dir, prev_entry->next = entry->next; pageno = (i - 1) / ENTRIESPERPAGE; - page = (DirPage1 *)((char *)page0 + pageno * AFSDIR_PAGESIZE); + page = getpage (page0, pageno); remove_from_page (page0, page, pageno, (i - 1) % ENTRIESPERPAGE); if (pageno == npages - 1 - && page0->dheader.map[pageno] == ENTRIESPERPAGE - 1) { + && is_page_empty (page0, pageno)) { do { len -= AFSDIR_PAGESIZE; --pageno; --npages; - } while(page0->dheader.map[pageno] == ENTRIESPERPAGE - 1); + } while(is_page_empty(page0, pageno)); page0->header.pg_pgcount = htons(npages); fbuf_truncate (&the_fbuf, len); + fcache_update_length (dir, len); } fbuf_end (&the_fbuf); return 0; diff --git a/usr.sbin/afs/src/arlad/adir.h b/usr.sbin/afs/src/arlad/adir.h index bb4e7b3751e..b0c3826e926 100644 --- a/usr.sbin/afs/src/arlad/adir.h +++ b/usr.sbin/afs/src/arlad/adir.h @@ -1,4 +1,4 @@ -/* $OpenBSD: adir.h,v 1.1.1.1 1998/09/14 21:52:54 art Exp $ */ +/* $OpenBSD: adir.h,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * Interface to directory handling routines */ -/* $KTH: adir.h,v 1.8 1998/03/18 14:14:17 assar Exp $ */ +/* $KTH: adir.h,v 1.10 1998/11/14 04:04:02 lha Exp $ */ #ifndef _ADIR_H_ #define _ADIR_H_ @@ -53,6 +53,20 @@ int adir_lookup (VenusFid dir, const char *name, VenusFid *file, CredCacheEntry *ce); +int +adir_lookup_fcacheentry (FCacheEntry *centry, const char *name, + VenusFid *file, CredCacheEntry *ce); + +int +adir_changefid (VenusFid dir, + const char *name, + VenusFid *file, + CredCacheEntry *ce); + +int +adir_emptyp (VenusFid dir, + CredCacheEntry *ce); + int adir_readdir (VenusFid dir, void (*)(VenusFid *, const char *name, void *), void *arg, diff --git a/usr.sbin/afs/src/arlad/afs_dir.h b/usr.sbin/afs/src/arlad/afs_dir.h index 8ba3b201fbd..b3e49aa0e22 100644 --- a/usr.sbin/afs/src/arlad/afs_dir.h +++ b/usr.sbin/afs/src/arlad/afs_dir.h @@ -1,4 +1,4 @@ -/* $OpenBSD: afs_dir.h,v 1.1.1.1 1998/09/14 21:52:54 art Exp $ */ +/* $OpenBSD: afs_dir.h,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * The directory structure used by AFS. */ -/* $KTH: afs_dir.h,v 1.4 1998/02/21 17:19:59 assar Exp $ */ +/* $KTH: afs_dir.h,v 1.5 1998/12/01 22:45:14 assar Exp $ */ #ifndef _AFS_DIR_ #define _AFS_DIR_ @@ -50,9 +50,9 @@ #define ADIRHASHSIZE 128 #define ENTRIESPERPAGE 64 -#define MAXPAGES 128 +/* number of pages in map */ -/* Is this really so? */ +#define MAXPAGES 128 /* * We only save vnode and unique in the directory. Everything else is diff --git a/usr.sbin/afs/src/arlad/afsdir_check.c b/usr.sbin/afs/src/arlad/afsdir_check.c index 2d37ce641b6..133005ab7ce 100644 --- a/usr.sbin/afs/src/arlad/afsdir_check.c +++ b/usr.sbin/afs/src/arlad/afsdir_check.c @@ -1,4 +1,4 @@ -/* $OpenBSD: afsdir_check.c,v 1.1.1.1 1998/09/14 21:52:54 art Exp $ */ +/* $OpenBSD: afsdir_check.c,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -43,7 +43,7 @@ #include "arla_local.h" -RCSID("$KTH: afsdir_check.c,v 1.7 1998/04/05 03:33:09 assar Exp $"); +RCSID("$KTH: afsdir_check.c,v 1.8 1998/12/01 22:44:14 assar Exp $"); /* * Hash the filename of one entry. @@ -96,7 +96,7 @@ check (const char *filename) unsigned page_entry_count; unsigned hash_entry_count; unsigned noverfill; - u_int8_t my_bitmaps[MAXPAGES][ENTRIESPERPAGE / 8]; + u_int8_t **my_bitmaps = NULL; fd = open (filename, O_RDONLY | O_BINARY, 0); if (fd < 0) @@ -124,8 +124,12 @@ check (const char *filename) npages = len / AFSDIR_PAGESIZE; + my_bitmaps = malloc (npages * sizeof(*my_bitmaps)); + if (my_bitmaps == NULL) + err (1, "malloc %u", npages * sizeof(*my_bitmaps)); + printf ("map: "); - for (i = 0; i < npages; ++i) { + for (i = 0; i < min(npages, MAXPAGES); ++i) { printf ("%u ", page0->dheader.map[i]); } printf ("\n"); @@ -135,6 +139,13 @@ check (const char *filename) for (i = 0; i < npages; ++i) { PageHeader *ph = (PageHeader *)((char *)page0 + i * AFSDIR_PAGESIZE); int start; + size_t sz = ENTRIESPERPAGE / 8 * sizeof(*my_bitmaps[i]); + + my_bitmaps[i] = malloc (sz); + if (my_bitmaps[i] == NULL) + err (1, "malloc %u", sz); + + memset (my_bitmaps[i], 0, sz); if (ph->pg_tag != htons(AFSDIRMAGIC)) { printf ("page %d: wrong tag: %u\n", i, htons(ph->pg_tag)); @@ -183,8 +194,6 @@ check (const char *filename) hash_entry_count = 0; noverfill = 0; - memset (my_bitmaps, 0, sizeof(my_bitmaps)); - for (i = 0; i < ADIRHASHSIZE; ++i) { const DirEntry *entry; @@ -265,6 +274,11 @@ check (const char *filename) out: fbuf_end (&the_fbuf); + if (my_bitmaps) { + for (i = 0; i < npages; ++i) + free (my_bitmaps[i]); + free (my_bitmaps); + } return ret; } diff --git a/usr.sbin/afs/src/arlad/arla.c b/usr.sbin/afs/src/arlad/arla.c index 8ea5439f9e7..96035be425a 100644 --- a/usr.sbin/afs/src/arlad/arla.c +++ b/usr.sbin/afs/src/arlad/arla.c @@ -1,7 +1,6 @@ -/* $OpenBSD: arla.c,v 1.1.1.1 1998/09/14 21:52:54 art Exp $ */ -/* $OpenBSD: arla.c,v 1.1.1.1 1998/09/14 21:52:54 art Exp $ */ +/* $OpenBSD: arla.c,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -49,7 +48,7 @@ #include <version.h> -RCSID("$KTH: arla.c,v 1.87 1998/08/23 22:50:22 assar Exp $") ; +RCSID("$KTH: arla.c,v 1.101 1999/04/14 16:00:16 map Exp $") ; enum connected_mode connected_mode = CONNECTED; @@ -61,6 +60,8 @@ static VenusFid rootcwd; static int arla_chdir(int, char **); static int arla_ls(int, char **); static int arla_cat(int, char **); +static int arla_cp(int, char **); +static int arla_wc(int, char **); static int help(int, char **); static int arla_quit(int, char **); static int arla_conn_status(int, char **); @@ -68,7 +69,9 @@ static int arla_vol_status(int, char **); static int arla_cred_status(int, char **); static int arla_fcache_status(int, char **); static int arla_sysname(int, char**); +#ifdef RXDEBUG static int arla_rx_status(int argc, char **argv); +#endif static int arla_flushfid(int argc, char **argv); static SL_cmd cmds[] = { @@ -76,13 +79,17 @@ static SL_cmd cmds[] = { {"cd"}, {"ls", arla_ls, "ls"}, {"cat", arla_cat, "cat file"}, + {"cp", arla_cp, "copy file"}, + {"wc", arla_wc, "wc file"}, {"help", help, "help"}, {"?"}, {"conn-status", arla_conn_status, "connection status"}, {"vol-status", arla_vol_status, "volume cache status"}, {"cred-status", arla_cred_status, "credentials status"}, {"fcache-status", arla_fcache_status, "file cache status"}, +#ifdef RXDEBUG {"rx-status", arla_rx_status, "rx connection status"}, +#endif {"flushfid", arla_flushfid, "flush a fid from the cache"}, {"quit", arla_quit, "quit"}, {"exit"}, @@ -158,7 +165,7 @@ newwalk (VenusFid *startdir, char *fname) } error = fcache_get_data (entry, tmpce); if (error) { - ReleaseWriteLock (&entry->lock); + fcache_release(entry); arla_warn (ADEBWARN, error, "fcache_get_data"); return -1; @@ -168,17 +175,17 @@ newwalk (VenusFid *startdir, char *fname) int len; int fd; - fd = fcache_open_file (entry, O_RDONLY, 0); + fd = fcache_open_file (entry, O_RDONLY); /* read the symlink and null-terminate it */ if (fd < 0) { - ReleaseWriteLock(&entry->lock); + fcache_release(entry); arla_warn (ADEBWARN, errno, "fcache_open_file"); return -1; } len = read (fd, symlink, sizeof(symlink)); close (fd); if (len <= 0) { - ReleaseWriteLock(&entry->lock); + fcache_release(entry); arla_warnx (ADEBWARN, "cannot read symlink"); return -1; } @@ -196,7 +203,7 @@ newwalk (VenusFid *startdir, char *fname) /* if not a symlink, just update cwd */ cwd = file; } - ReleaseWriteLock (&entry->lock); + fcache_release(entry); /* the *fname condition below deals with a trailing / in a * path-name */ @@ -284,15 +291,15 @@ arla_sysname (int argc, char **argv) } - static int -arla_cat (int argc, char **argv) +arla_cat_et_wc (int argc, char **argv, int do_cat, int out_fd) { VenusFid fid; int fd; char buf[8192]; int ret; FCacheEntry *e; + size_t size = 0; if (argc != 2) { printf ("usage: %s file\n", argv[0]); @@ -308,28 +315,73 @@ arla_cat (int argc, char **argv) } ret = fcache_get_data (e, tmpce); if (ret) { - ReleaseWriteLock (&e->lock); + fcache_release(e); printf ("fcache_get_data failed: %d\n", ret); return 0; } - fd = fcache_open_file (e, O_RDONLY, 0); + fd = fcache_open_file (e, O_RDONLY); if (fd < 0) { - ReleaseWriteLock (&e->lock); + fcache_release(e); printf ("fcache_open_file failed: %d\n", errno); return 0; } while ((ret = read (fd, buf, sizeof(buf))) > 0) { - write (STDOUT_FILENO, buf, ret); + if(do_cat) + write (out_fd, buf, ret); + else + size += ret; } + if(!do_cat) + printf("%lu %s\n", (unsigned long)size, argv[1]); close (fd); - ReleaseWriteLock (&e->lock); + fcache_release(e); } return 0; } static int +arla_cat (int argc, char **argv) +{ + return arla_cat_et_wc(argc, argv, 1, STDOUT_FILENO); +} + +static int +arla_cp (int argc, char **argv) +{ + char *nargv[3]; + int fd, ret; + + if (argc != 3) { + printf ("usage: %s from-file to-file\n", argv[0]); + return 0; + } + + fd = open (argv[2], O_CREAT|O_WRONLY|O_TRUNC, 0600); + if (fd < 0) { + warn ("open"); + return 0; + } + + nargv[0] = argv[0]; + nargv[1] = argv[1]; + nargv[2] = NULL; + + ret = arla_cat_et_wc(argc-1, nargv, 1, fd); + close (fd); + return ret; + +} + +static int +arla_wc (int argc, char **argv) +{ + return arla_cat_et_wc(argc, argv, 0, -1); +} + + +static int help (int argc, char **argv) { sl_help(cmds, argc, argv); @@ -339,38 +391,39 @@ help (int argc, char **argv) static int arla_conn_status (int argc, char **argv) { - conn_status (stderr); + conn_status (); return 0; } static int arla_vol_status (int argc, char **argv) { - volcache_status (stderr); + volcache_status (); return 0; } static int arla_cred_status (int argc, char **argv) { - cred_status (stderr); + cred_status (); return 0; } static int arla_fcache_status (int argc, char **argv) { - fcache_status (stderr); + fcache_status (); return 0; } +#ifdef RXDEBUG static int arla_rx_status(int argc, char **argv) { rx_PrintStats(stderr); return 0; } - +#endif static void initrx (int port) @@ -406,6 +459,10 @@ get_cred(const char *princ, const char *inst, const char *krealm, #define KERNEL_STACKSIZE (16*1024) +/* + * + */ + static void store_state (void) { @@ -452,7 +509,8 @@ daemonify (void) dup2 (fd, STDIN_FILENO); dup2 (fd, STDOUT_FILENO); dup2 (fd, STDERR_FILENO); - close (fd); + if (fd > 2) + close (fd); } struct conf_param { @@ -550,6 +608,23 @@ read_conffile(char *fname, fclose(fp); } +#if KERBEROS && !defined(HAVE_KRB_GET_ERR_TEXT) + +#ifndef MAX_KRB_ERRORS +#define MAX_KRB_ERRORS 256 +#endif + +static const char err_failure[] = "Unknown error code passed (krb_get_err_text)"; + +const char * +krb_get_err_text(int code) +{ + if(code < 0 || code >= MAX_KRB_ERRORS) + return err_failure; + return krb_err_txt[code]; +} +#endif + static unsigned low_vnodes, high_vnodes, low_bytes, high_bytes; static unsigned numcreds, numconns, numvols; @@ -581,6 +656,7 @@ static int help_flag; static int no_fork; static int client_port = 4711; static int recover = 1; +static int num_workers = 16; static struct getargs args[] = { {"test", 't', arg_flag, &test_flag, @@ -610,6 +686,8 @@ static struct getargs args[] = { "don't recover state", NULL}, {"cache-dir", 0, arg_string, &cache_dir, "cache directory", NULL}, + {"workers", 0, arg_integer, &num_workers, + "number of worker threads", NULL}, {"version", 0, arg_flag, &version_flag, NULL, NULL}, {"help", 0, arg_flag, &help_flag, @@ -671,7 +749,8 @@ usage (int ret) { arg_printusage (args, NULL, - "[device]"); + "[device]", + 0); exit (ret); } @@ -712,6 +791,9 @@ main (int argc, char **argv) if (argc != 0) usage (1); + if (!no_fork) + daemonify (); + if (temp_sysname == NULL) temp_sysname = arla_getsysname (); @@ -760,9 +842,6 @@ main (int argc, char **argv) read_conffile(conf_file, conf_params); - if (!test_flag && !no_fork) - daemonify (); - if (cache_dir == NULL) cache_dir = ARLACACHEDIR; @@ -780,8 +859,10 @@ main (int argc, char **argv) arla_warnx (ADEBINIT,"Arlad booting sequence:"); arla_warnx (ADEBINIT, "connected mode: %s", connected_levels[connected_mode]); - arla_warnx (ADEBINIT, "initports"); - initports (); + arla_warnx (ADEBINIT, "ports_init"); + ports_init (); + arla_warnx (ADEBINIT, "rx"); + initrx (client_port); arla_warnx (ADEBINIT, "conn_init numconns = %u", numconns); conn_init (numconns); arla_warnx (ADEBINIT, "cellcache"); @@ -792,8 +873,6 @@ main (int argc, char **argv) volcache_init (numvols, recover); if (root_volume != NULL) volcache_set_rootvolume (root_volume); - arla_warnx (ADEBINIT, "rx"); - initrx (client_port); #ifdef KERBEROS arla_warnx (ADEBINIT, "using rxkad level %s", rxkad_level_units[rxkad_min_level]); @@ -839,7 +918,7 @@ main (int argc, char **argv) "getting ticket for %s: %s", this_cell, krb_get_err_text (ret)); - } else if (cred_add_krb4(getuid(), &krbdata.c) == NULL) { + } else if (cred_add_krb4(getuid(), getuid(), &krbdata.c) == NULL) { arla_warnx (ADEBWARN, "Could not insert tokens to arla"); } } @@ -856,12 +935,19 @@ main (int argc, char **argv) sl_loop(cmds, "arla> "); store_state (); } else { + struct kernel_args kernel_args; + xfs_message_init (); + kernel_args.device = device_file; + kernel_args.num_workers = num_workers; + if (LWP_CreateProcess (kernel_interface, KERNEL_STACKSIZE, 1, - device_file, "Kernel-interface", &kernelpid)) + (char *)&kernel_args, + "Kernel-interface", &kernelpid)) arla_errx (1, ADEBERROR, "Cannot create kernel-interface process"); + LWP_WaitProcess ((char *)main); abort (); } diff --git a/usr.sbin/afs/src/arlad/arla_local.h b/usr.sbin/afs/src/arlad/arla_local.h index 86a87661f1f..6ae8558a26d 100644 --- a/usr.sbin/afs/src/arlad/arla_local.h +++ b/usr.sbin/afs/src/arlad/arla_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: arla_local.h,v 1.1.1.1 1998/09/14 21:52:54 art Exp $ */ +/* $OpenBSD: arla_local.h,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,7 +39,7 @@ /* * Include file for whole arlad - * $KTH: arla_local.h,v 1.32 1998/07/03 12:38:19 assar Exp $ + * $KTH: arla_local.h,v 1.42 1999/02/05 07:28:36 lha Exp $ */ #ifdef HAVE_CONFIG_H @@ -52,12 +52,12 @@ #include <assert.h> #include <ctype.h> #include <time.h> +#include <limits.h> #include <errno.h> #include <sys/time.h> -#ifdef HAVE_DIRENT_H +#if defined(HAVE_DIRENT_H) #include <dirent.h> -#endif -#ifdef USE_SYS_DIR_H +#elif defined(HAVE_SYS_DIR_H) #include <sys/dir.h> #endif #include <unistd.h> @@ -80,6 +80,7 @@ #include <arpa/inet.h> #include <netdb.h> #include <fcntl.h> +#include <pwd.h> #include <err.h> #include <parse_units.h> #include <roken.h> @@ -89,10 +90,11 @@ #include <rx/rx.h> #include <rx/rx_null.h> +#include <rx/rxgencon.h> #ifdef KERBEROS #include <des.h> -#include <kerberosIV/krb.h> +#include <krb.h> #include <rxkad.h> #endif @@ -100,7 +102,7 @@ #include <mmaptime.h> #endif -#include <kerberosIV/kafs.h> +#include <kafs.h> #include "log.h" @@ -112,14 +114,13 @@ #include "vldb.cs.h" #include "volcache.h" #include "fbuf.h" -#include "fcache.h" #include "hash.h" #include "afs_dir.h" #include "ip.h" #include "service.h" #include "ports.h" -#include "fcache.h" #include "conn.h" +#include "fcache.h" #include "inter.h" #include "cred.h" #include "adir.h" @@ -131,12 +132,10 @@ #include "kernel.h" #include "messages.h" #include "strutil.h" +#include "fs_errors.h" #include "arladeb.h" #include "ko.h" -#define SYSNAMEMAXLEN 2048 -extern char arlasysname[SYSNAMEMAXLEN]; - enum connected_mode { CONNECTED = 0, FETCH_ONLY = 1, DISCONNECTED = 2, @@ -144,6 +143,15 @@ enum connected_mode { CONNECTED = 0, extern enum connected_mode connected_mode; +#include "darla.h" +#include "discon_log.h" +#include "discon.h" +#include "reconnect.h" + +#define SYSNAMEMAXLEN 2048 +extern char arlasysname[SYSNAMEMAXLEN]; + + #define ARLA_NUMCONNS 200 #define ARLA_HIGH_VNODES 4000 #define ARLA_LOW_VNODES 3000 diff --git a/usr.sbin/afs/src/arlad/arladeb.c b/usr.sbin/afs/src/arlad/arladeb.c index 0af13d7297e..e6706b75edd 100644 --- a/usr.sbin/afs/src/arlad/arladeb.c +++ b/usr.sbin/afs/src/arlad/arladeb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: arladeb.c,v 1.1.1.1 1998/09/14 21:52:55 art Exp $ */ +/* $OpenBSD: arladeb.c,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,31 +39,40 @@ #include "arla_local.h" -RCSID("$KTH: arladeb.c,v 1.12 1998/04/03 03:30:17 assar Exp $"); +RCSID("$KTH: arladeb.c,v 1.15 1999/04/20 20:58:07 map Exp $"); static Log_method* arla_log_method = NULL; +#define all (ADEBERROR | ADEBWARN | ADEBDISCONN | ADEBFBUF | \ + ADEBMSG | ADEBKERNEL | ADEBCLEANER | ADEBCALLBACK | \ + ADEBCM | ADEBVOLCACHE | ADEBFCACHE | ADEBINIT | \ + ADEBCONN | ADEBMISC | ADEBVLOG) + +#define DEFAULT_LOG (ADEBWARN | ADEBERROR) + struct units arla_deb_units[] = { - { "all", (unsigned)(~0) >> 1 }, - { "miscellaneous", ADEBMISC }, - { "connection", ADEBCONN }, - { "initialization", ADEBINIT }, - { "file-cache", ADEBFCACHE }, - { "volume-cache", ADEBVOLCACHE }, - { "cache-manager", ADEBCM }, - { "callbacks", ADEBCALLBACK }, - { "cleaner", ADEBCLEANER }, - { "kernel", ADEBKERNEL }, - { "messages", ADEBMSG }, - { "fbuf", ADEBFBUF }, - { "warnings", ADEBWARN }, + { "all", all}, + { "almost-all", all & ~ADEBCLEANER}, { "errors", ADEBERROR }, + { "warnings", ADEBWARN }, + { "disconn", ADEBDISCONN }, + { "fbuf", ADEBFBUF }, + { "messages", ADEBMSG }, + { "kernel", ADEBKERNEL }, + { "cleaner", ADEBCLEANER }, + { "callbacks", ADEBCALLBACK }, + { "cache-manager", ADEBCM }, + { "volume-cache", ADEBVOLCACHE }, + { "file-cache", ADEBFCACHE }, + { "initialization", ADEBINIT }, + { "connection", ADEBCONN }, + { "miscellaneous", ADEBMISC }, + { "venuslog", ADEBVLOG }, + { "default", DEFAULT_LOG }, { "none", 0 }, { NULL } }; -#define DEFAULT_LOG (ADEBWARN | ADEBERROR) - void arla_log(unsigned level, char *fmt, ...) { @@ -100,12 +109,24 @@ arla_log_set_level (const char *s) } void +arla_log_set_level_num (unsigned level) +{ + log_set_mask (arla_log_method, level); +} + +void arla_log_get_level (char *s, size_t len) { unparse_flags (log_get_mask (arla_log_method), arla_deb_units, s, len); } +unsigned +arla_log_get_level_num (void) +{ + return log_get_mask (arla_log_method); +} + void arla_log_print_levels (FILE *f) { diff --git a/usr.sbin/afs/src/arlad/arladeb.h b/usr.sbin/afs/src/arlad/arladeb.h index 36c3d9e9f14..8d53bcc0272 100644 --- a/usr.sbin/afs/src/arlad/arladeb.h +++ b/usr.sbin/afs/src/arlad/arladeb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: arladeb.h,v 1.1.1.1 1998/09/14 21:52:55 art Exp $ */ +/* $OpenBSD: arladeb.h,v 1.2 1999/04/30 01:59:06 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -38,7 +38,7 @@ */ /* - * $KTH: arladeb.h,v 1.16 1998/05/23 05:25:47 assar Exp $ + * $KTH: arladeb.h,v 1.19 1999/04/20 20:58:07 map Exp $ */ #ifndef _arladeb_h @@ -62,13 +62,19 @@ #define ADEBKERNEL 0x00000100 /* kernel interface */ #define ADEBMSG 0x00000200 /* messages */ #define ADEBFBUF 0x00000400 /* fbuf */ +#define ADEBDISCONN 0x00000800 /* disconn */ #define ADEBWARN 0x08000000 /* don't ignore warning */ #define ADEBERROR 0x10000000 /* don't ignore error */ +#define ADEBVLOG 0x20000000 /* venuslog output */ + +extern struct units arla_deb_units[]; void arla_log(unsigned level, char *fmt, ...); void arla_loginit(char *log); int arla_log_set_level (const char *s); +void arla_log_set_level_num (unsigned level); void arla_log_get_level (char *s, size_t len); +unsigned arla_log_get_level_num (void); void arla_log_print_levels (FILE *f); void diff --git a/usr.sbin/afs/src/arlad/bsd-subr.c b/usr.sbin/afs/src/arlad/bsd-subr.c index a41669f1d70..dc504f1f067 100644 --- a/usr.sbin/afs/src/arlad/bsd-subr.c +++ b/usr.sbin/afs/src/arlad/bsd-subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bsd-subr.c,v 1.1.1.1 1998/09/14 21:52:55 art Exp $ */ +/* $OpenBSD: bsd-subr.c,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -43,50 +43,73 @@ #define _BSD #endif #include "arla_local.h" -RCSID("$KTH: bsd-subr.c,v 1.24 1998/05/02 02:28:46 assar Exp $"); +RCSID("$KTH: bsd-subr.c,v 1.32 1998/12/22 13:15:54 lha Exp $"); -static long blocksize = 1024; /* XXX */ +#ifdef __linux__ +#include <xfs/xfs_dirent.h> +#else +#define XFS_DIRENT_BLOCKSIZE 1024 +#define xfs_dirent dirent +#endif +#if defined(GENERIC_DIRSIZ_IN_SYS_DIRENT_H) +#include <sys/dirent.h> +#elif defined(DIRSIZ_IN_DIRENT_H) +#include <dirent.h> +#elif defined(DIRSIZ_IN_SYS_DIR_H) +#include <sys/dir.h> +#endif + +static long blocksize = XFS_DIRENT_BLOCKSIZE; /* XXX */ struct args { int fd; off_t off; char *buf; char *ptr; - struct dirent *last; + struct xfs_dirent *last; FCacheEntry *e; }; +/* + * Write out all remaining data in `args' + */ + static void flushbuf (struct args *args) { unsigned inc = blocksize - (args->ptr - args->buf); args->last->d_reclen += inc; -#if 0 - args->last->d_off += inc; -#endif if (write (args->fd, args->buf, blocksize) != blocksize) arla_warn (ADEBWARN, errno, "write"); args->ptr = args->buf; args->last = NULL; } +/* + * Write a dirent to the args buf in `arg' containg `fid' and `name'. + */ + static void write_dirent(VenusFid *fid, const char *name, void *arg) { - struct dirent dirent, *real; + struct xfs_dirent dirent, *real; struct args *args = (struct args *)arg; dirent.d_namlen = strlen (name); +#ifdef _GENERIC_DIRSIZ + dirent.d_reclen = _GENERIC_DIRSIZ(&dirent); +#else dirent.d_reclen = DIRSIZ(&dirent); +#endif if (args->ptr + dirent.d_reclen > args->buf + blocksize) flushbuf (args); - real = (struct dirent *)args->ptr; + real = (struct xfs_dirent *)args->ptr; real->d_namlen = dirent.d_namlen; real->d_reclen = dirent.d_reclen; -#ifdef HAVE_STRUCT_DIRENT_D_TYPE +#if defined(HAVE_STRUCT_DIRENT_D_TYPE) && !defined(__linux__) real->d_type = DT_UNKNOWN; #endif @@ -114,23 +137,34 @@ write_dirent(VenusFid *fid, const char *name, void *arg) */ Result -conv_dir (FCacheEntry *e, char *handle, size_t handle_size, - CredCacheEntry *ce, u_int tokens) +conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, + xfs_cache_handle *cache_handle, + char *cache_name, size_t cache_name_sz) { struct args args; Result res; + int ret; e->flags.extradirp = TRUE; - fcache_extra_file_name (e, handle, handle_size); + fcache_extra_file_name (e, cache_name, cache_name_sz); res.tokens = e->tokens |= XFS_DATA_R | XFS_OPEN_NR; - args.fd = open (handle, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); + args.fd = open (cache_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666); if (args.fd == -1) { res.res = -1; res.error = errno; - arla_warn (ADEBWARN, errno, "open %s", handle); + arla_warn (ADEBWARN, errno, "open %s", cache_name); return res; } + ret = fcache_fhget (cache_name, cache_handle); + if(ret) { + res.res = -1; + res.error = errno; + close (args.fd); + arla_warn (ADEBWARN, res.error, "fcache_fhget(%s)", cache_name); + return res; + } + args.off = 0; args.buf = (char *)malloc (blocksize); if (args.buf == NULL) { @@ -143,9 +177,9 @@ conv_dir (FCacheEntry *e, char *handle, size_t handle_size, args.ptr = args.buf; args.last = NULL; args.e = e; - ReleaseWriteLock (&e->lock); + ReleaseWriteLock (&e->lock); /* XXX */ adir_readdir (e->fid, write_dirent, (void *)&args, ce); - ObtainWriteLock (&e->lock); + ObtainWriteLock (&e->lock); /* XXX */ if (args.last) flushbuf (&args); free (args.buf); diff --git a/usr.sbin/afs/src/arlad/cmcb.c b/usr.sbin/afs/src/arlad/cmcb.c index 4894e150a8f..e7f3dd34515 100644 --- a/usr.sbin/afs/src/arlad/cmcb.c +++ b/usr.sbin/afs/src/arlad/cmcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmcb.c,v 1.1.1.1 1998/09/14 21:52:55 art Exp $ */ +/* $OpenBSD: cmcb.c,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -42,7 +42,7 @@ */ #include "arla_local.h" -RCSID("$KTH: cmcb.c,v 1.19 1998/04/03 03:32:38 assar Exp $") ; +RCSID("$KTH: cmcb.c,v 1.20 1998/11/09 20:33:44 assar Exp $") ; #include "cb.ss.h" @@ -57,19 +57,15 @@ cmcb_init (void) static struct rx_securityClass *(securityObjects[1]); nullSecObjP = rxnull_NewClientSecurityObject (); - if (nullSecObjP == NULL) { - arla_warnx (ADEBWARN, "Cannot create null security object."); - return; - } + if (nullSecObjP == NULL) + arla_errx (1, ADEBWARN, "Cannot create null security object."); securityObjects[0] = nullSecObjP; if (rx_NewService (0, CM_SERVICE_ID, "cm", securityObjects, sizeof(securityObjects) / sizeof(*securityObjects), - (long (*)())RXAFSCB_ExecuteRequest) == NULL ) { - arla_warnx (ADEBWARN, "Cannot install callback service"); - return; - } + (long (*)())RXAFSCB_ExecuteRequest) == NULL ) + arla_errx (1, ADEBWARN, "Cannot install callback service"); rx_StartServer (0); } @@ -142,11 +138,9 @@ RXAFSCB_CallBack (struct rx_call *a_rxCallP, fcache_purge_volume (fid); volcache_invalidate (fid.fid.Volume, fid.Cell); } else if (i < a_callBackArrayP->len) - fcache_stale_entry (fid, - a_callBackArrayP->val[i]); + fcache_stale_entry (fid, a_callBackArrayP->val[i]); else - fcache_stale_entry (fid, - broken_callback); + fcache_stale_entry (fid, broken_callback); } return 0; diff --git a/usr.sbin/afs/src/arlad/conn.c b/usr.sbin/afs/src/arlad/conn.c index 467aefc0a67..31d48e7e590 100644 --- a/usr.sbin/afs/src/arlad/conn.c +++ b/usr.sbin/afs/src/arlad/conn.c @@ -1,6 +1,6 @@ -/* $OpenBSD: conn.c,v 1.1.1.1 1998/09/14 21:52:55 art Exp $ */ +/* $OpenBSD: conn.c,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -44,7 +44,7 @@ #include "arla_local.h" #ifdef RCSID -RCSID("$KTH: conn.c,v 1.39 1998/07/13 19:16:55 assar Exp $") ; +RCSID("$KTH: conn.c,v 1.52 1999/04/20 20:58:07 map Exp $") ; #endif #define CONNCACHESIZE 101 @@ -63,6 +63,9 @@ static unsigned nconnections; /* # of active connections */ static unsigned nactive_connections; +/* List of connections to probe */ +static List *connprobelist; + /* * Functions for handling entries into the connection cache. */ @@ -70,24 +73,145 @@ static unsigned nactive_connections; static int conncmp (void *a, void *b) { - ConnCacheEntry *c1 = (ConnCacheEntry*)a; - ConnCacheEntry *c2 = (ConnCacheEntry*)b; - - return c1->cred != c2->cred - || c1->host != c2->host - || c1->service != c2->service - || c1->port != c2->port - || c1->securityindex != c2->securityindex; + ConnCacheEntry *c1 = (ConnCacheEntry*)a; + ConnCacheEntry *c2 = (ConnCacheEntry*)b; + + return c1->cred != c2->cred + || c1->host != c2->host + || c1->service != c2->service + || c1->port != c2->port + || c1->securityindex != c2->securityindex; } static unsigned int connhash (void *a) { - ConnCacheEntry *c = (ConnCacheEntry*)a; + ConnCacheEntry *c = (ConnCacheEntry*)a; + + return c->cred + c->host + c->service + c->port + c->securityindex; +} + + +/* + * Add this entry again to the probe list but without restarting ntries. + */ + +static void +re_probe (ConnCacheEntry *e) +{ + Listitem *item; + struct timeval tv; + + assert (!e->flags.alivep); + assert (e->probe != NULL); + + if (e->probe_le != NULL) + listdel (connprobelist, e->probe_le); + + gettimeofday (&tv, NULL); + e->probe_next = tv.tv_sec + (1 << e->ntries); + ++e->ntries; + + for (item = listhead (connprobelist); + item; + item = listnext (connprobelist, item)) { + ConnCacheEntry *this = (ConnCacheEntry *)listdata (item); + + if (e->probe_next < this->probe_next) { + e->probe_le = listaddbefore (connprobelist, item, e); + LWP_NoYieldSignal (connprobelist); + return; + } + } + e->probe_le = listaddtail (connprobelist, e); + LWP_NoYieldSignal (connprobelist); +} + +/* + * Initial add to probe list. + */ - return c->cred + c->host + c->service + c->port + c->securityindex; +static void +add_to_probe_list (ConnCacheEntry *e, int ntries) +{ + e->ntries = ntries; + re_probe (e); } +/* + * + */ + +#define PINGER_STACKSIZE (16*1024) +#define PINGER_SLEEP 10 + +#define MAX_RETRIES 5 + +static PROCESS pinger_pid; + +/* + * Loop waiting for things servers to probe. + */ + +static void +pinger (char *arg) +{ + for (;;) { + struct timeval tv; + Listitem *item; + ConnCacheEntry *e; + struct in_addr addr; + const char *port_str; + + arla_warnx(ADEBCONN, "running pinger"); + + while (listemptyp (connprobelist)) + LWP_WaitProcess (connprobelist); + + item = listhead (connprobelist); + e = (ConnCacheEntry *)listdata (item); + + assert (e->probe_le == item); + + gettimeofday (&tv, NULL); + if (tv.tv_sec < e->probe_next) { + unsigned long t = e->probe_next - tv.tv_sec; + + arla_warnx(ADEBCONN, + "pinger: sleeping %lu second(s)", t); + IOMGR_Sleep (t); + continue; + } + + listdel (connprobelist, item); + e->probe_le = NULL; + + if (e->flags.alivep) + continue; + + addr.s_addr = e->host; + port_str = ports_num2name (e->port); + + if (port_str != NULL) + arla_warnx (ADEBCONN, "pinger: probing %s/%s", + inet_ntoa(addr), port_str); + else + arla_warnx (ADEBCONN, "pinger: probing %s/%d", + inet_ntoa(addr), e->port); + ++e->refcount; + if (e->probe == NULL) + arla_warnx(ADEBWARN, "pinger: probe function is NULL, " + "host: %s cell: %d port: %d", + inet_ntoa(addr), e->cell, e->port); + + if (e->probe && ((*(e->probe))(e->connection) == 0)) { + conn_alive (e); + } else if (e->ntries <= MAX_RETRIES) { + re_probe (e); + } + conn_free (e); + } +} /* * Create `n' ConnCacheEntry's and add them to `connfreelist' @@ -104,7 +228,9 @@ create_new_connections (unsigned n) arla_errx (1, ADEBERROR, "conncache: calloc failed"); for (i = 0; i < n; ++i) { entries[i].connection = NULL; - entries[i].refcount = 0 ; + entries[i].refcount = 0; + entries[i].parent = NULL; + entries[i].probe_le = NULL; listaddhead (connfreelist, &entries[i]); } nconnections += n; @@ -125,7 +251,16 @@ conn_init (unsigned nentries) connfreelist = listnew (); if (connfreelist == NULL) arla_errx (1, ADEBERROR, "conn_init: listnew failed"); + connprobelist = listnew (); + if (connprobelist == NULL) + arla_errx (1, ADEBERROR, "conn_init: listnew failed"); nconnections = 0; + + if (LWP_CreateProcess (pinger, PINGER_STACKSIZE, 1, + NULL, "pinger", &pinger_pid)) + arla_errx (1, ADEBERROR, + "conn: cannot create pinger thread"); + create_new_connections (nentries); } @@ -137,6 +272,16 @@ conn_init (unsigned nentries) static void recycle_conn (ConnCacheEntry *e) { + assert (e->refcount == 0); + + if (e->parent != NULL) { + conn_free (e->parent); + e->parent = NULL; + } + if (e->probe_le != NULL) { + listdel (connprobelist, e->probe_le); + e->probe_le = NULL; + } hashtabdel (connhtab, e); rx_DestroyConnection (e->connection); memset (e, 0, sizeof(*e)); @@ -203,10 +348,13 @@ new_connection (int32_t cell, u_int16_t service, pag_t cred, int securityindex, + int (*probe)(struct rx_connection *), struct rx_securityClass *securityobject) { ConnCacheEntry *e; + assert (probe != NULL); + e = get_free_connection (); e->cell = cell; @@ -214,9 +362,11 @@ new_connection (int32_t cell, e->port = port; e->service = service; e->flags.alivep = TRUE; + e->flags.old = FALSE; e->refcount = 0; e->cred = cred; e->securityindex = securityindex; + e->probe = probe; e->connection = rx_NewConnection (host, htons (port), @@ -237,6 +387,7 @@ add_connection(int32_t cell, u_int32_t host, u_int16_t port, u_int16_t service, + int (*probe)(struct rx_connection *), CredCacheEntry *ce) { ConnCacheEntry *e; @@ -276,7 +427,7 @@ add_connection(int32_t cell, } e = new_connection (cell, host, port, service, - cred, securityindex, securityobj); + cred, securityindex, probe, securityobj); hashtabadd (connhtab, (void *)e); ++nactive_connections; @@ -291,12 +442,13 @@ add_connection(int32_t cell, * If there's no connection at all, create one. */ -ConnCacheEntry * -conn_get (int32_t cell, - u_int32_t host, - u_int16_t port, - u_int16_t service, - CredCacheEntry *ce) +static ConnCacheEntry * +internal_get (int32_t cell, + u_int32_t host, + u_int16_t port, + u_int16_t service, + int (*probe)(struct rx_connection *), + CredCacheEntry *ce) { ConnCacheEntry *e; ConnCacheEntry key; @@ -313,18 +465,56 @@ conn_get (int32_t cell, e = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key); if (e == NULL) { + ConnCacheEntry *parent = NULL; + if (ce->securityindex || ce->cred) { key.cred = 0; key.securityindex = 0; - e = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key); - if (e == NULL) - add_connection (cell, host, port, service, NULL); + parent = (ConnCacheEntry *)hashtabsearch (connhtab, (void *)&key); + if (parent == NULL) { + parent = add_connection (cell, host, port, service, + probe, NULL); + } + ++parent->refcount; } - e = add_connection (cell, host, port, service, ce); + e = add_connection (cell, host, port, service, probe, ce); + if (parent != NULL) + e->parent = parent; + } + if(e->parent != NULL) { + e->flags.alivep = e->parent->flags.alivep; } - ++e->refcount; + return e; +} + +/* + * Dead servers don't exist. + */ + +ConnCacheEntry * +conn_get (int32_t cell, + u_int32_t host, + u_int16_t port, + u_int16_t service, + int (*probe)(struct rx_connection *), + CredCacheEntry *ce) +{ + ConnCacheEntry *e = internal_get (cell, host, port, service, probe, ce); + ConnCacheEntry *parent = e; + + if (e != NULL) { + if (e->parent != NULL) + parent = e->parent; + if (e->flags.alivep) { + ++e->refcount; + } else { + e = NULL; + add_to_probe_list (parent, + min(parent->ntries, MAX_RETRIES)); + } + } return e; } @@ -339,6 +529,8 @@ conn_free (ConnCacheEntry *e) if (e == NULL) /* When in disconnected mode conn sets to NULL */ return; + assert (e->refcount > 0); + --e->refcount; if (e->refcount == 0 && e->flags.killme) recycle_conn (e); @@ -368,6 +560,82 @@ conn_host2cell (u_int32_t host, u_int16_t port, u_int16_t service) } /* + * Mark the server in `e' as being down. + */ + +void +conn_dead (ConnCacheEntry *e) +{ + struct in_addr a; + const char *s; + + assert (e->probe != NULL); + + e->flags.alivep = FALSE; + if (e->parent != NULL) { + e = e->parent; + e->flags.alivep = FALSE; + } + add_to_probe_list (e, 0); + a.s_addr = e->host; + s = ports_num2name (e->port); + if (s != NULL) + arla_warnx (ADEBWARN, "Lost connection to %s/%s", + inet_ntoa(a), s); + else + arla_warnx (ADEBWARN, "Lost connection to %s/%d", + inet_ntoa(a), e->port); +} + +/* + * Mark the server in `e' as being up. + */ + +void +conn_alive (ConnCacheEntry *e) +{ + struct in_addr a; + const char *s; + + a.s_addr = e->host; + s = ports_num2name (e->port); + if (s != NULL) + arla_warnx (ADEBWARN, "Server %s/%s up again", inet_ntoa(a), s); + else + arla_warnx (ADEBWARN, "Server %s/%d up again", inet_ntoa(a), e->port); + e->flags.alivep = TRUE; + if (e->parent != NULL) + e->parent->flags.alivep = TRUE; +} + +/* + * Probe the service in `e' + */ + +void +conn_probe (ConnCacheEntry *e) +{ + ++e->refcount; + { + struct in_addr a; + a.s_addr = e->host; + + if (e->probe == NULL) + arla_warnx(ADEBWARN, "conn_probe: probe function is NULL, " + "host: %s cell: %d port: %d", + inet_ntoa(a), e->cell, e->port); + } + if (e->probe && ((*(e->probe))(e->connection) == 0)) { + if (!e->flags.alivep) + conn_alive (e); + } else { + if (e->flags.alivep) + conn_dead (e); + } + conn_free (e); +} + +/* * Is the service at (cell, host, port, service) up? */ @@ -398,12 +666,11 @@ static Bool print_conn (void *ptr, void *arg) { ConnCacheEntry *e = (ConnCacheEntry *)ptr; - FILE *f = (FILE *)arg; struct in_addr tmp; tmp.s_addr = e->host; - fprintf (f, "host = %s, port = %d, service = %d, " + arla_log(ADEBVLOG, "host = %s, port = %d, service = %d, " "cell = %d (%s), " "securityindex = %d, cred = %u, " "conn = %p, alive = %d, " @@ -421,11 +688,11 @@ print_conn (void *ptr, void *arg) */ void -conn_status (FILE *f) +conn_status (void) { - fprintf (f, "%u(%u) connections\n", + arla_log(ADEBVLOG, "%u(%u) connections\n", nactive_connections, nconnections); - hashtabforeach (connhtab, print_conn, f); + hashtabforeach (connhtab, print_conn, NULL); } struct clear_state { @@ -466,3 +733,86 @@ conn_clearcred(int32_t cell, pag_t cred, int securityindex) hashtabforeach (connhtab, clear_cred, (void *)&s); } + +/* + * check if servers are up for cell `cell' + */ + +struct down_state { + int32_t cell; + u_int32_t *hosts; + int len; + int i; + int flags; +}; + +static Bool +host_down (void *ptr, void *arg) +{ + ConnCacheEntry *e = (ConnCacheEntry *)ptr; + struct down_state *s = (struct down_state *)arg; + int i; + + if (s->cell == e->cell) { + + if (!(s->flags & CKSERV_DONTPING)) { + conn_probe (e); + } + + if (e->flags.alivep) + return FALSE; + + if (s->flags & CKSERV_FSONLY && e->port != afsport) + return FALSE; + + for (i = 0; i < s->i; ++i) + if (s->hosts[i] == e->host) + return FALSE; + + s->hosts[s->i] = e->host; + ++s->i; + + if (s->i == s->len) + return TRUE; + } + return FALSE; +} + +/* + * Check what hosts are down. + * + * Flags is VIOCCKFLAGS + */ + +void +conn_downhosts(int32_t cell, u_int32_t *hosts, int *num, int flags) +{ + struct down_state s; + + if (*num == 0) + return; + + s.cell = cell; + s.hosts = hosts; + s.len = *num; + s.i = 0; + s.flags = flags; + + hashtabforeach (connhtab, host_down, (void *)&s); + + *num = s.i; +} + +/* + * Compare two ConnCacheEntries rtt-wise. Typically used when sorting + * entries. + */ + +int +conn_rtt_cmp (const void *v1, const void *v2) +{ + ConnCacheEntry **e1 = (ConnCacheEntry **)v1; + ConnCacheEntry **e2 = (ConnCacheEntry **)v2; + + return (*e1)->rtt - (*e2)->rtt; +} diff --git a/usr.sbin/afs/src/arlad/conn.h b/usr.sbin/afs/src/arlad/conn.h index 42fbf2c7e55..1c68e71e932 100644 --- a/usr.sbin/afs/src/arlad/conn.h +++ b/usr.sbin/afs/src/arlad/conn.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conn.h,v 1.1.1.1 1998/09/14 21:52:55 art Exp $ */ +/* $OpenBSD: conn.h,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * Header for connection cache */ -/* $KTH: conn.h,v 1.11 1998/02/19 05:39:03 assar Exp $ */ +/* $KTH: conn.h,v 1.20 1999/04/14 15:27:34 map Exp $ */ #ifndef _CONN_H_ #define _CONN_H_ @@ -50,29 +50,48 @@ #include <xfs/xfs_message.h> #include <cred.h> -typedef struct { +struct conncacheentry { u_int32_t host; /* IP address of host */ u_int16_t port; /* port number at host */ u_int16_t service; /* RX service # */ int32_t cell; /* cell of host */ int securityindex; + int (*probe)(struct rx_connection *); pag_t cred; struct rx_connection *connection; struct { unsigned alivep : 1; unsigned killme : 1; + unsigned old : 1; /* Old server,vldb -> only VL_GetEntryByName */ } flags; unsigned refcount; -} ConnCacheEntry; + Listitem *probe_le; + unsigned probe_next; + unsigned ntries; + struct conncacheentry *parent; + int rtt; +}; + +typedef struct conncacheentry ConnCacheEntry; void conn_init (unsigned nentries); ConnCacheEntry * conn_get (int32_t cell, u_int32_t host, u_int16_t port, u_int16_t service, + int (*probe)(struct rx_connection *), CredCacheEntry *ce); void +conn_dead (ConnCacheEntry *); + +void +conn_alive (ConnCacheEntry *); + +void +conn_probe (ConnCacheEntry *); + +void conn_free (ConnCacheEntry *e); int32_t @@ -82,9 +101,22 @@ Bool conn_serverupp (u_int32_t host, u_int16_t port, u_int16_t service); void -conn_status (FILE *); +conn_status (void); void conn_clearcred (int32_t cell, pag_t cred, int securityindex); +void +conn_downhosts(int32_t cell, u_int32_t *hosts, int *num, int flags); + +int +conn_rtt_cmp (const void *v1, const void *v2); + +/* + * Random factor to add to rtts when comparing them. + * This is in milliseconds/8 + */ + +static const int RTT_FUZZ = 400; + #endif /* _CONN_H_ */ diff --git a/usr.sbin/afs/src/arlad/cred.c b/usr.sbin/afs/src/arlad/cred.c index 51f2568d395..7c2336f4d95 100644 --- a/usr.sbin/afs/src/arlad/cred.c +++ b/usr.sbin/afs/src/arlad/cred.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cred.c,v 1.1.1.1 1998/09/14 21:52:55 art Exp $ */ +/* $OpenBSD: cred.c,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -42,7 +42,7 @@ */ #include "arla_local.h" -RCSID("$KTH: cred.c,v 1.22 1998/06/08 22:26:59 map Exp $"); +RCSID("$KTH: cred.c,v 1.28 1999/04/20 20:58:07 map Exp $"); #define CREDCACHESIZE 101 @@ -134,7 +134,7 @@ internal_get (long cell, pag_t cred, int type) e = (CredCacheEntry *)hashtabsearch (credhtab, (void *)&key); if (e == NULL && type == CRED_NONE) { - e = cred_add (cred, type, 0, cell, 0, NULL, 0); + e = cred_add (cred, type, 0, cell, 0, NULL, 0, 0); } if (e != NULL) @@ -201,7 +201,8 @@ get_free_cred (void) CredCacheEntry * cred_add (pag_t cred, int type, int securityindex, long cell, - time_t expire, void *cred_data, size_t cred_data_sz) + time_t expire, void *cred_data, size_t cred_data_sz, + uid_t uid) { void *data; CredCacheEntry *e; @@ -222,7 +223,8 @@ cred_add (pag_t cred, int type, int securityindex, long cell, e->securityindex = securityindex; e->cell = cell; e->expire = expire; - e->cred_data = data; + e->cred_data = data; + e->uid = uid; old = hashtabsearch (credhtab, e); if (old != NULL) @@ -235,7 +237,7 @@ cred_add (pag_t cred, int type, int securityindex, long cell, #if KERBEROS CredCacheEntry * -cred_add_krb4 (pag_t cred, CREDENTIALS *c) +cred_add_krb4 (pag_t cred, uid_t uid, CREDENTIALS *c) { CredCacheEntry *ce; char *cellname; @@ -250,7 +252,7 @@ cred_add_krb4 (pag_t cred, CREDENTIALS *c) free (cellname); assert (cellnum != -1); - ce = cred_add (cred, CRED_KRB4, 2, cellnum, -1, c, sizeof(*c)); + ce = cred_add (cred, CRED_KRB4, 2, cellnum, -1, c, sizeof(*c), uid); return ce; } #endif @@ -275,6 +277,24 @@ cred_delete (CredCacheEntry *ce) void cred_expire (CredCacheEntry *ce) { + const char *cell_name = cell_num2name (ce->cell); + struct passwd *pwd = getpwuid (ce->uid); + const char *user_name; + + if (pwd != NULL) + user_name = pwd->pw_name; + else + user_name = "<who-are-you?>"; + + if (cell_name != NULL) + arla_warnx (ADEBWARN, + "Credentials for %s (%u) in cell %s has expired", + user_name, (unsigned)ce->uid, cell_name); + else + arla_warnx (ADEBWARN, + "Credentials for %s (%u) in cell unknown %ld has expired", + user_name, (unsigned)ce->uid, ce->cell); + cred_delete (ce); } @@ -299,19 +319,18 @@ static Bool print_cred (void *ptr, void *arg) { CredCacheEntry *e = (CredCacheEntry *)ptr; - FILE *f = (FILE *)arg; - fprintf (f, "cred = %u, type = %d, securityindex = %d\n" - "cell = %ld, refcount = %u, killme = %d\n\n", + arla_log(ADEBVLOG, "cred = %u, type = %d, securityindex = %d\n" + "cell = %ld, refcount = %u, killme = %d, uid = %lu\n\n", e->cred, e->type, e->securityindex, e->cell, e->refcount, - e->flags.killme); + e->flags.killme, (unsigned long)e->uid); return FALSE; } void -cred_status (FILE *f) +cred_status (void) { - fprintf (f, "%u(%u) credentials\n", + arla_log(ADEBVLOG, "%u(%u) credentials\n", nactive_credentials, ncredentials); - hashtabforeach (credhtab, print_cred, f); + hashtabforeach (credhtab, print_cred, NULL); } diff --git a/usr.sbin/afs/src/arlad/cred.h b/usr.sbin/afs/src/arlad/cred.h index 2faa6f91aa4..4763c4d9ffa 100644 --- a/usr.sbin/afs/src/arlad/cred.h +++ b/usr.sbin/afs/src/arlad/cred.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cred.h,v 1.1.1.1 1998/09/14 21:52:55 art Exp $ */ +/* $OpenBSD: cred.h,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * Header for credetial cache */ -/* $KTH: cred.h,v 1.18 1998/05/02 01:03:25 assar Exp $ */ +/* $KTH: cred.h,v 1.23 1999/04/14 15:27:34 map Exp $ */ #ifndef _CRED_H_ #define _CRED_H_ @@ -51,7 +51,7 @@ #include <lock.h> #ifdef KERBEROS #include <des.h> -#include <kerberosIV/krb.h> +#include <krb.h> #endif /* KERBEROS */ #include "bool.h" #include <xfs/xfs_message.h> @@ -71,6 +71,7 @@ typedef struct { typedef struct { pag_t cred; + uid_t uid; int type; int securityindex; long cell; @@ -92,7 +93,8 @@ cred_free (CredCacheEntry *ce); CredCacheEntry * cred_add (pag_t cred, int type, int securityindex, long cell, - time_t expire, void *cred_data, size_t cred_data_sz); + time_t expire, void *cred_data, size_t cred_data_sz, + uid_t uid); void cred_delete (CredCacheEntry *ce); @@ -101,10 +103,10 @@ void cred_expire (CredCacheEntry *ce); #ifdef KERBEROS -CredCacheEntry * cred_add_krb4 (pag_t cred, CREDENTIALS *c); +CredCacheEntry * cred_add_krb4 (pag_t cred, uid_t uid, CREDENTIALS *c); #endif -void cred_status (FILE *f); +void cred_status (void); void cred_remove (pag_t cred); diff --git a/usr.sbin/afs/src/arlad/darla.c b/usr.sbin/afs/src/arlad/darla.c new file mode 100644 index 00000000000..886d2e5eba0 --- /dev/null +++ b/usr.sbin/afs/src/arlad/darla.c @@ -0,0 +1,104 @@ +/* $OpenBSD: darla.c,v 1.1 1999/04/30 01:59:07 art Exp $ */ +/* COPYRIGHT (C) 1998 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS + * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS + * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF + * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY + * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE + * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE + * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE + * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY + * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST + * ALSO BE INCLUDED. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +#include "arla_local.h" + +RCSID("$KTH: darla.c,v 1.5 1998/12/21 21:54:03 assar Exp $"); + +int DARLA_Open(DARLA_file *Dfp, char *fname, int oflag) +{ + + int fd; + + fd = open(fname, oflag); + arla_log(ADEBMISC, "DARLA_Open: errno=%d\n", errno); + if (fd > 0) + { + Dfp->fd = fd; + Dfp->offset=0; + Dfp->log_entries = 0; + } + + return fd; +} + +int DARLA_Close(DARLA_file *Dfp) +{ + int ret; + + ret = close(Dfp->fd); + Dfp->fd = 0; + Dfp->offset =0; + arla_log(ADEBMISC, "DARLA_Close: ret=%d\n", ret); + return ret; +} + +int DARLA_Read(DARLA_file *Dfp, char *cp, int len) +{ + ssize_t read_size; + + if (Dfp->fd) + { + read_size = read (Dfp->fd, cp, len); + } + else + read_size = 0; + + return read_size; +} + +int DARLA_Write(DARLA_file *Dfp, char *cp, int len) +{ + ssize_t write_size; + + if (Dfp->fd) + { + write_size = write(Dfp->fd, cp, len); + } + else + write_size = 0; + + return write_size; +} + +int DARLA_Seek(DARLA_file *Dfp, int offset, int whence) +{ + + off_t lseek_off; + + if (Dfp->fd) + { + lseek_off = lseek(Dfp->fd, offset, whence); + } + else + lseek_off = 0; + + return lseek_off; +} diff --git a/usr.sbin/afs/src/arlad/darla.h b/usr.sbin/afs/src/arlad/darla.h new file mode 100644 index 00000000000..80853a8c174 --- /dev/null +++ b/usr.sbin/afs/src/arlad/darla.h @@ -0,0 +1,51 @@ +/* $OpenBSD: darla.h,v 1.1 1999/04/30 01:59:07 art Exp $ */ +/* COPYRIGHT (C) 1998 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS + * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS + * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF + * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY + * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE + * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE + * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE + * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY + * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST + * ALSO BE INCLUDED. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +/* $KTH: darla.h,v 1.3 1998/12/21 21:54:03 assar Exp $ */ + +#ifndef _DARLA_H +#define _DARLA_H + +#include <lock.h> + +typedef struct _DARLA_file { + int fd; /*file descriptor of the current file */ + long offset; /*current byte offset */ + struct Lock bs_lock; /*lock to synchronize access */ + long log_entries; /*number of entries */ +} DARLA_file; + +int DARLA_Open(DARLA_file *Dfp, char *fname, int oflag); +int DARLA_Close(DARLA_file *Dfp); +int DARLA_Read(DARLA_file *Dfp, char *cp, int len); +int DARLA_Write(DARLA_file *Dfp, char *cp, int len); +int DARLA_Seek(DARLA_file *Dfp, int offset, int whence); + +#endif /* _DARLA_H */ diff --git a/usr.sbin/afs/src/arlad/discon.h b/usr.sbin/afs/src/arlad/discon.h new file mode 100644 index 00000000000..0d87b28474e --- /dev/null +++ b/usr.sbin/afs/src/arlad/discon.h @@ -0,0 +1,339 @@ +/* $OpenBSD: discon.h,v 1.1 1999/04/30 01:59:07 art Exp $ */ +/* COPYRIGHT (C) 1998 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS + * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS + * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF + * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY + * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE + * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE + * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE + * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY + * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST + * ALSO BE INCLUDED. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +/* +** These are defines for the different type of disconnected +** operations stored in the log. +*/ + +#ifndef _DISCONNH +#define _DISCONNH + + +/* these are define for integrity checking */ +#define CHECK_SLOTS (long) 0x1 +#define CHECK_LRUQ (long) 0x2 +#define CHECK_FREEVS (long) 0x4 + +/* values for the dflags in the vcache */ +#define VC_DIRTY 0x01 +#define KEEP_VC 0x04 +#define DBAD_VC 0x08 /* This is a know bad vcache */ +/* this flags is used by GetVSlot to mark when a vcache was read from +** the disk. +*/ +#define READ_DISK 0x10 + +/* Flags for dflags in the fcache */ +#define KEEP_DC 0x01 + +/* Flags in the afs_VindexFlags */ + +#define VC_FREE 0x01 +#define HAS_CCORE 0x02 +/* 0x04 is used by KEEP_VC */ +#define VC_DATAMOD 0x08 +#define VC_FLAG 0x10 +#define VC_CLEARAXS 0x20 +#define VC_HAVECB 0x40 + +/* magic number for data files */ + +#define AFS_DHMAGIC 0x7635fac1 + +/* these are the file name extensions for various errors */ +#define STORE_EXT ".store" +#define RENAME_EXT ".ren" +#define CREATE_EXT ".creat" +#define MKDIR_EXT ".mkdir" +#define LINK_EXT ".link" +#define SYMLINK_EXT ".slink" +#define ORPH_EXT ".orph" + +/* conflicting defs with arla_local.h */ +/*enum discon_modes { + CONNECTED, + DISCONNECTED, + FETCH_ONLY, + PARTIALLY_CONNECTED +};*/ + +#define IS_DISCONNECTED(state) (state == DISCONNECTED) +#define IS_FETCHONLY(state) (state == FETCH_ONLY) +#define IS_PARTIAL(state) (state == PARTIALLY_CONNECTED) +#define IS_CONNECTED(state) (state == CONNECTED) +#define LOG_OPERATIONS(state) ((state == DISCONNECTED) || \ + (state == FETCH_ONLY) || (state == PARTIALLY_CONNECTED)) +#define USE_OPTIMISTIC(state) ((state == DISCONNECTED) || \ + (state == FETCH_ONLY)) + + +/* These are the different levels of error logging */ +#define DISCON_ERR 0 +#define DISCON_NOTICE 1 +#define DISCON_INFO 2 +#define DISCON_DEBUG 3 + +/* pioctl flags */ +#define AFS_DIS_RECON 0 /* normal reconnect */ +#define AFS_DIS_DISCON 1 /* disconnect */ +#define AFS_DIS_PANIC 2 /* die, monster devil, die */ +#define AFS_DIS_RECONTOSS 3 /* reconnect now! */ +#define AFS_DIS_QUERY 4 /* query disconnected state */ +#define AFS_DIS_FETCHONLY 5 /* disconnect, fetch-only mode */ +#define AFS_DIS_PARTIAL 6 /* partially connected mode */ +#define AFS_DIS_DISCONTOSS 7 /* disconnect without discarding callbacks */ + + +/* these are items defined to fhe PSetDOps */ + +typedef enum { GET_BACKUP_LOG_NAME, + SET_USERLOG_LEVEL, + SET_FILELOG_LEVEL, + SET_LOGFILE, + UPDATE_FLAGS, + PING_SERVER, + GET_LOG_NAME, + GIVEUP_CBS, + PRINT_INFO, + VERIFY_VCACHE, + VERIFY_DCACHE } dis_setopt_op_t; + +#if 0 +#define MAX_NAME 255 +#endif + +typedef struct dis_setop_info { + dis_setopt_op_t op; + char data[MAX_NAME]; +} dis_setop_info_t; + + +#ifdef KERNEL + + +#define CELL_DIRTY 0x01 +#define REALLY_BIG 1024 + +struct save_cell { + long cell; /* unique id assigned by venus */ + char cellName[MAX_NAME]; /* char string name of cell */ + short cellHosts[MAXHOSTS]; /* volume *location* hosts for this cell */ + short lcell; /* Associated linked cell */ + short states; /* state flags */ + long fsport; /* file server port */ + long vlport; /* volume server port */ + short cellIndex; /* relative index number per cell */ + short dindex; /* disconnected index */ +}; + +#define SERV_DIRTY 0x01 + +struct save_server { + unsigned int cell; /* cell in which this host resides */ + long host; /* in network byte order, except subsys */ + long portal; /* in network byte order */ + unsigned int random; /* server priority, used for randomizing requests */ + char isDown; /* result of decision if server is down. */ + char vcbCount; /* count of vcbs */ + short dindex; /* disconnected index */ +}; + + +#define VOL_DIRTY 0x01 + +struct save_volume { + long cell; /* the cell in which the volume resides */ + long volume; /* This volume's ID number. */ + char name[MAX_NAME]; /* This volume's name, or 0 if unknown */ + short serverHost[MAXHOSTS]; /* servers serving this volume */ + struct VenusFid dotdot; /* dir to access as .. */ + struct VenusFid mtpoint; /* The mount point for this volume. */ + long rootVnode, rootUnique; /* Volume's root fid */ + long roVol; + long backVol; + long rwVol; /* For r/o vols, original read/write volume. */ + long accessTime; /* last time we used it */ + long copyDate; /* copyDate field, for tracking vol releases */ + char states; /* snuck here for alignment reasons */ + short dindex; +}; + + +#define LLIST_SIZE 1024 + + +#ifndef GET_WRITE +#define GET_WRITE 0x1 +#define GET_READ 0x2 +#define GET_SHARED 0x4 + +#define REL_WRITE 0x10 +#define REL_READ 0x20 +#define REL_SHARED 0x40 + +#define S_TO_W 0x100 +#define W_TO_S 0x200 +#define W_TO_R 0x400 +#define S_TO_R 0x800 +#endif /* GET_WRITE */ + +struct llist { + struct afs_lock *lk; + short operation; + short who; + struct llist * next; + struct llist *prev; +}; + +/* These are definition for the translation flags fields */ + +#define KNOWNBAD 0x20 +#define SYMLINK 0x40 +struct name_trans { + struct VenusFid pfid; + int ntrans_idx; + int oname_idx; + int nname_idx; + int next_nt_idx; + char *old_name; + char *new_name; + struct name_trans *next; +}; + +struct translations { + struct VenusFid oldfid; + struct VenusFid newfid; + u_long flags; + hyper validDV; + int trans_idx; + long callback; + long cbExpires; + int nl_idx; + struct translations *next; + struct name_trans *name_list; +}; + + + +/* + * this struct is used to help speed up finding the number of callbacks for + * each server + */ + +struct serv_cbcount { + long server; + long count; + struct serv_cbcount *next; +}; + +/* Stuff for the link name persistence */ + +#define MAP_ENTS 100 +#define NAME_UNIT 255 +#define NAME_DIRTY 0x1 + +/* header for the name backing file */ +typedef struct map_header { + long magic; /* magic number */ + int num_ents; /* number of names stored */ + char flags; /* flags for in core copy */ +} map_header_t; + +/* commented out */ +/* + * this struct holds all the information pertaining to a certain + * backing store used to keep persistance information + */ +/*typedef struct backing_store { + long bs_inode; + struct osi_dev bs_dev; + char *bs_name; + map_header_t *bs_header; + char *bs_map; + struct afs_lock bs_lock; + struct osi_file *tfile; +} backing_store_t;*/ + +#endif /* KERNEL */ + +/* CacheItems file has a header of type struct afs_fheader (keep aligned properly) */ +struct afs_dheader { + long magic; + long firstCSize; + long otherCSize; + long spare; + long current_op; + enum connected_mode mode; +}; + +#ifdef KERNEL + +#define have_shared_lock(lock) \ + ((((lock)->excl_locked==SHARED_LOCK) && \ + ((lock)->proc == osi_curpid())) ? 1 : 0) + +#define have_write_lock(lock) \ + ((((lock)->excl_locked==WRITE_LOCK) && \ + ((lock)->proc == osi_curpid())) ? 1 : 0) + +extern struct llist *llist; +extern struct llist *cur_llist; + +/* these are function declarations so I can compile with -Wall in gcc, + * not really needed, but help make clean compiles. + */ + +extern int strlen(); +#ifndef AFS_NETBSD_ENV +extern void strcpy(); +#endif /* AFS_NETBSD_ENV */ +extern void bcopy(); +extern int dir_Delete(); +extern int dir_FindBlobs(); +extern int dir_Lookup(); +extern int dir_Create(); +extern int find_file_name(); +extern int afs_create(); +extern int afs_PutDCache(); + +#endif /* KERNEL */ + +#endif /* _DISCONNH */ + + +#ifdef DISCONN +typedef struct _fid_cb { +VenusFid fid; +struct _fid_cb *next; +} fid_cb; +#endif + + diff --git a/usr.sbin/afs/src/arlad/discon_log.c b/usr.sbin/afs/src/arlad/discon_log.c new file mode 100644 index 00000000000..b895067a6d4 --- /dev/null +++ b/usr.sbin/afs/src/arlad/discon_log.c @@ -0,0 +1,480 @@ +/* $OpenBSD: discon_log.c,v 1.1 1999/04/30 01:59:07 art Exp $ */ +/* COPYRIGHT (C) 1998 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS + * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS + * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF + * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY + * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE + * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE + * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE + * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY + * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST + * ALSO BE INCLUDED. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +/* + * This file contains functions that relate to performance statistics + * for disconnected operation. + */ + +#include "arla_local.h" + +RCSID("$KTH: discon_log.c,v 1.8 1998/12/21 21:54:03 assar Exp $"); + +extern int dlog_mod; +extern long current_op_no; + +extern DARLA_file log_data; + +extern long Log_is_open; + +log_ent_t log_head; + +int DARLA_Open(DARLA_file *Dfp, char *fname, int oflag); +int DARLA_Read(DARLA_file *Dfp, char *cp, int len); +int DARLA_Write(DARLA_file *Dfp, char *cp, int len); +int DARLA_Seek(DARLA_file *Dfp, int offset, int whence); + +/* + * read an entry from the log file described by tfile. The result is + * put into the log_ent data. This return 0 if successful, 1 if + * it failed to some reason ( ie. no more data ). + */ + +int +read_log_ent(DARLA_file * tfile, log_ent_t *in_log) +{ + int len; + char *bp; + + if (DARLA_Read(tfile, (char *) in_log, sizeof (int)) != sizeof(int)) + return 1; + + len = in_log->log_len - sizeof(int); + bp = (char *) in_log + sizeof(int); + + if (DARLA_Read(tfile, bp, len) != len) { + printf("read_log_ent: short read \n"); + return 1; + } + return 0; +} + +#if 0 +void +update_log_ent(offset, flags) +long offset; +int flags; +{ + struct DARLA_file *tfile; + log_ent_t *log_ent; + int code; + + tfile = DARLA_UFSOpen(&log_data.bs_dev, log_data.bs_inode); + if (!tfile) + panic("update_log_ent: failed to open log file"); + + DARLA_Seek(tfile, offset); + + log_ent = (log_ent_t *) malloc(sizeof(log_ent_t)); + code = read_log_ent(tfile, log_ent); + + if (code) { + printf("update_log_ent: failed to read log entry at %d \n", + offset); + } else { + + /* set the log flags */ + log_ent->log_flags |= flags; + + /* write the entry back out */ + DARLA_Seek(tfile, offset); + DARLA_Write(tfile, (char *) log_ent, log_ent->log_len); + } + free(log_ent); + DARLA_Close(tfile); +} +#endif + + +/* write the log entries to disk */ +long +write_log_ent(int len, log_ent_t *log) +{ + + long new_num; + static int index=0; + + arla_warnx (ADEBDISCONN,"We are writing a log"); + if (!Log_is_open) { + return -1; + } + + if (log_head.next == 0) { + log_head.next = (log_ent_t *) malloc(sizeof(log_ent_t)); + *log_head.next = *log; + log_head.next->next = 0; + } + else { + log->next = log_head.next; + log_head.next = (log_ent_t *) malloc(sizeof(log_ent_t)); + *log_head.next = *log; + } + + ObtainWriteLock(&log_data.bs_lock); + + new_num = 0; + + log->log_opno = new_num; + gettimeofday(&log->log_time, 0); + + log->log_offset = log_data.offset; + log->log_flags = 0; + log->log_index = index++; + + DARLA_Write(&log_data, (char *) log, len); + + ReleaseWriteLock(&log_data.bs_lock); + + return (new_num); +} + +long +log_dis_store(struct vcache *avc) +{ + log_ent_t *store; + long op_no; + + store = (log_ent_t *) malloc(sizeof(log_ent_t)); + + store->log_op = DIS_STORE; + store->st_fid = avc->fid; + store->st_origdv = avc->DataVersion; + store->st_flag = avc->flag; + + /* have to log cred as well */ + store->cred = avc->cred; + + /* figure out the length of a store entry */ + store->log_len = ((char *) &(store->st_origdv)) - ((char *) store) + + sizeof(store->st_origdv); + + op_no = write_log_ent(store->log_len, store); + + free(store); + return op_no; +} + + +/* Log a mkdir operation */ +long +log_dis_mkdir(struct vcache *pvc, struct vcache *dvc, + AFSStoreStatus *attrs, char *name) +{ + log_ent_t *mkdir; + long op_no; + + mkdir = (log_ent_t *) malloc(sizeof(log_ent_t)); + + mkdir->log_op = DIS_MKDIR; + mkdir->md_dirfid = dvc->fid; + /*Ba Wu: the data vers. for child dir*/ + mkdir->md_dversion = dvc->DataVersion; + mkdir->md_parentfid = pvc->fid; + mkdir->cred = pvc->cred; + mkdir->md_vattr = *attrs; + + /* save the name */ + strcpy((char *) mkdir->md_name, name); + + /* calculate the length of this record */ + mkdir->log_len = ((char *) mkdir->md_name - (char *) mkdir) + + strlen(name) + 1; + + op_no = write_log_ent(mkdir->log_len, mkdir); + + free(mkdir); + return op_no; +} + + +long +log_dis_create(struct vcache *parent, struct vcache *child, char *name) +{ + log_ent_t *create; + long op_no; + struct vcache *ch; + struct vcache *par; + + ch = child; + par = parent; + ch->DataVersion = child->DataVersion; + + create = (log_ent_t *) malloc(sizeof(log_ent_t)); + + create->log_op = DIS_CREATE; + create->cr_filefid = ch->fid; + create->cr_parentfid = par->fid; + create->cr_origdv = ch->DataVersion; + create->cred = parent->cred; + + strcpy((char *) create->cr_name, name); + + create->log_len = ((char *) create->cr_name - (char *) create) + + strlen(name) + 1; + + op_no = write_log_ent(create->log_len, create); + + free(create); + return op_no; +} + +long +log_dis_remove(struct vcache *avc, FCacheEntry *childentry, char *name) +{ + log_ent_t *remove; + long op_no; + remove = (log_ent_t *) malloc(sizeof(log_ent_t)); + + remove->log_op = DIS_REMOVE; + remove->cred = avc->cred; + remove->rm_filefid = avc->fid; + remove->rm_origdv = avc->DataVersion; + remove->rm_chentry = childentry; + + strcpy((char *) remove->rm_name, name); + + remove->log_len = ((char *) remove->rm_name - (char *) remove) + + strlen(name) + 1; + + op_no = write_log_ent(remove->log_len, remove); + + free(remove); + arla_log(ADEBDISCONN, "remove: fid.Cell=%ld, fid.fid.Volume=%ld, " + "fid.Unique=%ld", \ + remove->rm_filefid.Cell, + remove->rm_filefid.fid.Volume, + remove->rm_filefid.fid.Unique); + + return op_no; +} + + +long +log_dis_rmdir(struct vcache *dir, FCacheEntry *cce, const char *name) +{ + log_ent_t *rmdir; + long op_no; + + rmdir = malloc(sizeof(log_ent_t)); + + rmdir->log_op = DIS_RMDIR; + rmdir->cred = dir->cred; + rmdir->rd_parentfid = dir->fid; + rmdir->rd_direntry = cce; + + strcpy((char *) rmdir->rd_name, name); + + rmdir->log_len = ((char *) rmdir->rd_name - (char *) rmdir) + + strlen(name) + 1; + + op_no = write_log_ent(rmdir->log_len, rmdir); + + free(rmdir); + return op_no; +} + + +long +log_dis_rename(struct vcache *old_dir, char *old_name, + struct vcache *new_dir, char *new_name) +{ + log_ent_t *rename; + char *cp; + + rename = malloc(sizeof(log_ent_t)); + + rename->log_op = DIS_RENAME; + rename->rn_oparentfid = old_dir->fid; + rename->rn_nparentfid = new_dir->fid; + rename->rn_origdv = old_dir->DataVersion; + rename->rn_overdv = new_dir->DataVersion; + rename->cred = old_dir->cred; + + strcpy((char *) rename->rn_names, old_name); + cp = (char *) rename->rn_names + strlen(old_name) + 1; + + strcpy((char *) cp, new_name); + cp += strlen(new_name) + 1; + + rename->log_len = (char *) cp - (char *) rename; + + write_log_ent(rename->log_len, rename); + + free(rename); + return 0; +} + + + +/* Log a link operation */ +long +log_dis_link(struct vcache *pvc, struct vcache *lvc, char *name) + +{ + log_ent_t *link; + long op_no; + + link = malloc(sizeof(log_ent_t)); + + link->log_op = DIS_LINK; + link->cred = pvc->cred; + link->ln_linkfid = lvc->fid; + link->ln_parentfid = pvc->fid; + + /* save the name */ + strcpy((char *) link->ln_name, name); + /* calculate the length of this record */ + link->log_len = ((char *) link->ln_name - (char *) link) + + strlen(name) + 1; + + op_no = write_log_ent(link->log_len, link); + + free(link); + return op_no; +} + +/* Log a symlink operation */ +long +log_dis_symlink(struct vcache *pvc, struct vcache *cvc, + AFSStoreStatus *attr, char *linkname, char *content) +{ + log_ent_t *slink; + long op_no; + + slink = malloc(sizeof(log_ent_t)); + + slink->log_op = DIS_SYMLINK; + slink->sy_parentfid = pvc->fid; + slink->sy_filefid = cvc->fid; + slink->sy_attr = *attr; + slink->cred = pvc->cred; + + /* copy in the link name */ + strcpy((char *) slink->sy_name, linkname); + strcpy((char *) slink->sy_content, content); + + /* calculate the length of this record */ + slink->log_len = ( (char *) slink->sy_content - + (char *) slink) + + strlen(content) + 1; + + op_no = write_log_ent(slink->log_len, slink); + + free(slink); + return op_no; +} + + +/* Log a setattr operation */ +long +log_dis_setattr(struct vcache *tvc, struct xfs_attr *attrs) +{ + log_ent_t *setattr; + long op_no; + + setattr = (log_ent_t *) malloc(sizeof(log_ent_t)); + + setattr->log_op = DIS_SETATTR; + setattr->sa_fid = tvc->fid; + setattr->cred = tvc->cred; + setattr->sa_origdv = tvc->DataVersion; + + setattr->sa_vattr = *attrs; + + /* calculate the length of this record */ + setattr->log_len = ((char *) &setattr->sa_origdv - (char *) setattr) + + sizeof(setattr->sa_origdv); + + op_no = write_log_ent(setattr->log_len, setattr); + + arla_log(ADEBDISCONN, "log_dis_setattr: fid.Cell=0x%x, fid.fid.Volume=0x%x," + "fid.fid.Vnode=0x%x, fid.fid.Unique=0x%x", + tvc->fid.Cell, + tvc->fid.fid.Volume, + tvc->fid.fid.Vnode, + tvc->fid.fid.Unique); + + arla_log(ADEBDISCONN, "log_dis_setattr: writing %d byte log entry."); + + free(setattr); + return op_no; +} + +long +log_dis_nonmutating(struct vcache *tvc, log_ops_t op) +{ +#ifdef LOGNONMUTE + log_ent_t *non_mute; + long op_no; + + non_mute = (log_ent_t *) malloc(sizeof(log_ent_t)); + + non_mute->log_op = op; + non_mute->cred = tvc->cred; + non_mute->nm_fid = tvc->fid; + non_mute->nm_origdv = tvc->DataVersion; + non_mute->log_len = ((char *) &non_mute->nm_origdv - + (char *) non_mute) + sizeof(non_mute->nm_origdv); + + /* XXX lhuston removed for debugging */ + op_no = write_log_ent(non_mute->log_len, non_mute); + + free(non_mute); + return op_no; +#else + return 0; /* 0 was current_op_no */ +#endif +} + + +long +log_dis_access(struct vcache *tvc) +{ + return log_dis_nonmutating(tvc, DIS_ACCESS); +} + +long +log_dis_readdir(struct vcache *tvc) +{ + return log_dis_nonmutating(tvc, DIS_READDIR); +} + +long +log_dis_readlink(struct vcache *tvc) +{ + return log_dis_nonmutating(tvc, DIS_READLINK); +} + +long +log_dis_fsync(struct vcache *tvc) +{ + /* treat an fsync as a store */ + return log_dis_nonmutating(tvc, DIS_FSYNC); +} diff --git a/usr.sbin/afs/src/arlad/discon_log.h b/usr.sbin/afs/src/arlad/discon_log.h new file mode 100644 index 00000000000..2fdb2a6ef94 --- /dev/null +++ b/usr.sbin/afs/src/arlad/discon_log.h @@ -0,0 +1,268 @@ +/* $OpenBSD: discon_log.h,v 1.1 1999/04/30 01:59:07 art Exp $ */ +/* COPYRIGHT (C) 1998 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS + * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS + * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF + * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY + * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE + * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE + * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE + * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY + * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST + * ALSO BE INCLUDED. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +/* + * This file contains all the relevant information pertaining to logging + * for disconnected afs. + */ +/* replace vattr with xfs_attr in the log */ +#include <xfs/xfs_attr.h> +#ifndef _DISCONN_LOG_H + +#define _DISCONN_LOG_H + +#define BUFSIZE 256 + +#define MAX_NAME AFSNAMEMAX + +enum log_ops { + DIS_STORE, + DIS_MKDIR, + DIS_CREATE, + DIS_REMOVE, + DIS_RMDIR, + DIS_RENAME, + DIS_LINK, + DIS_SYMLINK, + DIS_SETATTR, + DIS_FSYNC, + DIS_ACCESS, + DIS_READDIR, + DIS_READLINK, + DIS_INFO, + DIS_START_OPT, + DIS_END_OPT, + DIS_REPLAYED +}; + +typedef enum log_ops log_ops_t; + +/* These are defines for the different log flags that can be set */ +#define LOG_INACTIVE 0x1 /* log no longer needs replay */ +#define LOG_REPLAYED 0x2 /* log entry was replayed */ +#define LOG_OPTIMIZED 0x4 /* log entry was optimized away */ +#define LOG_GENERATED 0x8 /* log entry created by optimizer */ + + +/* defines to make access easier */ +#define st_fid log_data.st.fid +#define st_origdv log_data.st.origdv + +/* added flag option */ +#define st_flag log_data.st.flag + +typedef u_int32_t hyper; + +/* a really stripped down version of CITI's vcache */ +struct vcache { + u_int32_t DataVersion; + struct VenusFid fid; + xfs_cred cred; + u_int flag; /* write flag */ +}; + +typedef struct store_log_data { + struct VenusFid fid; /* fid of the file */ + u_int flag; /* write flag */ + hyper origdv; /* cached data version of file */ +} store_log_data_t; + +/* defines to make access easier */ +#define md_dirfid log_data.md.dirfid +#define md_parentfid log_data.md.parentfid +#define md_vattr log_data.md.vattr +#define md_dversion log_data.md.dversion +#define md_name log_data.md.name + +typedef struct mkdir_log_data { + struct VenusFid dirfid; /* Fid of this dir */ + struct VenusFid parentfid; /* Fid of parent */ + /* struct vattr vattr; attrs to create with */ + AFSStoreStatus vattr; /* log store_status */ /*Ba Wu */ + hyper dversion; /* cached data version of file */ + char name[MAX_NAME]; /* space to store create name */ +} mkdir_log_data_t; + + +/* defines to make access easier */ +#define cr_filefid log_data.cr.filefid +#define cr_parentfid log_data.cr.parentfid +#define cr_vattr log_data.cr.vattr +#define cr_mode log_data.cr.mode +#define cr_exists log_data.cr.exists +#define cr_excl log_data.cr.excl +#define cr_origdv log_data.cr.origdv +#define cr_name log_data.cr.name + +typedef struct create_log_data { + struct VenusFid filefid; /* Fid of this file */ + struct VenusFid parentfid; /* Fid of parent */ + struct xfs_attr vattr; /* attrs to create with */ + int mode; /* mode to create with */ + int exists; /* did file exists */ + int excl; /* is file create exclusive ? */ + hyper origdv; /* cached data version of file */ + char name[MAX_NAME]; /* space to store create name */ +} create_log_data_t; + + + + +/* defines to make access easier */ +#define rm_filefid log_data.rm.filefid +#define rm_chentry log_data.rm.chentry +#define rm_origdv log_data.rm.origdv +#define rm_name log_data.rm.name + +typedef struct remove_log_data { + struct VenusFid filefid; /* Fid of this file */ + /*struct VenusFid parentfid;*/ /* Fid of parent */ + FCacheEntry *chentry; /*The entry for the deleted file*/ + hyper origdv; /* cached data version of file */ + char name[MAX_NAME]; /* space to store remove name */ +} remove_log_data_t; + + + +/* defines to make access easier */ +#define rd_direntry log_data.rd.direntry +#define rd_parentfid log_data.rd.parentfid +#define rd_name log_data.rd.name + +typedef struct rmdir_log_data { + FCacheEntry *direntry; /*Entry of this dir */ + struct VenusFid parentfid; /* Fid of parent */ + char name[MAX_NAME]; /* space to store dir name */ +} rmdir_log_data_t; + + +/* defines to make access easier */ +#define rn_oparentfid log_data.rn.oparentfid +#define rn_nparentfid log_data.rn.nparentfid +#define rn_renamefid log_data.rn.renamefid +#define rn_overfid log_data.rn.overfid +#define rn_origdv log_data.rn.origdv +#define rn_overdv log_data.rn.overdv +#define rn_names log_data.rn.names + +typedef struct rename_log_data { + struct VenusFid oparentfid; /* Fid of parent */ + struct VenusFid nparentfid; /* Fid of parent */ + struct VenusFid renamefid; /* Fid of file being rename */ + struct VenusFid overfid; /* Fid of overwritten file */ + hyper origdv; /* cached data version of file */ + hyper overdv; /* overwritten version of cached data */ + char names[MAX_NAME * 2]; /* space to store dir name */ +} rename_log_data_t; + +/* defines to make access easier */ +#define ln_linkfid log_data.ln.linkfid +#define ln_parentfid log_data.ln.parentfid +#define ln_name log_data.ln.name + +typedef struct link_log_data { + struct VenusFid linkfid; /* Fid of this dir */ + struct VenusFid parentfid; /* Fid of parent */ + char name[MAX_NAME]; /* space to store create name */ +} link_log_data_t; + +/* defines to make access easier */ +#define sy_linkfid log_data.sy.linkfid +#define sy_parentfid log_data.sy.parentfid +#define sy_filefid log_data.sy.filefid +#define sy_attr log_data.sy.attr +#define sy_name log_data.sy.name +#define sy_content log_data.sy.content + + +typedef struct slink_log_data { + struct VenusFid linkfid; /* Fid of this link */ + struct VenusFid parentfid; /* Fid of parent */ + struct VenusFid filefid; /* Fid of file */ + AFSStoreStatus attr; /* attrs to create with */ + char name[MAX_NAME]; /* space to name */ + char content[MAX_NAME]; /* space to new name */ +} slink_log_data_t; + +/* defines to make access easier */ +#define sa_fid log_data.sa.fid +#define sa_vattr log_data.sa.vattr +#define sa_origdv log_data.sa.origdv + +typedef struct setattr_log_data { + struct VenusFid fid; /* operand fid */ + struct xfs_attr vattr; /* attrs to set */ + hyper origdv; /* cached data version number */ +} setattr_log_data_t; + + +/* defines to make access easier */ +#define nm_fid log_data.nm.fid +#define nm_origdv log_data.nm.origdv + +typedef struct nonmute_log_data { + struct VenusFid fid; /* fid */ + hyper origdv; /* cached data version */ +} nonmute_log_data_t; + + + +typedef struct log_ent { + int log_len; /* len of this entry */ + log_ops_t log_op; /* operation */ + long log_opno; /* operation number */ + struct timeval log_time; /* time operation was logged */ + long log_offset; /* offset into the log file */ + short log_flags; /* offset into the log file */ + uid_t log_uid; /* uid of person performing op */ + xfs_cred cred; /* user credential */ + int log_index; /* index for the log */ + struct log_ent *next; /* point to the next one */ + + union { + store_log_data_t st; + mkdir_log_data_t md; + create_log_data_t cr; + remove_log_data_t rm; + rmdir_log_data_t rd; + rename_log_data_t rn; + link_log_data_t ln; + slink_log_data_t sy; + setattr_log_data_t sa; + nonmute_log_data_t nm; + } log_data; +} log_ent_t; + + +long log_dis_create(struct vcache *parent, struct vcache *child, char *name); + + +#endif /* _DISCONN_LOG_H */ + diff --git a/usr.sbin/afs/src/arlad/fbuf.c b/usr.sbin/afs/src/arlad/fbuf.c index c7994a0417d..405d086de4f 100644 --- a/usr.sbin/afs/src/arlad/fbuf.c +++ b/usr.sbin/afs/src/arlad/fbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fbuf.c,v 1.1.1.1 1998/09/14 21:52:56 art Exp $ */ +/* $OpenBSD: fbuf.c,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -38,17 +38,21 @@ */ #include "arla_local.h" -RCSID("$KTH: fbuf.c,v 1.16 1998/07/29 13:37:29 assar Exp $") ; +RCSID("$KTH: fbuf.c,v 1.22 1998/12/25 20:25:58 assar Exp $") ; #ifdef BROKEN_MMAP #undef HAVE_MMAP #endif -#if defined(HAVE_MMAP) && !defined(MAP_FAILED) +#ifdef HAVE_MMAP + +#if !defined(MAP_FAILED) #define MAP_FAILED ((void *)(-1)) #endif -#ifdef HAVE_MMAP +/* + * Map fbuf_flags in `flags' to mmap dito + */ static int mmap_flags (fbuf_flags flags) @@ -62,6 +66,11 @@ mmap_flags (fbuf_flags flags) return ret; } +/* + * Create a fbuf with (fd, len, flags). + * Returns 0 or error. + */ + static int mmap_create (fbuf *f, int fd, size_t len, fbuf_flags flags) { @@ -83,6 +92,12 @@ mmap_create (fbuf *f, int fd, size_t len, fbuf_flags flags) return 0; } +/* + * Change the size of the underlying file and the fbuf to `new_len' + * bytes. + * Returns 0 or error. + */ + static int mmap_truncate (fbuf *f, size_t new_len) { @@ -103,6 +118,11 @@ mmap_truncate (fbuf *f, size_t new_len) return mmap_create (f, f->fd, new_len, f->flags); } +/* + * End using `f'. + * Returns 0 or error. + */ + static int mmap_end (fbuf *f) { @@ -115,52 +135,66 @@ mmap_end (fbuf *f) return ret; } +/* + * Copy `len' bytes from the rx call `call' to the file `fd'. + * Returns 0 or error + */ + static int mmap_copyrx2fd (struct rx_call *call, int fd, size_t len) { void *buf; int r_len; - int save_errno; + int ret = 0; + if (len == 0) + return 0; + if(ftruncate (fd, len) < 0) return errno; buf = mmap (0, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (buf == (void *) MAP_FAILED) return errno; r_len = rx_Read (call, buf, len); - save_errno = errno; + if (r_len != len) + ret = rx_Error(call); munmap (buf, len); ftruncate (fd, len); - close (fd); - if (r_len != len) { - return save_errno; - } else { - return 0; - } + return ret; } +/* + * Copy `len' bytes from `fd' to `call'. + * Returns 0 or error. + */ + static int mmap_copyfd2rx (int fd, struct rx_call *call, size_t len) { void *buf; int r_write; - int save_errno; + int ret = 0; + + if (len == 0) + return 0; buf = mmap (0, len, PROT_READ, MAP_PRIVATE, fd, 0); if (buf == (void *) MAP_FAILED) return errno; r_write = rx_Write (call, buf, len); - save_errno = errno; - munmap (buf, len); - close (fd); if (r_write != len) - return save_errno; - else - return 0; + ret = rx_Error(call); + munmap (buf, len); + return ret; } #else /* !HAVE_MMAP */ +/* + * Create a fbuf with (fd, len, flags). + * Returns 0 or error. + */ + static int malloc_create (fbuf *f, int fd, size_t len, fbuf_flags flags) { @@ -171,7 +205,8 @@ malloc_create (fbuf *f, int fd, size_t len, fbuf_flags flags) close(fd); return ENOMEM; } - if (read (fd, buf, len) != len) { + if (lseek(fd, 0, SEEK_SET) == -1 || + read (fd, buf, len) != len) { free(buf); close(fd); return errno; @@ -183,6 +218,11 @@ malloc_create (fbuf *f, int fd, size_t len, fbuf_flags flags) return 0; } +/* + * Write out the data of `f' to the file. + * Returns 0 or error. + */ + static int malloc_flush (fbuf *f) { @@ -194,6 +234,11 @@ malloc_flush (fbuf *f) return 0; } +/* + * End using `f'. + * Returns 0 or error. + */ + static int malloc_end (fbuf *f) { @@ -205,6 +250,12 @@ malloc_end (fbuf *f) return ret; } +/* + * Change the size of the underlying file and the fbuf to `new_len' + * bytes. + * Returns 0 or error. + */ + static int malloc_truncate (fbuf *f, size_t new_len) { @@ -237,6 +288,11 @@ fail: return ret; } +/* + * Copy `len' bytes from the rx call `call' to the file `fd'. + * Returns 0 or error + */ + static int malloc_copyrx2fd (struct rx_call *call, int fd, size_t len) { @@ -247,6 +303,9 @@ malloc_copyrx2fd (struct rx_call *call, int fd, size_t len) size_t reallen = len; int ret = 0; + if (len == 0) + return 0; + if (fstat (fd, &statbuf)) { arla_warn (ADEBFBUF, errno, "fstat"); bufsize = 1024; @@ -267,11 +326,15 @@ malloc_copyrx2fd (struct rx_call *call, int fd, size_t len) } if (ftruncate (fd, reallen) < 0) ret = errno; - close (fd); free (buf); return ret; } +/* + * Copy `len' bytes from `fd' to `call'. + * Returns 0 or error. + */ + static int malloc_copyfd2rx (int fd, struct rx_call *call, size_t len) { @@ -281,6 +344,9 @@ malloc_copyfd2rx (int fd, struct rx_call *call, size_t len) u_long nread; int ret = 0; + if (len == 0) + return 0; + if (fstat (fd, &statbuf)) { arla_warn (ADEBFBUF, errno, "fstat"); bufsize = 1024; @@ -299,13 +365,32 @@ malloc_copyfd2rx (int fd, struct rx_call *call, size_t len) } len -= nread; } - close (fd); free (buf); return ret; } #endif /* !HAVE_MMAP */ /* + * Accessor functions. + */ + +size_t +fbuf_len (fbuf *f) +{ + return f->len; +} + +/* + * + */ + +void * +fbuf_buf (fbuf *f) +{ + return f->buf; +} + +/* * Return a pointer to a copy of this file contents. If we have mmap, * we use that, otherwise we have to allocate some memory and read it. */ @@ -364,6 +449,8 @@ copyrx2fd (struct rx_call *call, int fd, size_t len) /* * Copy from a file descriptor to a RX call. + * + * Returns: error number if failed */ int diff --git a/usr.sbin/afs/src/arlad/fbuf.h b/usr.sbin/afs/src/arlad/fbuf.h index 9e20d00dfca..23ca8069995 100644 --- a/usr.sbin/afs/src/arlad/fbuf.h +++ b/usr.sbin/afs/src/arlad/fbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fbuf.h,v 1.1.1.1 1998/09/14 21:52:56 art Exp $ */ +/* $OpenBSD: fbuf.h,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,7 +37,7 @@ * SUCH DAMAGE. */ -/* $KTH: fbuf.h,v 1.5 1998/02/22 08:09:09 assar Exp $ */ +/* $KTH: fbuf.h,v 1.7 1998/11/19 16:18:46 assar Exp $ */ #ifndef _FBUF_H_ #define _FBUF_H_ @@ -56,6 +56,8 @@ typedef struct fbuf fbuf; int fbuf_create (fbuf *fbuf, int fd, size_t len, fbuf_flags flags); int fbuf_truncate (fbuf *fbuf, size_t new_len); int fbuf_end (fbuf *fbuf); +size_t fbuf_len (fbuf *f); +void *fbuf_buf (fbuf *f); int copyrx2fd (struct rx_call *call, int fd, size_t len); int copyfd2rx (int fd, struct rx_call *call, size_t len); diff --git a/usr.sbin/afs/src/arlad/fcache.c b/usr.sbin/afs/src/arlad/fcache.c index 0517c17ef78..c653e55ac8a 100644 --- a/usr.sbin/afs/src/arlad/fcache.c +++ b/usr.sbin/afs/src/arlad/fcache.c @@ -1,6 +1,6 @@ -/* $OpenBSD: fcache.c,v 1.1.1.1 1998/09/14 21:52:56 art Exp $ */ +/* $OpenBSD: fcache.c,v 1.2 1999/04/30 01:59:07 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -43,7 +43,7 @@ */ #include "arla_local.h" -RCSID("$KTH: fcache.c,v 1.114 1998/08/13 21:32:38 assar Exp $") ; +RCSID("$KTH: fcache.c,v 1.189 1999/04/20 20:58:08 map Exp $") ; /* * Local data for this module. @@ -65,10 +65,10 @@ static Hashtab *hashtab; static List *lrulist; /* - * List of entries to be invalidated. + * Heap of entries to be invalidated. */ -static List *invalid_list; +static Heap *invalid_heap; /* low and high-water marks for vnodes and space */ @@ -87,9 +87,7 @@ static u_long usedbytes, usedvnodes; unsigned fprioritylevel; -/* This is just temporary for allocating "inode"-numbers. */ - -static int inode_count; /* XXX */ +static int node_count; /* XXX */ #define FCHASHSIZE 997 @@ -119,6 +117,34 @@ static PROCESS create_nodes_pid; static PROCESS invalidator_pid; /* + * Smalltalk emulation + */ + +u_long +fcache_highbytes(void) +{ + return highbytes; +} + +u_long +fcache_usedbytes(void) +{ + return usedbytes; +} + +u_long +fcache_highvnodes(void) +{ + return highvnodes; +} + +u_long +fcache_usedvnodes(void) +{ + return usedvnodes; +} + +/* * Compare two entries. Return 0 if and only if the same. */ @@ -148,12 +174,150 @@ fcachehash (void *e) } /* + * Compare expiration times. + */ + +static int +expiration_time_cmp (const void *a, const void *b) +{ + const FCacheEntry *f1 = (const FCacheEntry *)a; + const FCacheEntry *f2 = (const FCacheEntry *)b; + + return f1->callback.ExpirationTime - f2->callback.ExpirationTime; +} + +/* * Globalnames */ char arlasysname[SYSNAMEMAXLEN]; /* + * return the file name of the cached file for `entry'. + */ + +int +fcache_file_name (FCacheEntry *entry, char *s, size_t len) +{ + return snprintf (s, len, "%04X", (unsigned)entry->index); +} + +/* + * return the file name of the converted directory for `entry'. + */ + +int +fcache_extra_file_name (FCacheEntry *entry, char *s, size_t len) +{ + int ret; + + assert (entry->flags.datap && + entry->flags.extradirp && + entry->status.FileType == TYPE_DIR); + + ret = fcache_file_name (entry, s, len); + *s += 0x10; + return ret; +} + +static int fhopen_working; + +/* + * open file by handle + */ + +static int +fhopen (xfs_cache_handle *handle, int flags) +{ + struct ViceIoctl vice_ioctl; + + vice_ioctl.in = (caddr_t)handle; + vice_ioctl.in_size = sizeof(*handle); + + vice_ioctl.out = NULL; + vice_ioctl.out_size = 0; + + return k_pioctl (NULL, VIOC_FHOPEN, &vice_ioctl, flags); +} + +/* + * get the handle of `filename' + */ + +int +fcache_fhget (char *filename, xfs_cache_handle *handle) +{ + struct ViceIoctl vice_ioctl; + + if (!fhopen_working) + return 0; + + vice_ioctl.in = NULL; + vice_ioctl.in_size = 0; + + vice_ioctl.out = (caddr_t)handle; + vice_ioctl.out_size = sizeof(*handle); + + return k_pioctl (filename, VIOC_FHGET, &vice_ioctl, 0); +} + +/* + * create a new cache vnode + */ + +int +fcache_create_file (FCacheEntry *entry) +{ + char fname[MAXPATHLEN]; + int fd; + int ret; + + fcache_file_name (entry, fname, sizeof(fname)); + fd = open (fname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666); + assert (fd >= 0); + ret = close (fd); + assert (ret == 0); + return fcache_fhget (fname, &entry->handle); +} + +/* + * return a fd to the cache file of `entry' + */ + +int +fcache_open_file (FCacheEntry *entry, int flag) +{ + int ret; + char fname[MAXPATHLEN]; + + if (fhopen_working) { + ret = fhopen (&entry->handle, flag); + if (ret < 0 && errno == EINVAL) + fhopen_working = 0; + else + return ret; + } + fcache_file_name (entry, fname, sizeof(fname)); + return open (fname, flag | O_BINARY); +} + +/* + * return a fd to the converted directory for `entry' + */ + +int +fcache_open_extra_dir (FCacheEntry *entry, int flag, mode_t mode) +{ + char fname[MAXPATHLEN]; + + assert (entry->flags.datap && entry->flags.extradirp && + entry->status.FileType == TYPE_DIR); + + fcache_extra_file_name (entry, fname, sizeof(fname)); + return open (fname, flag | O_BINARY, mode); +} + +/* * Create `n' new entries */ @@ -168,11 +332,11 @@ create_new_entries (unsigned n) arla_errx (1, ADEBERROR, "fcache: calloc failed"); for (i = 0; i < n; ++i) { - entries[i].lru_le = listaddhead (lrulist, &entries[i]); - entries[i].invalid_le = NULL; - entries[i].volume = NULL; - entries[i].refcount = 0; - entries[i].anonaccess = 0; + entries[i].lru_le = listaddhead (lrulist, &entries[i]); + entries[i].invalid_ptr = -1; + entries[i].volume = NULL; + entries[i].refcount = 0; + entries[i].anonaccess = 0; for (j = 0; j < NACCESS; j++) { entries[i].acccache[j].cred = ARLA_NO_AUTH_CRED; entries[i].acccache[j].access = 0; @@ -190,16 +354,34 @@ static void throw_data (FCacheEntry *entry) { int fd; + struct stat sb; + int ret; assert (entry->flags.datap && entry->flags.usedp && CheckLock(&entry->lock) == -1); - fd = fcache_open_file (entry, O_WRONLY | O_TRUNC, 0); + fd = fcache_open_file (entry, O_WRONLY); if (fd < 0) { arla_warn (ADEBFCACHE, errno, "fcache_open_file"); return; } - close (fd); + if (fstat (fd, &sb) < 0) { + arla_warn (ADEBFCACHE, errno, "fstat"); + ret = close (fd); + assert (ret == 0); + return; + } + if (entry->status.FileType != TYPE_DIR) { + assert (sb.st_size == entry->status.Length); + } + if (ftruncate (fd, 0) < 0) { + arla_warn (ADEBFCACHE, errno, "ftruncate"); + ret = close (fd); + assert (ret == 0); + return; + } + ret = close (fd); + assert (ret == 0); if (entry->flags.extradirp) { char fname[MAXPATHLEN]; @@ -207,12 +389,24 @@ throw_data (FCacheEntry *entry) unlink (fname); } assert(usedbytes >= entry->status.Length); - usedbytes -= entry->status.Length; + usedbytes -= sb.st_size; entry->flags.datap = FALSE; entry->flags.extradirp = FALSE; } /* + * A probe function for a file server. + */ + +static int +fs_probe (struct rx_connection *conn) +{ + u_int32_t sec, usec; + + return RXAFS_GetTime (conn, &sec, &usec); +} + +/* * */ @@ -233,9 +427,9 @@ throw_entry (FCacheEntry *entry) if (entry->flags.datap) throw_data (entry); - if (entry->invalid_le != NULL) { - listdel (invalid_list, entry->invalid_le); - entry->invalid_le = NULL; + if (entry->invalid_ptr != -1) { + heap_remove (invalid_heap, entry->invalid_ptr); + entry->invalid_ptr = -1; } if (entry->flags.attrp && entry->host) { @@ -243,16 +437,18 @@ throw_entry (FCacheEntry *entry) assert (ce != NULL); conn = conn_get (entry->fid.Cell, entry->host, afsport, - FS_SERVICE_ID, ce); + FS_SERVICE_ID, fs_probe, ce); cred_free (ce); - - fids.len = cbs.len = 1; - fids.val = &entry->fid.fid; - cbs.val = &entry->callback; - ret = RXAFS_GiveUpCallBacks (conn->connection, &fids, &cbs); - conn_free (conn); - if (ret) - arla_warn (ADEBFCACHE, ret, "RXAFS_GiveUpCallBacks"); + + if (conn != NULL) { + fids.len = cbs.len = 1; + fids.val = &entry->fid.fid; + cbs.val = &entry->callback; + ret = RXAFS_GiveUpCallBacks (conn->connection, &fids, &cbs); + conn_free (conn); + if (ret) + arla_warn (ADEBFCACHE, ret, "RXAFS_GiveUpCallBacks"); + } } volcache_free (entry->volume); entry->volume = NULL; @@ -260,20 +456,33 @@ throw_entry (FCacheEntry *entry) entry->flags.attrp = FALSE; entry->flags.usedp = FALSE; --usedvnodes; + LWP_NoYieldSignal (lrulist); } /* - * Return the next inode-number. + * Return the next cache node number. */ static ino_t -nextinode (void) +next_cache_index (void) { - return inode_count++; + return node_count++; } /* - * + * Allocate a cache file for `e' + */ + +static void +create_node (FCacheEntry *e) +{ + assert (CheckLock (&e->lock) == -1); + e->index = next_cache_index (); + fcache_create_file (e); +} + +/* + * Pre-create cache nodes for all entries in lrulist that doesn't have any. */ static void @@ -281,7 +490,6 @@ create_nodes (char *arg) { Listitem *item; FCacheEntry *entry; - int fd; unsigned count = 0; arla_warnx (ADEBFCACHE, @@ -295,13 +503,11 @@ create_nodes (char *arg) assert (entry->lru_le == item); if (!entry->flags.usedp && CheckLock(&entry->lock) == 0 - && entry->inode == 0) { + && entry->index == 0) { struct timeval tv; ObtainWriteLock (&entry->lock); - entry->inode = nextinode (); - fd = fcache_open_file (entry, O_RDWR | O_CREAT | O_TRUNC, 0666); - close (fd); + create_node (entry); ReleaseWriteLock (&entry->lock); ++count; tv.tv_sec = 0; @@ -390,37 +596,40 @@ cleaner (char *arg) } /* - * + * XXX: will not work if an entry with shorter invalidation time + * than the shortest existing invalidation time is inserted. */ static void invalidator (char *arg) { for (;;) { - Listitem *item, *next; + const void *head; struct timeval tv; - while (listemptyp (invalid_list)) - LWP_WaitProcess (invalid_list); + arla_warnx(ADEBCLEANER, + "running invalidator"); - gettimeofday (&tv, NULL); + while ((head = heap_head (invalid_heap)) == NULL) + LWP_WaitProcess (invalid_heap); - for (item = listhead (invalid_list); - item; - item = next) { - FCacheEntry *entry = (FCacheEntry *)listdata(item); + gettimeofday (&tv, NULL); - assert (entry->invalid_le == item); + while ((head = heap_head (invalid_heap)) != NULL) { + FCacheEntry *entry = (FCacheEntry *)head; - next = listnext (invalid_list, item); if (tv.tv_sec < entry->callback.ExpirationTime) { - IOMGR_Sleep (entry->callback.ExpirationTime - tv.tv_sec); + unsigned long t = entry->callback.ExpirationTime - tv.tv_sec; + + arla_warnx (ADEBCLEANER, + "invalidator: sleeping for %lu second(s)", t); + IOMGR_Sleep (t); break; } - + ObtainWriteLock (&entry->lock); - listdel (invalid_list, item); - entry->invalid_le = NULL; + heap_remove_head (invalid_heap); + entry->invalid_ptr = -1; if (entry->flags.kernelp) break_callback (entry->fid); ReleaseWriteLock (&entry->lock); @@ -435,32 +644,13 @@ invalidator (char *arg) static void add_to_invalidate (FCacheEntry *e) { - Listitem *item; - - if (e->invalid_le != NULL) { - listdel (invalid_list, e->invalid_le); - e->invalid_le = NULL; - } - - for (item = listhead (invalid_list); - item; - item = listnext (invalid_list, item)) { - FCacheEntry *this_entry = (FCacheEntry *)listdata (item); - - if (e->callback.ExpirationTime < this_entry->callback.ExpirationTime) { - e->invalid_le = listaddbefore (invalid_list, - item, - e); - return; - } - } - e->invalid_le = listaddhead (invalid_list, e); - LWP_NoYieldSignal (invalid_list); + heap_insert (invalid_heap, (const void *)e, &e->invalid_ptr); + LWP_NoYieldSignal (invalid_heap); } /* - * Remove the entry least-recently used and return it or NULL if none - * is found. + * Remove the entry least-recently used and return it. Sleep until + * there's an entry. */ static FCacheEntry * @@ -469,59 +659,44 @@ unlink_lru_entry (void) FCacheEntry *entry = NULL; Listitem *item; - assert (!listemptyp (lrulist)); - for (item = listtail (lrulist); - item; - item = listprev (lrulist, item)) { - - entry = (FCacheEntry *)listdata (item); - if (!entry->flags.usedp - && CheckLock(&entry->lock) == 0) { - ObtainWriteLock (&entry->lock); - listdel (lrulist, entry->lru_le); - entry->lru_le = NULL; - return entry; - } - } + for (;;) { - assert (!listemptyp (lrulist)); - for (item = listtail (lrulist); - item; - item = listprev (lrulist, item)) { - - entry = (FCacheEntry *)listdata (item); - if (entry->flags.usedp - && !entry->flags.attrusedp - && entry->refcount == 0 - && CheckLock(&entry->lock) == 0) { - ObtainWriteLock (&entry->lock); - listdel (lrulist, entry->lru_le); - entry->lru_le = NULL; - throw_entry (entry); - return entry; - } - } + assert (!listemptyp (lrulist)); + for (item = listtail (lrulist); + item; + item = listprev (lrulist, item)) { - assert (!listemptyp (lrulist)); - for (item = listtail (lrulist); - item; - item = listprev (lrulist, item)) { - - entry = (FCacheEntry *)listdata (item); - if (entry->flags.usedp - && entry->refcount == 0 - && CheckLock(&entry->lock) == 0) { - ObtainWriteLock (&entry->lock); - listdel (lrulist, entry->lru_le); - entry->lru_le = NULL; - if (entry->flags.kernelp) - break_callback (entry->fid); - throw_entry (entry); - return entry; - } - } + entry = (FCacheEntry *)listdata (item); + if (!entry->flags.usedp + && CheckLock(&entry->lock) == 0) { + ObtainWriteLock (&entry->lock); + listdel (lrulist, entry->lru_le); + entry->lru_le = NULL; + return entry; + } + } + + assert (!listemptyp (lrulist)); + for (item = listtail (lrulist); + item; + item = listprev (lrulist, item)) { + + entry = (FCacheEntry *)listdata (item); + if (entry->flags.usedp + && !entry->flags.attrusedp + && entry->refcount == 0 + && CheckLock(&entry->lock) == 0) { + ObtainWriteLock (&entry->lock); + listdel (lrulist, entry->lru_le); + entry->lru_le = NULL; + throw_entry (entry); + return entry; + } + } - return NULL; + arla_warnx (ADEBFCACHE, "unlink_lru_entry: sleeping"); + LWP_WaitProcess (lrulist); + } } /* @@ -550,21 +725,7 @@ emergency_remove_data (size_t sz) ReleaseWriteLock (&entry->lock); } } - - for (item = listtail (lrulist); - item && usedbytes + sz > highbytes; - item = listprev (lrulist, item)) { - entry = (FCacheEntry *)listdata (item); - if (entry->flags.datap - && entry->priority < prio - && CheckLock(&entry->lock) == 0) { - ObtainWriteLock (&entry->lock); - throw_data (entry); - ReleaseWriteLock (&entry->lock); - } - } } - } /* @@ -609,8 +770,12 @@ fcache_store_state (void) if (!entry->flags.usedp) continue; if (write (fd, entry, sizeof(*entry)) != sizeof(*entry)) { - close (fd); - return errno; + int save_errno = errno; + int ret; + + ret = close (fd); + assert (ret == 0); + return save_errno; } ++n; } @@ -636,6 +801,7 @@ fcache_recover_state (void) FCacheEntry tmp; unsigned n; AFSCallBack broken_callback = {0, 0, CBDROPPED}; + int ret; fd = open ("fcache", O_RDONLY | O_BINARY, 0); if (fd < 0) @@ -646,13 +812,16 @@ fcache_recover_state (void) FCacheEntry *e; int i; VolCacheEntry *vol; + int res; + int32_t type; ce = cred_get (tmp.fid.Cell, 0, 0); assert (ce != NULL); - vol = volcache_getbyid (tmp.fid.fid.Volume, tmp.fid.Cell, ce); + res = volcache_getbyid (tmp.fid.fid.Volume, tmp.fid.Cell, + ce, &vol, &type); cred_free (ce); - if (vol == NULL) + if (res) continue; e = find_free_entry (); @@ -673,8 +842,9 @@ fcache_recover_state (void) } e->anonaccess = tmp.anonaccess; - e->inode = tmp.inode; - inode_count = max(inode_count, tmp.inode + 1); + e->index = tmp.index; + e->handle = tmp.handle; /* XXX */ + node_count = max(node_count, tmp.index + 1); e->flags.usedp = TRUE; e->flags.attrp = tmp.flags.attrp; e->flags.datap = tmp.flags.datap; @@ -682,7 +852,8 @@ fcache_recover_state (void) e->flags.datausedp = FALSE; e->flags.kernelp = FALSE; e->flags.extradirp = tmp.flags.extradirp; - e->flags.mountp = tmp.flags.mountp; + e->flags.mountp = tmp.flags.mountp; + e->flags.sentenced = FALSE; e->tokens = tmp.tokens; e->parent = tmp.parent; e->realfid = tmp.realfid; @@ -694,7 +865,8 @@ fcache_recover_state (void) usedbytes += e->status.Length; ReleaseWriteLock (&e->lock); } - close (fd); + ret = close (fd); + assert (ret == 0); arla_warnx (ADEBFCACHE, "recovered %u entries to fcache", n); } @@ -723,53 +895,103 @@ findaccess (pag_t cred, AccessEntry *ae, AccessEntry **pos) } /* - * Find the file server we should be talking to for a given fid and - * user and return the connection. + * Find the next fileserver for the request in `context'. + * Returns a ConnCacheEntry or NULL. */ -static ConnCacheEntry * -findconn (FCacheEntry *e, CredCacheEntry *ce) +ConnCacheEntry * +find_next_fs (fs_server_context *context, ConnCacheEntry *prev_conn) +{ + if (prev_conn != NULL) + conn_dead (prev_conn); + + if (context->i < context->num_conns) + return context->conns[context->i++]; + else + return NULL; +} + +/* + * Clean up a `fs_server_context' + */ + +void +free_fs_server_context (fs_server_context *context) +{ + int i; + + for (i = 0; i < context->num_conns; ++i) + conn_free (context->conns[i]); +} + +/* + * Find the first file server housing the volume for `e'. + * The context is saved in `context' and can later be sent to find_next_fs. + * Returns a ConnCacheEntry or NULL. + */ + +ConnCacheEntry * +find_first_fs (FCacheEntry *e, + CredCacheEntry *ce, + fs_server_context *context) { - ConnCacheEntry *conn; VolCacheEntry *ve = e->volume; int i; - u_long addr = 0; - int type = -1, bit; + int bit = 0; + int num_clones; + int cell = e->fid.Cell; + int ret; - for (i = RWVOL; i <= BACKVOL; ++i) - if (ve->entry.volumeId[i] == e->fid.fid.Volume) { - type = i; - break; - } + if (connected_mode == DISCONNECTED) { + context->num_conns = 0; + return NULL; + } - switch (type) { - case RWVOL : + ret = volume_make_uptodate (ve, ce); + if (ret) + return NULL; + + + if (ve->entry.volumeId[RWVOL] == e->fid.fid.Volume + && ve->entry.flags & VLF_RWEXISTS) bit = VLSF_RWVOL; - break; - case ROVOL : + + if (ve->entry.volumeId[ROVOL] == e->fid.fid.Volume + && ve->entry.flags & VLF_ROEXISTS) bit = VLSF_ROVOL; - break; - case BACKVOL : - bit = VLSF_BACKVOL; - break; - default : - abort (); - } - for (i = 0; i < MAXNSERVERS; ++i) - if (ve->entry.serverFlags[i] & bit) { - addr = htonl(ve->entry.serverNumber[i]); - break; - } + if (ve->entry.volumeId[BACKVOL] == e->fid.fid.Volume + && ve->entry.flags & VLF_BACKEXISTS) + bit = VLSF_RWVOL; - assert (addr != 0); + assert (bit); - conn = conn_get (e->fid.Cell, addr, afsport, FS_SERVICE_ID, ce); - if (conn == NULL) { - arla_warnx (ADEBFCACHE, "Cannot connect to FS"); - return NULL; + num_clones = 0; + for (i = 0; i < NMAXNSERVERS; ++i) { + u_long addr = htonl(ve->entry.serverNumber[i]); + + if (ve->entry.serverFlags[i] & bit + && addr != 0) { + ConnCacheEntry *conn; + + conn = conn_get (cell, addr, afsport, + FS_SERVICE_ID, fs_probe, ce); + if (conn != NULL) { + conn->rtt = rx_PeerOf(conn->connection)->rtt + + rand() % RTT_FUZZ - RTT_FUZZ / 2; + context->conns[num_clones] = conn; + ++num_clones; + } + } } - return conn; + + qsort (context->conns, num_clones, sizeof(*context->conns), + conn_rtt_cmp); + + context->num_conns = num_clones; + context->i = 0; + + return find_next_fs (context, NULL); } /* @@ -788,7 +1010,9 @@ fcache_init (u_long alowvnodes, * Initialize all variables. */ - inode_count = 1; /* XXX */ + fhopen_working = k_hasafs (); + + node_count = 1; /* XXX */ lowvnodes = alowvnodes; highvnodes = ahighvnodes; lowbytes = alowbytes; @@ -803,9 +1027,9 @@ fcache_init (u_long alowvnodes, if (lrulist == NULL) arla_errx (1, ADEBERROR, "fcache: listnew failed"); - invalid_list = listnew (); - if (invalid_list == NULL) - arla_errx (1, ADEBERROR, "fcache: listnew failed"); + invalid_heap = heap_new (highvnodes, expiration_time_cmp); + if (invalid_heap == NULL) + arla_errx (1, ADEBERROR, "fcache: heap_new failed"); create_new_entries (highvnodes); @@ -861,19 +1085,21 @@ fcache_reinit(u_long alowvnodes, /* * Find the entry for `fid' in the hash table. - * If it's found, move it to the front of the lrulist as well. + * If it's found, move it to the front of `lrulist' as well. */ static FCacheEntry * -find_entry (VenusFid fid) +find_entry_nolock (VenusFid fid) { FCacheEntry key; FCacheEntry *e; + if (hashtab == NULL) + return NULL; + key.fid = fid; e = (FCacheEntry *)hashtabsearch (hashtab, (void *)&key); if (e != NULL) { - ObtainWriteLock (&e->lock); listdel (lrulist, e->lru_le); e->lru_le = listaddhead (lrulist, e); } @@ -881,6 +1107,22 @@ find_entry (VenusFid fid) } /* + * Find the entry and return it locked. + */ + +static FCacheEntry * +find_entry (VenusFid fid) +{ + FCacheEntry *e; + + e = find_entry_nolock (fid); + + if (e != NULL) + ObtainWriteLock (&e->lock); + return e; +} + +/* * Mark `e' as having `callback' and notify the kernel. */ @@ -891,15 +1133,21 @@ stale (FCacheEntry *e, AFSCallBack callback) e->callback.CallBackType == CBDROPPED) return; - assert (CheckLock (&e->lock) == 0); - - ObtainWriteLock (&e->lock); - e->callback = callback; - e->tokens = 0; - if (e->flags.kernelp) - break_callback (e->fid); - e->flags.kernelp = FALSE; - ReleaseWriteLock (&e->lock); + if (CheckLock (&e->lock) != 0) + e->flags.sentenced = TRUE; + else { + ObtainWriteLock (&e->lock); + e->callback = callback; + e->tokens = 0; + if (e->flags.kernelp) + break_callback (e->fid); + e->flags.kernelp = FALSE; + e->flags.attrp = FALSE; + e->flags.datap = FALSE; + e->flags.attrusedp = FALSE; + e->flags.datausedp = FALSE; + ReleaseWriteLock (&e->lock); + } } /* @@ -911,25 +1159,21 @@ fcache_stale_entry (VenusFid fid, AFSCallBack callback) { FCacheEntry *e; - e = find_entry (fid); + e = find_entry_nolock (fid); if (e == NULL) { arla_warnx (ADEBFCACHE, "callback for non-existing file (%d, %u, %u, %u)", fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique); return; } - - ReleaseWriteLock(&e->lock); stale (e, callback); } - typedef struct { pag_t pag; int32_t cell; } fc_purgecred; - /* * If ptr has cred arg, set it invalid */ @@ -948,7 +1192,8 @@ purge_cred (void *ptr, void *arg) if(ae[i].cred == cred->pag) { ae[i].cred = ARLA_NO_AUTH_CRED; ae[i].access = ANONE; - stale(e, e->callback); + if (e->flags.kernelp) + install_attr (e); break; } } @@ -1012,10 +1257,8 @@ purge_host (void *ptr, void *arg) AFSCallBack broken_callback = {0, 0, CBDROPPED}; assert (*host); - if (e->host == *host) { - if (CheckLock (&e->lock) == 0) - stale (e, broken_callback); - } + if (e->host == *host) + stale (e, broken_callback); return FALSE; } @@ -1030,60 +1273,15 @@ fcache_purge_host (u_long host) } /* - * return the file name of the cached file for `entry'. - */ - -int -fcache_file_name (FCacheEntry *entry, char *s, size_t len) -{ - return snprintf (s, len, "%04X", (unsigned)entry->inode); -} - -/* - * return the file name of the converted directory for `entry'. - */ - -int -fcache_extra_file_name (FCacheEntry *entry, char *s, size_t len) -{ - int ret; - - assert (entry->flags.datap && - entry->flags.extradirp && - entry->status.FileType == TYPE_DIR); - - ret = fcache_file_name (entry, s, len); - *s += 0x10; - return ret; -} - -/* - * return a fd to the cache file of `entry' + * Mark `entry' as not being used. Wake up any threads sleeping in + * unlink_lru_entry */ -int -fcache_open_file (FCacheEntry *entry, int flag, mode_t mode) +void +fcache_unused (FCacheEntry *entry) { - char fname[MAXPATHLEN]; - - fcache_file_name (entry, fname, sizeof(fname)); - return open (fname, flag | O_BINARY, mode); -} - -/* - * return a fd to the converted directory for `entry' - */ - -int -fcache_open_extra_dir (FCacheEntry *entry, int flag, mode_t mode) -{ - char fname[MAXPATHLEN]; - - assert (entry->flags.datap && entry->flags.extradirp && - entry->status.FileType == TYPE_DIR); - - fcache_extra_file_name (entry, fname, sizeof(fname)); - return open (fname, flag | O_BINARY, mode); + entry->flags.datausedp = entry->flags.attrusedp = FALSE; + LWP_NoYieldSignal (lrulist); } /* @@ -1101,10 +1299,15 @@ update_entry (FCacheEntry *entry, { struct timeval tv; AccessEntry *ae; + unsigned long bitmask = 0141777; /* REG, DIR, STICKY, USR, GRP, OTH */ + + if (cell_issuid_by_num (entry->volume->cell)) + bitmask |= 0006000; /* SUID, SGID */ gettimeofday (&tv, NULL); entry->status = *status; + entry->status.UnixModeBits &= bitmask; if (callback) { entry->callback = *callback; entry->callback.ExpirationTime += tv.tv_sec; @@ -1123,16 +1326,136 @@ update_entry (FCacheEntry *entry, } /* + * Give up all callbacks. + */ + +int +fcache_giveup_all_callbacks (void) +{ + Listitem *item; + + for (item = listtail(lrulist); + item != NULL; + item = listprev(lrulist, item)) { + FCacheEntry *entry = (FCacheEntry *)listdata(item); + + if (entry->flags.attrp && entry->host != 0) { + CredCacheEntry *ce; + ConnCacheEntry *conn; + AFSCBFids fids; + AFSCBs cbs; + int ret; + + ce = cred_get (entry->fid.Cell, 0, CRED_ANY); + assert (ce != NULL); + + conn = conn_get (entry->fid.Cell, entry->host, afsport, + FS_SERVICE_ID, fs_probe, ce); + cred_free (ce); + + if (conn != NULL) { + fids.len = cbs.len = 1; + fids.val = &entry->fid.fid; + cbs.val = &entry->callback; + + ret = RXAFS_GiveUpCallBacks (conn->connection, &fids, &cbs); + conn_free (conn); + if (ret) + arla_warn (ADEBFCACHE, ret, "RXAFS_GiveUpCallBacks"); + } + } + } + return 0; /* XXX */ +} + +/* + * Obtain new callbacks for all entries in the cache. + */ + +int +fcache_reobtain_callbacks (void) +{ + Listitem *item; + int ret; + + for (item = listtail(lrulist); + item != NULL; + item = listprev(lrulist, item)) { + FCacheEntry *entry = (FCacheEntry *)listdata(item); + + if (entry->flags.usedp && entry->host != 0) { + CredCacheEntry *ce; + ConnCacheEntry *conn; + AFSFetchStatus status; + AFSCallBack callback; + AFSVolSync volsync; + + ce = cred_get (entry->fid.Cell, 0, CRED_ANY); + assert (ce != NULL); + + conn = conn_get (entry->fid.Cell, entry->host, afsport, + FS_SERVICE_ID, fs_probe, ce); + cred_free (ce); + + if (conn != NULL) { + ret = RXAFS_FetchStatus (conn->connection, + &entry->fid.fid, + &status, + &callback, + &volsync); + if (ret) + arla_warn (ADEBFCACHE, ret, "RXAFS_FetchStatus"); + else + update_entry (entry, &status, &callback, &volsync, + rx_HostOf(rx_PeerOf (conn->connection)), + ce->cred); + conn_free (conn); + } + } + } + return 0; /* XXX */ +} + +/* + * Return true iff there's any point in trying the next fs. + */ + +static Bool +try_next_fs (int error) +{ + switch (error) { + case RX_CALL_DEAD : + case ARLA_VSALVAGE : + case ARLA_VNOSERVICE : + case ARLA_VOFFLINE : + case ARLA_VBUSY : + case ARLA_VIO : + return TRUE; + case ARLA_VMOVED : + case ARLA_VNOVOL : + case 0 : + return FALSE; + default : + return FALSE; + } +} + + +/* * Fetch the attributes for the file in `entry' from the file_server, * using the credentials in `ce' and returning the connection in - * `ret_conn' */ + * `ret_conn' + * + * `entry' must be write-locked. + */ static int do_read_attr (FCacheEntry *entry, CredCacheEntry *ce, - ConnCacheEntry **ret_conn) + ConnCacheEntry **ret_conn, + fs_server_context *ret_context) { - int ret; + int ret = RX_CALL_DEAD; ConnCacheEntry *conn; AFSFetchStatus status; AFSCallBack callback; @@ -1140,27 +1463,26 @@ do_read_attr (FCacheEntry *entry, assert (CheckLock(&entry->lock) == -1); - if (connected_mode == DISCONNECTED) { - *ret_conn = NULL; - if (entry->flags.attrp == TRUE) - return 0; - return ENETDOWN; - } - - conn = findconn (entry, ce); + for (conn = find_first_fs (entry, ce, ret_context); + conn != NULL; + conn = find_next_fs (ret_context, conn)) { + ret = RXAFS_FetchStatus (conn->connection, + &entry->fid.fid, + &status, + &callback, + &volsync); - if (conn == NULL) - return ENETDOWN; + if (!try_next_fs (ret)) + break; + } + assert (CheckLock(&entry->lock) == -1); - ret = RXAFS_FetchStatus (conn->connection, - &entry->fid.fid, - &status, - &callback, - &volsync); if (ret) { - if (ret == -1) + if (ret == RX_CALL_DEAD) { + if (connected_mode == DISCONNECTED && entry->flags.attrp) + return 0; ret = ENETDOWN; - conn_free(conn); + } arla_warn (ADEBFCACHE, ret, "fetch-status"); return ret; } @@ -1178,6 +1500,8 @@ do_read_attr (FCacheEntry *entry, entry->tokens |= XFS_ATTR_R; entry->flags.attrp = TRUE; + assert (CheckLock(&entry->lock) == -1); + *ret_conn = conn; return 0; } @@ -1185,6 +1509,7 @@ do_read_attr (FCacheEntry *entry, /* * Read the attributes of `entry' from the file server and store them. + * `e' must be write-locked. */ int @@ -1192,13 +1517,14 @@ read_attr (FCacheEntry *entry, CredCacheEntry *ce) { int ret; ConnCacheEntry *conn; + fs_server_context context; assert (CheckLock(&entry->lock) == -1); - ret = do_read_attr (entry, ce, &conn); + ret = do_read_attr (entry, ce, &conn, &context); + free_fs_server_context (&context); if (ret) return ret; - conn_free (conn); return 0; } @@ -1239,14 +1565,24 @@ read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce) goto out; } + assert (CheckLock(&entry->lock) == -1); + ret = StartRXAFS_FetchData (call, &entry->fid.fid, 0, entry->status.Length); + + assert (CheckLock(&entry->lock) == -1); + if(ret) { arla_warn (ADEBFCACHE, ret, "fetch-data"); goto out; } + assert (CheckLock(&entry->lock) == -1); + ret = rx_Read (call, &sizefs, sizeof(sizefs)); + + assert (CheckLock(&entry->lock) == -1); + if (ret != sizeof(sizefs)) { ret = rx_Error(call); arla_warn (ADEBFCACHE, ret, "Error reading length"); @@ -1257,27 +1593,37 @@ read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce) assert (sizefs == entry->status.Length); - fd = fcache_open_file (entry, O_RDWR | O_CREAT | O_TRUNC, 0666); + assert (CheckLock(&entry->lock) == -1); + + fd = fcache_open_file (entry, O_RDWR); if (fd < 0) { ret = errno; arla_warn (ADEBFCACHE, ret, "open cache file %u", - (unsigned)entry->inode); + (unsigned)entry->index); rx_EndCall(call, 0); goto out; } - if (copyrx2fd (call, fd, sizefs)) { - ret = errno; - rx_EndCall(call, ret); + assert (CheckLock(&entry->lock) == -1); + + ret = copyrx2fd (call, fd, sizefs); + close (fd); + if (ret) { arla_warn (ADEBFCACHE, ret, "copyrx2fd"); + rx_EndCall(call, ret); + goto out; } + assert (CheckLock(&entry->lock) == -1); + usedbytes += sizefs; /* XXX - sync */ ret = rx_EndCall (call, EndRXAFS_FetchData (call, &status, &callback, &volsync)); + assert (CheckLock(&entry->lock) == -1); + if(ret) { arla_warn (ADEBFCACHE, ret, "rx_EndCall"); goto out; @@ -1291,6 +1637,8 @@ read_data (FCacheEntry *entry, ConnCacheEntry *conn, CredCacheEntry *ce) entry->tokens |= XFS_DATA_R | XFS_DATA_W | XFS_OPEN_NR | XFS_OPEN_NW; out: + assert (CheckLock(&entry->lock) == -1); + return ret; } @@ -1299,87 +1647,113 @@ out: */ int -write_data (FCacheEntry *entry, CredCacheEntry *ce) +write_data (FCacheEntry *entry, AFSStoreStatus *storestatus, + CredCacheEntry *ce) { ConnCacheEntry *conn; struct rx_call *call; int ret = 0; + int close_ret; u_int32_t sizefs; int fd; struct stat statinfo; - AFSStoreStatus storestatus; AFSFetchStatus status; AFSCallBack callback; AFSVolSync volsync; + fs_server_context context; assert (CheckLock(&entry->lock) == -1); - conn = findconn (entry, ce); - - if (conn == NULL) - return ENETDOWN; - - fd = fcache_open_file (entry, O_RDONLY, 0666); + fd = fcache_open_file (entry, O_RDONLY); if (fd < 0) { ret = errno; arla_warn (ADEBFCACHE, ret, "open cache file %u", - (unsigned)entry->inode); - goto out; + (unsigned)entry->index); + return ret; } if (fstat (fd, &statinfo) < 0) { - ret = errno; - arla_warn (ADEBFCACHE, ret, "stat cache file %u", - (unsigned)entry->inode); - goto out; + int close_ret; + + ret = errno; + close_ret = close (fd); + assert (close_ret == 0); + arla_warn (ADEBFCACHE, ret, "stat cache file %u", + (unsigned)entry->index); + return ret; } sizefs = statinfo.st_size; - usedbytes = usedbytes - entry->status.Length + sizefs; + fcache_update_length (entry, sizefs); + if (connected_mode != CONNECTED) { + int close_ret; - call = rx_NewCall (conn->connection); - if (call == NULL) { - arla_warnx (ADEBMISC, "rx_NewCall failed"); - ret = ENOMEM; - goto out; + close_ret = close (fd); + assert (close_ret == 0); + return 0; } - storestatus.Mask = 0; /* Dont save anything */ - ret = StartRXAFS_StoreData (call, &entry->fid.fid, - &storestatus, - 0, - sizefs, - sizefs); - if (ret) { - arla_warn (ADEBFCACHE, ret, "store-data"); - rx_EndCall(call, 0); - goto out; - } + for (conn = find_first_fs (entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - if (copyfd2rx (fd, call, sizefs)) { - ret = errno; - rx_EndCall(call, ret); - arla_warnx (ADEBFCACHE, "copyfd2rx"); - goto out; - } + call = rx_NewCall (conn->connection); + if (call == NULL) { + arla_warnx (ADEBMISC, "rx_NewCall failed"); + ret = ENOMEM; + break; + } - ret = rx_EndCall (call, EndRXAFS_StoreData (call, - &status, - &callback, - &volsync)); - if (ret) { - arla_warn (ADEBFCACHE, ret, "rx_EndCall"); - goto out; - } + ret = StartRXAFS_StoreData (call, &entry->fid.fid, + storestatus, + 0, + sizefs, + sizefs); + if (ret == RX_CALL_DEAD) { + rx_EndCall(call, ret); + continue; + } else if (ret) { + arla_warn (ADEBFCACHE, ret, "store-data"); + rx_EndCall(call, 0); + break; + } - update_entry (entry, &status, &callback, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + ret = copyfd2rx (fd, call, sizefs); + if (ret) { + rx_EndCall(call, ret); + arla_warn (ADEBFCACHE, ret, "copyfd2rx"); + break; + } -out: - close (fd); - conn_free (conn); + ret = EndRXAFS_StoreData (call, + &status, + &callback, + &volsync); + if (ret) { + rx_EndCall (call, ret); + arla_warnx (ADEBFCACHE, "EndRXAFS_StoreData"); + break; + } + + ret = rx_EndCall (call, 0); + if (ret) { + arla_warn (ADEBFCACHE, ret, "rx_EndCall"); + } + break; + } + + if (conn != NULL) { + if (ret == 0) + update_entry (entry, &status, &callback, &volsync, + rx_HostOf(rx_PeerOf(conn->connection)), + ce->cred); + } else { + ret = ENETDOWN; + } + free_fs_server_context (&context); + close_ret = close (fd); + assert(close_ret == 0); return ret; } @@ -1394,92 +1768,107 @@ truncate_file (FCacheEntry *entry, off_t size, CredCacheEntry *ce) struct rx_call *call; int ret = 0; AFSStoreStatus storestatus; - u_int32_t sizefs = sizeof(entry->status.Length); + u_int32_t sizefs; int fd; AFSFetchStatus status; AFSCallBack callback; AFSVolSync volsync; + fs_server_context context; + int close_ret; assert (CheckLock(&entry->lock) == -1); - conn = findconn (entry, ce); - - if (conn == NULL) - return ENETDOWN; - - fd = fcache_open_file (entry, O_RDWR | O_CREAT, 0); + fd = fcache_open_file (entry, O_RDWR); if (fd < 0) { ret = errno; arla_warn (ADEBFCACHE, ret, "open fache file %u", - (unsigned)entry->inode); - goto out; + (unsigned)entry->index); + return ret; } if(ftruncate (fd, size) < 0) { ret = errno; arla_warn (ADEBFCACHE, ret, "ftruncate %ld", (long)size); - close (fd); - goto out; + close_ret = close (fd); + assert (close_ret == 0); + return ret; } - close (fd); + close_ret = close (fd); + assert (close_ret == 0); - if (entry->flags.datap) { - assert (usedbytes >= entry->status.Length); - usedbytes -= entry->status.Length; - } - usedbytes += size; + if (!entry->flags.datap) + entry->status.Length = 0; - entry->status.Length = size; + fcache_update_length (entry, size); - call = rx_NewCall (conn->connection); - if (call == NULL) { - arla_warnx (ADEBMISC, "rx_NewCall failed"); - ret = ENOMEM; - goto out; - } + if (connected_mode != CONNECTED) + return 0; - storestatus.Mask = 0; - ret = StartRXAFS_StoreData (call, - &entry->fid.fid, - &storestatus, - 0, 0, entry->status.Length); - if(ret) { - arla_warn (ADEBFCACHE, ret, "store-data"); - rx_EndCall(call, 0); - goto out; - } + for (conn = find_first_fs (entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - sizefs = htonl (sizefs); - if (rx_Write (call, &sizefs, sizeof(sizefs)) != sizeof(sizefs)) { - ret = rx_Error(call); - arla_warn (ADEBFCACHE, ret, "writing length"); - rx_EndCall(call, 0); - goto out; - } + call = rx_NewCall (conn->connection); + if (call == NULL) { + arla_warnx (ADEBMISC, "rx_NewCall failed"); + ret = ENOMEM; + break; + } - if (rx_Write (call, 0, 0) != 0) { - ret = rx_Error(call); - arla_warn (ADEBFCACHE, ret, "writing length"); - rx_EndCall(call, 0); - goto out; - } + storestatus.Mask = 0; + ret = StartRXAFS_StoreData (call, + &entry->fid.fid, + &storestatus, + size, + 0, + size); + if (ret == RX_CALL_DEAD) { + rx_EndCall(call, ret); + continue; + } else if(ret) { + arla_warn (ADEBFCACHE, ret, "store-data"); + rx_EndCall(call, 0); + break; + } - ret = rx_EndCall (call, EndRXAFS_StoreData (call, - &status, - &callback, - &volsync)); - if (ret) { - arla_warn (ADEBFCACHE, ret, "rx_EndCall"); - goto out; + sizefs = htonl (0); + if (rx_Write (call, &sizefs, sizeof(sizefs)) != sizeof(sizefs)) { + ret = rx_Error(call); + arla_warn (ADEBFCACHE, ret, "writing length"); + rx_EndCall(call, 0); + break; + } + + ret = EndRXAFS_StoreData (call, + &status, + &callback, + &volsync); + if (ret) { + rx_EndCall (call, ret); + arla_warnx (ADEBFCACHE, "EndRXAFS_StoreData"); + break; + } + + ret = rx_EndCall (call, 0); + if (ret) { + arla_warn (ADEBFCACHE, ret, "rx_EndCall"); + } + break; } - update_entry (entry, &status, &callback, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + if (conn != NULL) { + if (ret == 0) { + update_entry (entry, &status, &callback, &volsync, + rx_HostOf(rx_PeerOf(conn->connection)), + ce->cred); -out: - conn_free(conn); + assert (entry->status.Length == size); + } + } else { + ret = ENETDOWN; + } + free_fs_server_context (&context); return ret; } @@ -1496,30 +1885,40 @@ write_attr (FCacheEntry *entry, int ret = 0; AFSFetchStatus status; AFSVolSync volsync; + fs_server_context context; + u_int32_t host; assert (CheckLock(&entry->lock) == -1); - conn = findconn (entry, ce); + for (conn = find_first_fs (entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - if (conn == NULL) - return ENETDOWN; + host = rx_HostOf (rx_PeerOf (conn->connection)); - ret = RXAFS_StoreStatus (conn->connection, - &entry->fid.fid, - store_status, - &status, - &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "store-status"); + ret = RXAFS_StoreStatus (conn->connection, + &entry->fid.fid, + store_status, + &status, + &volsync); + if (ret == RX_CALL_DEAD) { + continue; + } else if (ret) { + arla_warn (ADEBFCACHE, ret, "store-status"); + goto out; + } + break; + } + + if (conn == NULL) { + ret = ENETDOWN; goto out; } - - update_entry (entry, &status, NULL, &volsync, - rx_HostOf (rx_PeerOf (conn->connection)), - ce->cred); + + update_entry (entry, &status, NULL, &volsync, host, ce->cred); out: - conn_free (conn); + free_fs_server_context (&context); return ret; } @@ -1534,39 +1933,83 @@ create_file (FCacheEntry *dir_entry, CredCacheEntry *ce) { int ret = 0; - ConnCacheEntry *conn; + int close_ret; AFSFid OutFid; FCacheEntry *child_entry; AFSFetchStatus status; AFSCallBack callback; AFSVolSync volsync; int fd; + fs_server_context context; + u_int32_t host; assert (CheckLock(&dir_entry->lock) == -1); - conn = findconn (dir_entry, ce); + if (connected_mode == CONNECTED) { + ConnCacheEntry *conn; + + for (conn = find_first_fs (dir_entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { + + host = rx_HostOf (rx_PeerOf (conn->connection)); + + ret = RXAFS_CreateFile (conn->connection, + &dir_entry->fid.fid, + name, + store_attr, + &OutFid, + fetch_attr, + &status, + &callback, + &volsync); + if (ret == RX_CALL_DEAD) { + continue; + } else if (ret) { + free_fs_server_context (&context); + arla_warn (ADEBFCACHE, ret, "CreateFile"); + goto out; + } + break; + } + free_fs_server_context (&context); - if (conn == NULL) - return ENETDOWN; + if (conn == NULL) + return ENETDOWN; - ret = RXAFS_CreateFile (conn->connection, - &dir_entry->fid.fid, - name, - store_attr, - &OutFid, - fetch_attr, - &status, - &callback, - &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "CreateFile"); - goto out; + status.Length = dir_entry->status.Length; + update_entry (dir_entry, &status, &callback, &volsync, + host, ce->cred); + } else { + static int fakefid = 100; + + OutFid.Volume = dir_entry->fid.fid.Volume; + OutFid.Vnode = fakefid; + OutFid.Unique = fakefid; + ++fakefid; + + fetch_attr->ClientModTime = store_attr->ClientModTime; + fetch_attr->Owner = store_attr->Owner; + fetch_attr->Group = store_attr->Group; + fetch_attr->UnixModeBits = store_attr->UnixModeBits; + fetch_attr->SegSize = store_attr->SegSize; + fetch_attr->ServerModTime = store_attr->ClientModTime; + fetch_attr->FileType = TYPE_FILE; + fetch_attr->DataVersion = 1; + fetch_attr->InterfaceVersion = 1; + fetch_attr->Author = fetch_attr->Owner; + fetch_attr->LinkCount = 1; + fetch_attr->SyncCount = 0; + fetch_attr->spare1 = 0; + fetch_attr->spare2 = 0; + fetch_attr->spare3 = 0; + fetch_attr->spare4 = 0; + fetch_attr->ParentVnode = dir_entry->fid.fid.Vnode; + fetch_attr->ParentUnique = dir_entry->fid.fid.Unique; + fetch_attr->CallerAccess = dir_entry->status.CallerAccess; + fetch_attr->AnonymousAccess = dir_entry->status.AnonymousAccess; } - update_entry (dir_entry, &status, &callback, &volsync, - rx_HostOf (rx_PeerOf (conn->connection)), - ce->cred); - child_fid->Cell = dir_entry->fid.Cell; child_fid->fid = OutFid; @@ -1577,29 +2020,37 @@ create_file (FCacheEntry *dir_entry, } update_entry (child_entry, fetch_attr, NULL, NULL, - rx_HostOf (rx_PeerOf (conn->connection)), - ce->cred); + host, ce->cred); child_entry->flags.attrp = TRUE; child_entry->flags.kernelp = TRUE; - fd = fcache_open_file (child_entry, O_WRONLY | O_CREAT | O_TRUNC, 0666); + fd = fcache_open_file (child_entry, O_WRONLY); if (fd < 0) { ret = errno; arla_warn (ADEBFCACHE, ret, "open cache file %u", - (unsigned)child_entry->inode); - ReleaseWriteLock (&child_entry->lock); + (unsigned)child_entry->index); + fcache_release(child_entry); goto out; } - close (fd); + if (ftruncate (fd, 0) < 0) { + ret = errno; + arla_warn (ADEBFCACHE, ret, "ftruncate cache file %u", + (unsigned)child_entry->index); + close_ret = close (fd); + assert (close_ret == 0); + fcache_release(child_entry); + goto out; + } + close_ret = close (fd); + assert (close_ret == 0); child_entry->flags.datap = TRUE; child_entry->tokens |= XFS_ATTR_R | XFS_DATA_R | XFS_DATA_W; - ReleaseWriteLock (&child_entry->lock); + fcache_release(child_entry); out: - conn_free (conn); return ret; } @@ -1620,32 +2071,44 @@ create_directory (FCacheEntry *dir_entry, AFSFetchStatus status; AFSCallBack callback; AFSVolSync volsync; + u_int32_t host; + fs_server_context context; assert (CheckLock(&dir_entry->lock) == -1); - conn = findconn (dir_entry, ce); + for (conn = find_first_fs (dir_entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - if (conn == NULL) - return ENETDOWN; + host = rx_HostOf(rx_PeerOf(conn->connection)); - ret = RXAFS_MakeDir (conn->connection, - &dir_entry->fid.fid, - name, - store_attr, - &OutFid, - fetch_attr, - &status, - &callback, - &volsync); + ret = RXAFS_MakeDir (conn->connection, + &dir_entry->fid.fid, + name, + store_attr, + &OutFid, + fetch_attr, + &status, + &callback, + &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "MakeDir"); - goto out; + if (ret == RX_CALL_DEAD) { + continue; + } else if (ret) { + free_fs_server_context (&context); + arla_warn (ADEBFCACHE, ret, "MakeDir"); + goto out; + } + break; } + free_fs_server_context (&context); + + if (conn == NULL) + return ENETDOWN; + status.Length = dir_entry->status.Length; update_entry (dir_entry, &status, &callback, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); child_fid->Cell = dir_entry->fid.Cell; child_fid->fid = OutFid; @@ -1657,8 +2120,7 @@ create_directory (FCacheEntry *dir_entry, } update_entry (child_entry, fetch_attr, NULL, NULL, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); child_entry->flags.attrp = TRUE; child_entry->flags.kernelp = TRUE; @@ -1666,7 +2128,7 @@ create_directory (FCacheEntry *dir_entry, ret = adir_mkdir (child_entry, child_fid->fid, dir_entry->fid.fid); if (ret) { arla_warn (ADEBFCACHE, ret, "adir_mkdir"); - ReleaseWriteLock (&child_entry->lock); + fcache_release(child_entry); goto out; } @@ -1675,10 +2137,9 @@ create_directory (FCacheEntry *dir_entry, child_entry->flags.datap = TRUE; child_entry->tokens |= XFS_ATTR_R | XFS_DATA_R | XFS_DATA_W; - ReleaseWriteLock (&child_entry->lock); + fcache_release(child_entry); out: - conn_free (conn); return ret; } @@ -1699,33 +2160,43 @@ create_symlink (FCacheEntry *dir_entry, FCacheEntry *child_entry; AFSVolSync volsync; AFSFetchStatus new_status; + u_int32_t host; + fs_server_context context; assert (CheckLock(&dir_entry->lock) == -1); - conn = findconn (dir_entry, ce); + for (conn = find_first_fs (dir_entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - if (conn == NULL) - return ENETDOWN; + host = rx_HostOf(rx_PeerOf(conn->connection)); - ret = RXAFS_Symlink (conn->connection, - &dir_entry->fid.fid, - name, - contents, - store_attr, - &OutFid, - fetch_attr, - &new_status, - &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "Symlink"); - goto out; + ret = RXAFS_Symlink (conn->connection, + &dir_entry->fid.fid, + name, + contents, + store_attr, + &OutFid, + fetch_attr, + &new_status, + &volsync); + if (ret == RX_CALL_DEAD) { + continue; + } else if (ret) { + arla_warn (ADEBFCACHE, ret, "Symlink"); + free_fs_server_context (&context); + goto out; + } + break; } + free_fs_server_context (&context); - usedbytes = usedbytes - dir_entry->status.Length + new_status.Length; + if (conn == NULL) + return ENETDOWN; + new_status.Length = dir_entry->status.Length; update_entry (dir_entry, &new_status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); child_fid->Cell = dir_entry->fid.Cell; child_fid->fid = OutFid; @@ -1737,17 +2208,16 @@ create_symlink (FCacheEntry *dir_entry, } update_entry (child_entry, fetch_attr, NULL, NULL, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); + usedbytes += child_entry->status.Length; child_entry->flags.attrp = TRUE; child_entry->flags.kernelp = TRUE; child_entry->tokens |= XFS_ATTR_R; - ReleaseWriteLock (&child_entry->lock); + fcache_release(child_entry); out: - conn_free (conn); return ret; } @@ -1766,38 +2236,47 @@ create_link (FCacheEntry *dir_entry, AFSFetchStatus new_status; AFSFetchStatus status; AFSVolSync volsync; + u_int32_t host; + fs_server_context context; assert (CheckLock(&dir_entry->lock) == -1); - conn = findconn (dir_entry, ce); + for (conn = find_first_fs (dir_entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - if (conn == NULL) - return ENETDOWN; + host = rx_HostOf(rx_PeerOf(conn->connection)); - ret = RXAFS_Link (conn->connection, - &dir_entry->fid.fid, - name, - &existing_entry->fid.fid, - &new_status, - &status, - &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "Link"); - goto out; + ret = RXAFS_Link (conn->connection, + &dir_entry->fid.fid, + name, + &existing_entry->fid.fid, + &new_status, + &status, + &volsync); + if (ret == RX_CALL_DEAD) { + continue; + } else if (ret) { + free_fs_server_context (&context); + arla_warn (ADEBFCACHE, ret, "Link"); + goto out; + } + break; } + free_fs_server_context (&context); + + if (conn == NULL) + return ENETDOWN; - usedbytes = usedbytes - dir_entry->status.Length + status.Length; + status.Length = dir_entry->status.Length; update_entry (dir_entry, &status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); update_entry (existing_entry, &new_status, NULL, NULL, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); out: - conn_free (conn); return ret; } @@ -1812,37 +2291,47 @@ remove_file (FCacheEntry *dir_entry, const char *name, CredCacheEntry *ce) ConnCacheEntry *conn; AFSFetchStatus status; AFSVolSync volsync; + u_int32_t host; + fs_server_context context; assert (CheckLock(&dir_entry->lock) == -1); - conn = findconn (dir_entry, ce); + for (conn = find_first_fs (dir_entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - if (conn == NULL) - return ENETDOWN; + host = rx_HostOf(rx_PeerOf(conn->connection)); - ret = RXAFS_RemoveFile (conn->connection, - &dir_entry->fid.fid, - name, - &status, - &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "RemoveFile"); - goto out; + ret = RXAFS_RemoveFile (conn->connection, + &dir_entry->fid.fid, + name, + &status, + &volsync); + if (ret == RX_CALL_DEAD) { + continue; + } else if (ret) { + free_fs_server_context (&context); + arla_warn (ADEBFCACHE, ret, "RemoveFile"); + goto out; + } + break; } + free_fs_server_context (&context); - usedbytes = usedbytes - dir_entry->status.Length + status.Length; + if (conn == NULL) + return ENETDOWN; + + status.Length = dir_entry->status.Length; update_entry (dir_entry, &status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); out: - conn_free (conn); return ret; } /* - * Remove a file from a directory. + * Remove a directory from a directory. */ int @@ -1854,32 +2343,42 @@ remove_directory (FCacheEntry *dir_entry, ConnCacheEntry *conn; AFSFetchStatus status; AFSVolSync volsync; + u_int32_t host; + fs_server_context context; assert (CheckLock(&dir_entry->lock) == -1); - conn = findconn (dir_entry, ce); + for (conn = find_first_fs (dir_entry, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - if (conn == NULL) - return ENETDOWN; + host = rx_HostOf(rx_PeerOf(conn->connection)); - ret = RXAFS_RemoveDir (conn->connection, - &dir_entry->fid.fid, - name, - &status, - &volsync); - if (ret) { - arla_warn (ADEBFCACHE, ret, "RemoveDir"); - goto out; + ret = RXAFS_RemoveDir (conn->connection, + &dir_entry->fid.fid, + name, + &status, + &volsync); + if (ret == RX_CALL_DEAD) { + continue; + } else if (ret) { + free_fs_server_context (&context); + arla_warn (ADEBFCACHE, ret, "RemoveDir"); + goto out; + } + break; } + free_fs_server_context (&context); + + if (conn == NULL) + return ENETDOWN; - usedbytes = usedbytes - dir_entry->status.Length + status.Length; + status.Length = dir_entry->status.Length; update_entry (dir_entry, &status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); out: - conn_free (conn); return ret; } @@ -1898,43 +2397,50 @@ rename_file (FCacheEntry *old_dir, ConnCacheEntry *conn; AFSFetchStatus orig_status, new_status; AFSVolSync volsync; + u_int32_t host; + fs_server_context context; assert (CheckLock(&old_dir->lock) == -1 && CheckLock(&new_dir->lock) == -1); - conn = findconn (old_dir, ce); + for (conn = find_first_fs (old_dir, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { - if (conn == NULL) - return ENETDOWN; - - ret = RXAFS_Rename (conn->connection, - &old_dir->fid.fid, - old_name, - &new_dir->fid.fid, - new_name, - &orig_status, - &new_status, - &volsync); + host = rx_HostOf(rx_PeerOf(conn->connection)); - if (ret) { - arla_warn (ADEBFCACHE, ret, "Rename"); - goto out; + ret = RXAFS_Rename (conn->connection, + &old_dir->fid.fid, + old_name, + &new_dir->fid.fid, + new_name, + &orig_status, + &new_status, + &volsync); + if (ret == RX_CALL_DEAD) { + continue; + } else if (ret) { + free_fs_server_context (&context); + arla_warn (ADEBFCACHE, ret, "Rename"); + goto out; + } + break; } + free_fs_server_context (&context); - usedbytes = usedbytes - old_dir->status.Length + orig_status.Length; + if (conn == NULL) + return ENETDOWN; - usedbytes = usedbytes - new_dir->status.Length + new_status.Length; + orig_status.Length = old_dir->status.Length; + new_status.Length = new_dir->status.Length; update_entry (old_dir, &orig_status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); update_entry (new_dir, &new_status, NULL, &volsync, - rx_HostOf(rx_PeerOf(conn->connection)), - ce->cred); + host, ce->cred); out: - conn_free (conn); return ret; } @@ -1948,11 +2454,13 @@ getroot (VenusFid *res, CredCacheEntry *ce) VolCacheEntry *ve; VenusFid fid; const char *root_volume = volcache_get_rootvolume (); + int32_t type; + int ret; - ve = volcache_getbyname (root_volume, 0, ce); - if (ve == NULL) { + ret = volcache_getbyname (root_volume, 0, ce, &ve, &type); + if (ret) { arla_warnx (ADEBFCACHE, "Cannot find the root volume"); - return ENODEV; + return ret; } fid.Cell = 0; @@ -2013,29 +2521,34 @@ fcache_find (FCacheEntry **res, VenusFid fid) int fcache_get (FCacheEntry **res, VenusFid fid, CredCacheEntry *ce) { + FCacheEntry *old; FCacheEntry *e; - VolCacheEntry *vol; + int32_t type; + int error; - e = find_entry (fid); - if (e) { - assert (e->flags.usedp); - *res = e; + old = find_entry (fid); + if (old) { + assert (old->flags.usedp); + *res = old; return 0; } - if (connected_mode == DISCONNECTED) { - *res = NULL; - return ENETDOWN; - } + e = find_free_entry (); + assert (e != NULL); - vol = volcache_getbyid (fid.fid.Volume, fid.Cell, ce); - if (vol == NULL) - return ENODEV; + old = find_entry (fid); + if (old) { + e->lru_le = listaddtail (lrulist, e); - e = find_free_entry (); - e->fid = fid; - if (e->inode == 0) - e->inode = nextinode (); + assert (old->flags.usedp); + *res = old; + return 0; + } + + e->fid = fid; + e->realfid = fid; + if (e->index == 0) + create_node (e); e->anonaccess = 0; e->tokens = 0; e->flags.usedp = TRUE; @@ -2046,18 +2559,51 @@ fcache_get (FCacheEntry **res, VenusFid fid, CredCacheEntry *ce) e->flags.extradirp = FALSE; e->flags.mountp = FALSE; e->flags.kernelp = FALSE; + e->flags.sentenced = FALSE; e->host = 0; e->priority = fprio_get(fid); - e->volume = vol; + e->volume = NULL; e->lru_le = listaddhead (lrulist, e); hashtabadd (hashtab, e); + if (connected_mode != DISCONNECTED) { + VolCacheEntry *vol; + + error = volcache_getbyid (fid.fid.Volume, fid.Cell, ce, &vol, &type); + if (error) { + e->volume = NULL; + *res = NULL; + ReleaseWriteLock (&e->lock); + return error; + } + e->volume = vol; + } + *res = e; return 0; } /* + * Release the lock on `e' and mark it as stale if it has been sentenced. + */ + +void +fcache_release (FCacheEntry *e) +{ + assert (CheckLock (&e->lock) == -1); + + ReleaseWriteLock (&e->lock); + + if (e->flags.sentenced) { + AFSCallBack broken_callback = {0, 0, CBDROPPED}; + + stale (e, broken_callback); + e->flags.sentenced = FALSE; + } +} + +/* * */ @@ -2068,7 +2614,7 @@ uptodatep (FCacheEntry *e) assert (e->flags.usedp); if (connected_mode != CONNECTED && - connected_mode != CONNECTEDLOG) + connected_mode != FETCH_ONLY) return TRUE; gettimeofday(&tv, NULL); @@ -2084,6 +2630,7 @@ uptodatep (FCacheEntry *e) /* * Make sure that `e' has attributes and that they are up-to-date. + * `e' must be write-locked. */ int @@ -2101,6 +2648,27 @@ fcache_get_attr (FCacheEntry *e, CredCacheEntry *ce) return read_attr (e, ce); } +static int +do_read_data (FCacheEntry *e, CredCacheEntry *ce) +{ + int ret = RX_CALL_DEAD; + fs_server_context context; + ConnCacheEntry *conn; + + for (conn = find_first_fs (e, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { + ret = read_data (e, conn, ce); + if (!try_next_fs (ret)) + break; + } + free_fs_server_context (&context); + + if (conn == NULL) + return ENETDOWN; + return ret; +} + /* * Make sure that `e' has file data and is up-to-date. */ @@ -2108,8 +2676,9 @@ fcache_get_attr (FCacheEntry *e, CredCacheEntry *ce) int fcache_get_data (FCacheEntry *e, CredCacheEntry *ce) { - ConnCacheEntry *conn; + ConnCacheEntry *conn = NULL; int ret; + fs_server_context context; assert (e->flags.usedp); @@ -2118,29 +2687,207 @@ fcache_get_data (FCacheEntry *e, CredCacheEntry *ce) if (e->flags.attrp && uptodatep(e)) { if (e->flags.datap) return 0; - else { - conn = findconn (e, ce); - if (conn == NULL) - return ENETDOWN; - } + else + return do_read_data (e, ce); } else { - ret = do_read_attr (e, ce, &conn); - if (ret) + ret = do_read_attr (e, ce, &conn, &context); + if (ret) { + free_fs_server_context (&context); return ret; + } if (e->flags.datap) { - conn_free (conn); + free_fs_server_context (&context); return 0; } } ret = read_data (e, conn, ce); - conn_free (conn); + free_fs_server_context (&context); return ret; } /* + * Helper function for followmountpoint. + * Given the contents of a mount-point, figure out the cell and volume name. + */ + +static int +parse_mountpoint (char *mp, size_t len, int32_t *cell, char **volname) +{ + char *colon; + + mp[len - 1] = '\0'; + colon = strchr (mp, ':'); + if (colon != NULL) { + *colon++ = '\0'; + *cell = cell_name2num (mp + 1); + if (*cell == -1) + return ENOENT; + *volname = colon; + } else { + *volname = mp + 1; + } + return 0; +} + +/* + * Used by followmountpoint to figure out what clone of a volume + * should be used. + * + * Given a `volname', `cell', it uses the given `ce', `mount_symbol' + * and `parent_type' to return a volume id in `volume'. + * + * The rules are: + * + * "readonly" -> RO + * BK + "backup" -> fail + * "backup" -> BK + * BK + "" + # -> RO + * RO + "" + # -> RO + * * -> RW + * + * this_type = "" | "readonly" | "backup" + * parent_type = RW | RO | BK + * mount_symbol = "#" | "%" + */ + +static int +find_volume (const char *volname, int32_t cell, + CredCacheEntry *ce, char mount_symbol, int parent_type, + u_int32_t *volid) +{ + VolCacheEntry *ve; + int result_type; + int this_type; + int res; + + res = volcache_getbyname (volname, cell, ce, &ve, &this_type); + if (res) + return res; + + assert (this_type == RWVOL || + this_type == ROVOL || + this_type == BACKVOL); + + if (this_type == ROVOL) { + assert (ve->entry.flags & VLF_ROEXISTS); + result_type = ROVOL; + } else if (this_type == BACKVOL && parent_type == BACKVOL) { + volcache_free (ve); + return ENOENT; + } else if (this_type == BACKVOL) { + assert (ve->entry.flags & VLF_BOEXISTS); + result_type = BACKVOL; + } else if (this_type == RWVOL && + parent_type != RWVOL && + mount_symbol == '#') { + if (ve->entry.flags & VLF_ROEXISTS) + result_type = ROVOL; + else + result_type = RWVOL; + } else { + if (ve->entry.flags & VLF_RWEXISTS) + result_type = RWVOL; + else if (ve->entry.flags & VLF_ROEXISTS) + result_type = ROVOL; + else { + volcache_free (ve); + return ENOENT; + } + } + *volid = ve->entry.volumeId[result_type]; + volcache_free (ve); + return 0; +} + +/* + * Set `fid' to point to the root of the volume pointed to by the + * mount-point in (buf, len). + */ + +static int +get_root_of_volume (VenusFid *fid, VenusFid *parent, + VolCacheEntry *volume, CredCacheEntry **ce, + char *buf, size_t len) +{ + VenusFid oldfid = *fid; + char *volname; + int32_t cell; + u_int32_t volid; + int res; + long parent_type; + char mount_symbol; + FCacheEntry *e; + + cell = fid->Cell; + + res = parse_mountpoint (buf, len, &cell, &volname); + if (res) + return res; + + /* + * If this is a cross-cell mountpoint we need new credentials. + */ + + if ((*ce)->cell != cell) { + CredCacheEntry *new_ce; + + new_ce = cred_get (cell, (*ce)->cred, (*ce)->type); + if (new_ce == NULL) + new_ce = cred_get(cell, (*ce)->cred, CRED_ANY); + if (new_ce == NULL) + return ENOMEM; + cred_free (*ce); + *ce = new_ce; + } + + parent_type = gettype (fid->fid.Volume, volume); + mount_symbol = *buf; + + res = find_volume (volname, cell, *ce, mount_symbol, + parent_type, &volid); + if (res) + return res; + + /* + * Create the new fid. The root of a volume always has + * (Vnode, Unique) = (1,1) + */ + + fid->Cell = cell; + fid->fid.Volume = volid; + fid->fid.Vnode = fid->fid.Unique = 1; + + res = fcache_get (&e, *fid, *ce); + if (res) + return res; + + /* + * Mount points are a little bit special. We keep track of + * their parent in `parent' so that `..' can be handled + * properly. Also, increment the refcount so that this entry + * doesn't get gc:ed away under out feet. + */ + + ++e->refcount; + e->flags.mountp = TRUE; + e->realfid = oldfid; + e->parent = *parent; + fcache_release (e); + return 0; +} + +/* * If this entry is a mount point, set the fid data to * the root directory of the volume it's pointing at, * otherwise just leave it. + * + * Mount points are symbol links with the following contents: + * + * '#' | '%' [ cell ':' ] volume-name [ '.' ] + * + * This function tries to the minimal amount of work. It always has + * to fetch the attributes of `fid' and if it's a symbolic link, the + * contents as well. */ int @@ -2149,12 +2896,16 @@ followmountpoint (VenusFid *fid, VenusFid *parent, CredCacheEntry **ce) int fd; fbuf the_fbuf; char *buf; - long cell; - long type; FCacheEntry *e; - VenusFid oldfid = *fid; int res; u_int32_t length; + int close_ret; + + /* + * Get the node for `fid' and verify that it's a symbolic link + * with the correct contents. Otherwise, just return the old + * `fid' without any change. + */ res = fcache_get (&e, *fid, *ce); if (res) @@ -2162,130 +2913,46 @@ followmountpoint (VenusFid *fid, VenusFid *parent, CredCacheEntry **ce) res = fcache_get_attr (e, *ce); if (res) { - ReleaseWriteLock (&e->lock); + fcache_release(e); return res; } - if (e->status.FileType != TYPE_LINK) { - ReleaseWriteLock (&e->lock); + if (e->status.FileType != TYPE_LINK + || e->status.Length == 0) { + fcache_release(e); return 0; } res = fcache_get_data (e, *ce); if (res) { - ReleaseWriteLock (&e->lock); + fcache_release(e); return res; } + + length = e->status.Length; + if (length == 0) { + fcache_release(e); + return 0; + } - fd = fcache_open_file (e, O_RDONLY, 0); + fd = fcache_open_file (e, O_RDONLY); if (fd < 0) { - ReleaseWriteLock (&e->lock); + fcache_release(e); return errno; } - length = e->status.Length; res = fbuf_create (&the_fbuf, fd, length, FBUF_READ); if (res) { - close (fd); - ReleaseWriteLock (&e->lock); + close_ret = close (fd); + assert (close_ret == 0); + fcache_release(e); return res; } buf = (char *)(the_fbuf.buf); - switch (*buf) { - case '#' : - case '%' : { - int founderr; - char *dot; - - dot = buf + e->status.Length - 1; - *dot = '\0'; - dot = strchr (buf, ':'); - if (dot) { - *dot++ = '\0'; - cell = cell_name2num (buf + 1); - } else { - cell = fid->Cell; - dot = buf + 1; - } - if (*buf == '%') - type = RWVOL; - else - type = gettype (fid->fid.Volume, e->volume); - - founderr = 0; - - /* - * If this is a cross-cell mountpoint we need new credentials. - */ - - if ((*ce)->cell != cell) { - CredCacheEntry *new_ce; - - new_ce = cred_get (cell, (*ce)->cred, (*ce)->type); - if (new_ce == NULL) { - new_ce = cred_get(cell, (*ce)->cred, CRED_ANY); - } - if (new_ce == NULL) { - ReleaseWriteLock (&e->lock); - return ENOMEM; - } - cred_free (*ce); - *ce = new_ce; - } - - /* is the cell is invalid the rest should be bougs too */ - if (cell== -1) - founderr = -1; - else { - VolCacheEntry *ve; - - ve = volcache_getbyname (dot, cell, *ce); - if (ve == NULL) - founderr = -1; - else { - switch (type) { - case ROVOL : - if (ve->entry.flags & VLF_ROEXISTS) { - fid->fid.Volume = ve->entry.volumeId[ROVOL]; - break; - } - /* fall through */ - case RWVOL : - if (ve->entry.flags & VLF_RWEXISTS) - fid->fid.Volume = ve->entry.volumeId[RWVOL]; - else - founderr = -1; - break; - case BACKVOL : - if (ve->entry.flags & VLF_BOEXISTS) - fid->fid.Volume = ve->entry.volumeId[BACKVOL]; - else - founderr = -1; - break; - default : - abort (); - } - volcache_free (ve); - } - } - if (founderr) { - res = ENODEV; - break; - } - fid->Cell = cell; - fid->fid.Vnode = fid->fid.Unique = 1; - - ReleaseWriteLock (&e->lock); - res = fcache_get (&e, *fid, *ce); - if (res) - break; - ++e->refcount; - e->flags.mountp = TRUE; - e->realfid = oldfid; - e->parent = *parent; - } - } - ReleaseWriteLock (&e->lock); + if (*buf == '#' || *buf == '%') + res = get_root_of_volume (fid, parent, e->volume, ce, + buf, e->status.Length); + fcache_release(e); fbuf_end (&the_fbuf); return res; } @@ -2298,11 +2965,20 @@ static Bool print_entry (void *ptr, void *arg) { FCacheEntry *e = (FCacheEntry *)ptr; - FILE *f = (FILE *)arg; - fprintf (f, "(%d, %u, %u, %u)\n", + arla_log(ADEBVLOG, "(%d, %u, %u, %u)%s%s%s%s%s%s%s%s%s length: %ld\n", e->fid.Cell, - e->fid.fid.Volume, e->fid.fid.Vnode, e->fid.fid.Unique); + e->fid.fid.Volume, e->fid.fid.Vnode, e->fid.fid.Unique, + e->flags.usedp?" used":"", + e->flags.attrp?" attr":"", + e->flags.datap?" data":"", + e->flags.attrusedp?" attrused":"", + e->flags.datausedp?" dataused":"", + e->flags.extradirp?" extradir":"", + e->flags.mountp?" mount":"", + e->flags.kernelp?" kernel":"", + e->flags.sentenced?" sentenced":"", + e->status.Length); return FALSE; } @@ -2312,13 +2988,47 @@ print_entry (void *ptr, void *arg) */ void -fcache_status (FILE *f) +fcache_status (void) { - fprintf (f, "%lu (%lu-%lu) files\n" + arla_log(ADEBVLOG, "%lu (%lu-%lu) files\n" "%lu (%lu-%lu) bytes\n", usedvnodes, lowvnodes, highvnodes, usedbytes, lowbytes, highbytes); - hashtabforeach (hashtab, print_entry, f); + hashtabforeach (hashtab, print_entry, NULL); +} + +/* + * + */ + +void +fcache_update_length (FCacheEntry *e, size_t len) +{ + int fd; + struct stat sb; + int close_ret; + + fd = fcache_open_file (e, O_RDONLY); + if (fd < 0) { + arla_warn (ADEBFCACHE, errno, "fcache_open_file"); + assert(FALSE); + } + + if (fstat (fd, &sb) < 0) { + arla_warn (ADEBFCACHE, errno, "fstat"); + close_ret = close (fd); + assert (close_ret); + assert (FALSE); + } + close_ret = close(fd); + assert(close_ret == 0); + + assert (len == sb.st_size); + + assert (usedbytes + len >= e->status.Length); + + usedbytes = usedbytes - e->status.Length + len; + e->status.Length = len; } /* @@ -2335,6 +3045,7 @@ getacl(VenusFid fid, AFSFetchStatus status; AFSVolSync volsync; int ret; + fs_server_context context; ret = fcache_get (&dire, fid, ce); if (ret) { @@ -2342,15 +3053,24 @@ getacl(VenusFid fid, return ret; } - conn = findconn (dire, ce); + ret = RX_CALL_DEAD; + + for (conn = find_first_fs (dire, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { + ret = RXAFS_FetchACL (conn->connection, &fid.fid, + opaque, &status, &volsync); + if (!try_next_fs (ret)) + break; + } + if (ret) + arla_warn (ADEBFCACHE, ret, "FetchACL"); + free_fs_server_context (&context); + if (conn == NULL) - return ENETDOWN; + ret = ENETDOWN; - ret = RXAFS_FetchACL (conn->connection, &fid.fid, - opaque, &status, &volsync); - conn_free (conn); - throw_entry (dire); - + fcache_release (dire); return ret; } @@ -2368,6 +3088,7 @@ setacl(VenusFid fid, AFSFetchStatus status; AFSVolSync volsync; int ret; + fs_server_context context; ret = fcache_get (&dire, fid, ce); if (ret) { @@ -2375,16 +3096,29 @@ setacl(VenusFid fid, return EINVAL; } - conn = findconn (dire, ce); + ret = RX_CALL_DEAD; + + for (conn = find_first_fs (dire, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { + ret = RXAFS_StoreACL (conn->connection, &fid.fid, + opaque, &status, &volsync); + if (!try_next_fs (ret)) + break; + } + if (ret) + arla_warn (ADEBFCACHE, ret, "StoreACL"); + free_fs_server_context (&context); + if (conn == NULL) - return ENETDOWN; + ret = ENETDOWN; - ret = RXAFS_StoreACL (conn->connection, &fid.fid, - opaque, &status, &volsync); - - conn_free (conn); - throw_entry (dire); - + if (ret == 0 && dire->flags.kernelp) { + break_callback (dire->fid); + dire->flags.kernelp = FALSE; + } + + fcache_release (dire); return ret; } @@ -2402,6 +3136,7 @@ getvolstat(VenusFid fid, CredCacheEntry *ce, FCacheEntry *dire; ConnCacheEntry *conn; int ret; + fs_server_context context; ret = fcache_get (&dire, fid, ce); if (ret) { @@ -2409,16 +3144,25 @@ getvolstat(VenusFid fid, CredCacheEntry *ce, return EINVAL; } - conn = findconn (dire, ce); + ret = RX_CALL_DEAD; + + for (conn = find_first_fs (dire, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { + ret = RXAFS_GetVolumeStatus (conn->connection, fid.fid.Volume, + volstat, volumename, offlinemsg, + motd); + if (!try_next_fs (ret)) + break; + } + if (ret) + arla_warn (ADEBFCACHE, ret, "GetVolumeStatus"); + free_fs_server_context (&context); + if (conn == NULL) - return ENETDOWN; + ret = ENETDOWN; - ret = RXAFS_GetVolumeStatus (conn->connection, fid.fid.Volume, - volstat, volumename, offlinemsg, - motd); - conn_free (conn); - throw_entry (dire); - + fcache_release (dire); return ret; } @@ -2436,6 +3180,7 @@ setvolstat(VenusFid fid, CredCacheEntry *ce, FCacheEntry *dire; ConnCacheEntry *conn; int ret; + fs_server_context context; ret = fcache_get (&dire, fid, ce); if (ret) { @@ -2443,15 +3188,24 @@ setvolstat(VenusFid fid, CredCacheEntry *ce, return EINVAL; } - conn = findconn (dire, ce); + ret = RX_CALL_DEAD; + + for (conn = find_first_fs (dire, ce, &context); + conn != NULL; + conn = find_next_fs (&context, conn)) { + ret = RXAFS_SetVolumeStatus (conn->connection, fid.fid.Volume, + volstat, volumename, offlinemsg, + motd); + if (!try_next_fs (ret)) + break; + } + if (ret) + arla_warn (ADEBFCACHE, ret, "SetVolumeStatus"); + free_fs_server_context (&context); + if (conn == NULL) - return ENETDOWN; + ret = ENETDOWN; - ret = RXAFS_SetVolumeStatus (conn->connection, fid.fid.Volume, - volstat, volumename, offlinemsg, - motd); - conn_free (conn); - throw_entry (dire); - + fcache_release (dire); return ret; } diff --git a/usr.sbin/afs/src/arlad/fcache.h b/usr.sbin/afs/src/arlad/fcache.h index 6838ce9b7ae..6f920507206 100644 --- a/usr.sbin/afs/src/arlad/fcache.h +++ b/usr.sbin/afs/src/arlad/fcache.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fcache.h,v 1.1.1.1 1998/09/14 21:52:56 art Exp $ */ +/* $OpenBSD: fcache.h,v 1.2 1999/04/30 01:59:08 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * The interface for the file-cache. */ -/* $KTH: fcache.h,v 1.37 1998/07/22 07:02:04 assar Exp $ */ +/* $KTH: fcache.h,v 1.49 1999/04/14 15:27:35 map Exp $ */ #ifndef _FCACHE_H_ #define _FCACHE_H_ @@ -49,6 +49,7 @@ #include <xfs/xfs_message.h> #include <fcntl.h> #include <cred.h> +#include <heap.h> /* * For each entry in the filecache we save the rights of NACCESS users. @@ -73,17 +74,30 @@ enum Access { ANONE = 0x0, ALOCK = 0x20, AADMIN = 0x40 }; +/* + * Keep the necessary state with traversing mount points. + * Might want to make this per-user/per-process in some distant future. + */ + +struct mp_traversal { + VenusFid parent; /* the point where the traversal started */ + unsigned refcount; +}; + +typedef struct mp_traversal mp_traversal; + typedef struct { struct Lock lock; /* locking information for this entry */ VenusFid fid; /* The fid of the file for this entry */ unsigned refcount; /* reference count */ - u_long host; /* the source of this entry */ + u_int32_t host; /* the source of this entry */ AFSFetchStatus status; /* Removed unused stuff later */ AFSCallBack callback; /* Callback to the AFS-server */ AFSVolSync volsync; /* Sync info for ro-volumes */ AccessEntry acccache[NACCESS]; /* cache for the access rights */ - u_long anonaccess; /* the access mask for system:anyuser */ - ino_t inode; /* right now only an index */ + u_int32_t anonaccess; /* the access mask for system:anyuser */ + unsigned index; /* this is V%u */ + xfs_cache_handle handle; /* handle */ struct { unsigned usedp : 1; /* Is this entry used? */ unsigned attrp : 1; /* Are the attributes in status valid? */ @@ -93,16 +107,35 @@ typedef struct { unsigned extradirp : 1; /* Has this directory been "converted"? */ unsigned mountp : 1; /* Is this an AFS mount point? */ unsigned kernelp : 1; /* Does this entry exist in the kernel? */ + unsigned sentenced : 1; /* This entry should die */ } flags; u_int tokens; /* read/write tokens for the kernel */ - VenusFid parent; /* fid of the parent */ +#if 0 + mp_traversal *mp_traversal; /* valid iff flags.mountp */ +#endif + VenusFid parent; VenusFid realfid; /* Real fid (mountpoints) */ Listitem *lru_le; /* lru */ +#if 0 Listitem *invalid_le; /* invalidation list */ +#else + heap_ptr invalid_ptr; /* pointer into the heap */ +#endif VolCacheEntry *volume; /* pointer to the volume entry */ unsigned priority; /* the priority of keeping the file 0-100 */ } FCacheEntry; +/* + * The fileservers to ask for a particular volume. + */ + +struct fs_server_context { + ConnCacheEntry *conns[NMAXNSERVERS]; + int i; /* current number being probed */ + int num_conns; /* number in `conns' */ +}; + +typedef struct fs_server_context fs_server_context; /* * How far the cleaner will go went cleaning things up. @@ -142,13 +175,19 @@ int fcache_extra_file_name (FCacheEntry *entry, char *s, size_t len); int -fcache_open_file (FCacheEntry *entry, int flag, mode_t mode); +fcache_create_file (FCacheEntry *entry); + +int +fcache_open_file (FCacheEntry *entry, int flag); int fcache_open_extra_dir (FCacheEntry *entry, int flag, mode_t mode); int -write_data (FCacheEntry *entry, CredCacheEntry *ce); +fcache_fhget (char *filename, xfs_cache_handle *handle); + +int +write_data (FCacheEntry *entry, AFSStoreStatus *status, CredCacheEntry *ce); int truncate_file (FCacheEntry *entry, off_t size, CredCacheEntry *ce); @@ -201,6 +240,9 @@ getroot (VenusFid *res, CredCacheEntry *ce); int fcache_get (FCacheEntry **res, VenusFid fid, CredCacheEntry *ce); +void +fcache_release (FCacheEntry *e); + int fcache_find (FCacheEntry **res, VenusFid fid); @@ -214,7 +256,7 @@ int followmountpoint (VenusFid *fid, VenusFid *parent, CredCacheEntry **ce); void -fcache_status (FILE *f); +fcache_status (void); int fcache_store_state (void); @@ -241,6 +283,23 @@ setvolstat(VenusFid fid, CredCacheEntry *ce, char *offlinemsg, char *motd); +u_long +fcache_highbytes(void); + +u_long +fcache_usedbytes(void); + +u_long +fcache_highvnodes(void); + +u_long +fcache_usedvnodes(void); + +int +fcache_giveup_all_callbacks (void); + +int +fcache_reobtain_callbacks (void); /* XXX - this shouldn't be public, but getrights in inter.c needs it */ int @@ -249,4 +308,21 @@ read_attr (FCacheEntry *, CredCacheEntry *); Bool findaccess (pag_t cred, AccessEntry *ae, AccessEntry **pos); +void +fcache_unused(FCacheEntry *entry); + +void +fcache_update_length (FCacheEntry *entry, size_t len); + +ConnCacheEntry * +find_first_fs (FCacheEntry *e, + CredCacheEntry *ce, + fs_server_context *context); + +ConnCacheEntry * +find_next_fs (fs_server_context *context, ConnCacheEntry *prev_conn); + +void +free_fs_server_context (fs_server_context *context); + #endif /* _FCACHE_H_ */ diff --git a/usr.sbin/afs/src/arlad/fprio.c b/usr.sbin/afs/src/arlad/fprio.c index 7e4aabe3ab2..3904d2b43f8 100644 --- a/usr.sbin/afs/src/arlad/fprio.c +++ b/usr.sbin/afs/src/arlad/fprio.c @@ -1,6 +1,6 @@ -/* $OpenBSD: fprio.c,v 1.1.1.1 1998/09/14 21:52:56 art Exp $ */ +/* $OpenBSD: fprio.c,v 1.2 1999/04/30 01:59:08 art Exp $ */ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -42,8 +42,8 @@ */ #include "arla_local.h" -#include <kerberosIV/kafs.h> -RCSID("$KTH: fprio.c,v 1.3 1998/06/08 18:55:13 lha Exp $"); +#include <kafs.h> +RCSID("$KTH: fprio.c,v 1.6 1999/04/20 20:58:08 map Exp $"); /* Hashtable of entries by name */ static Hashtab *fpriohashtab; @@ -202,10 +202,8 @@ fprio_readin(char *file) int lineno = 0 ; f = fopen(file, "r"); - if (f == NULL) { - arla_warn(ADEBFCACHE, 1, "fprio_readin: cant open file %s", file); + if (f == NULL) return -1; - } while(fgets(line, sizeof(line)-1, f) != NULL) { lineno++; @@ -263,7 +261,6 @@ static Bool fprio_print_entry (void *ptr, void *arg) { struct fpriorityentry *n = (struct fpriorityentry *)ptr; - FILE *f = (FILE *) ptr; const char *cell = cell_num2name(n->fid.Cell); char *comment; @@ -272,9 +269,9 @@ fprio_print_entry (void *ptr, void *arg) else comment = ""; - fprintf(f, "%s%d:%s:%d:%d:%d", - comment, n->priority, cell?cell:"unknowncell", n->fid.fid.Volume, - n->fid.fid.Vnode, n->fid.fid.Unique); + arla_log(ADEBVLOG, "%s%d:%s:%d:%d:%d", + comment, n->priority, cell?cell:"unknowncell", n->fid.fid.Volume, + n->fid.fid.Vnode, n->fid.fid.Unique); return FALSE; } @@ -284,16 +281,16 @@ fprio_print_entry (void *ptr, void *arg) */ void -fprio_status (FILE *f) +fprio_status (void) { time_t the_time = time(NULL); - fprintf (f, "#fprio entries\n#\n# Date: %s\n#\n" + arla_log(ADEBVLOG, "#fprio entries\n#\n# Date: %s\n#\n" "#priority range from %d to %d\n#\n" "#Syntax: (# means comment)\n" "#priority:cell:volume:vnode:unique\n", ctime(&the_time), FPRIO_MIN, FPRIO_MAX); - hashtabforeach (fpriohashtab, fprio_print_entry, f); + hashtabforeach (fpriohashtab, fprio_print_entry, NULL); } diff --git a/usr.sbin/afs/src/arlad/fprio.h b/usr.sbin/afs/src/arlad/fprio.h index b8a7d123c8e..0b498d341f4 100644 --- a/usr.sbin/afs/src/arlad/fprio.h +++ b/usr.sbin/afs/src/arlad/fprio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fprio.h,v 1.1.1.1 1998/09/14 21:52:56 art Exp $ */ +/* $OpenBSD: fprio.h,v 1.2 1999/04/30 01:59:08 art Exp $ */ /* * Copyright (c) 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * Our cache of volume information. */ -/* $KTH: fprio.h,v 1.3 1998/06/08 18:55:13 lha Exp $ */ +/* $KTH: fprio.h,v 1.4 1999/04/14 15:27:36 map Exp $ */ #ifndef _FPRIO_ #define _FPRIO_ @@ -61,7 +61,7 @@ void fprio_remove(VenusFid fid); void fprio_set(VenusFid fid, unsigned prio); int fprio_readin(char *file); int fprio_get(VenusFid fid); -void fprio_status (FILE *f); +void fprio_status (void); #endif /* _FPRIO_ */ diff --git a/usr.sbin/afs/src/arlad/fs_errors.h b/usr.sbin/afs/src/arlad/fs_errors.h new file mode 100644 index 00000000000..8a4695d4416 --- /dev/null +++ b/usr.sbin/afs/src/arlad/fs_errors.h @@ -0,0 +1,92 @@ +/* $OpenBSD: fs_errors.h,v 1.1 1999/04/30 01:59:08 art Exp $ */ +/* + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _FS_ERRORS_H_ +#define _FS_ERRORS_H_ 1 + +#define VICE_SPECIAL_ERRORS 101 + +#define VICE_SPECIAL_ERRORS_MIN 101 +#define VICE_SPECIAL_ERRORS_MAX 112 + +#define VSALVAGE 101 +#define VNOVNODE 102 +#define VNOVOL 103 +#define VVOLEXISTS 104 +#define VNOSERVICE 105 +#define VOFFLINE 106 +#define VONLINE 107 +#define VDISKFULL 108 +#define VOVERQUOTA 109 +#define VBUSY 110 +#define VMOVED 111 +#define VIO 112 + +#define VRESTARTING -100 + +#define ARLA_SPECIAL_ERROR_ADD 4000 +#define ARLA_SPECIAL2_ERROR_ADD 4600 + +#define ARLA_VSALVAGE (ARLA_SPECIAL_ERROR_ADD+VSALVAGE) +#define ARLA_VNOVNODE (ARLA_SPECIAL_ERROR_ADD+VNOVNODE) +#define ARLA_VNOVOL (ARLA_SPECIAL_ERROR_ADD+VNOVOL) +#define ARLA_VVOLEXISTS (ARLA_SPECIAL_ERROR_ADD+VVOLEXISTS) +#define ARLA_VNOSERVICE (ARLA_SPECIAL_ERROR_ADD+VNOSERVICE) +#define ARLA_VOFFLINE (ARLA_SPECIAL_ERROR_ADD+VOFFLINE) +#define ARLA_VONLINE (ARLA_SPECIAL_ERROR_ADD+VONLINE) +#define ARLA_VDISKFULL (ARLA_SPECIAL_ERROR_ADD+VDISKFULL) +#define ARLA_VOVERQUOTA (ARLA_SPECIAL_ERROR_ADD+VOVERQUOTA) +#define ARLA_VBUSY (ARLA_SPECIAL_ERROR_ADD+VBUSY) +#define ARLA_VMOVED (ARLA_SPECIAL_ERROR_ADD+VMOVED) +#define ARLA_VIO (ARLA_SPECIAL_ERROR_ADD+VIO) +#define ARLA_VRESTARTING (ARLA_SPECIAL2_ERROR_ADD+VRESTARTING) + +static inline int __attribute__ ((unused)) +conv_to_arla_errno(int error) +{ + if (error >= VICE_SPECIAL_ERRORS_MIN && + error <= VICE_SPECIAL_ERRORS_MAX) + return error + ARLA_SPECIAL_ERROR_ADD; + else if (error == VRESTARTING) + return ARLA_VRESTARTING; + else + return error; +} + +#endif /* _FS_ERRORS_H_ */ diff --git a/usr.sbin/afs/src/arlad/inter.c b/usr.sbin/afs/src/arlad/inter.c index 0205beebc4e..2f416cf04ad 100644 --- a/usr.sbin/afs/src/arlad/inter.c +++ b/usr.sbin/afs/src/arlad/inter.c @@ -1,6 +1,6 @@ -/* $OpenBSD: inter.c,v 1.1.1.1 1998/09/14 21:52:56 art Exp $ */ +/* $OpenBSD: inter.c,v 1.2 1999/04/30 01:59:08 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -42,7 +42,7 @@ */ #include "arla_local.h" -RCSID("$KTH: inter.c,v 1.55 1998/07/29 21:31:59 assar Exp $") ; +RCSID("$KTH: inter.c,v 1.71 1999/02/05 02:43:33 assar Exp $") ; #include <xfs/xfs_message.h> @@ -154,7 +154,12 @@ log_operation (const char *fmt, ...) */ Result -cm_open (VenusFid fid, CredCacheEntry* ce, u_int tokens) +cm_open (VenusFid fid, + CredCacheEntry* ce, + u_int tokens, + xfs_cache_handle *cache_handle, + char *cache_name, + size_t cache_name_sz) { FCacheEntry *entry; Result ret; @@ -172,7 +177,7 @@ cm_open (VenusFid fid, CredCacheEntry* ce, u_int tokens) error = fcache_get_data (entry, ce); if(error) { - ReleaseWriteLock (&entry->lock); + fcache_release(entry); ret.res = -1; ret.error = error; return ret; @@ -198,21 +203,24 @@ cm_open (VenusFid fid, CredCacheEntry* ce, u_int tokens) } if (checkright (entry, mask, ce)) { - ret.res = entry->inode; entry->flags.datausedp = TRUE; entry->tokens |= tokens; - - ret.res = entry->inode; + ret.res = 0; + ret.error = 0; ret.tokens = entry->tokens; + + *cache_handle = entry->handle; + fcache_file_name (entry, cache_name, cache_name_sz); log_operation ("open (%ld,%lu,%lu,%lu) %u\n", - fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique, - mask); + fid.Cell, + fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique, + mask); } else { ret.res = -1; ret.error = EACCES; } - ReleaseWriteLock (&entry->lock); + fcache_release(entry); return ret; } @@ -223,7 +231,7 @@ cm_open (VenusFid fid, CredCacheEntry* ce, u_int tokens) */ Result -cm_close (VenusFid fid, int flag, CredCacheEntry* ce) +cm_close (VenusFid fid, int flag, AFSStoreStatus *status, CredCacheEntry* ce) { FCacheEntry *entry; Result ret; @@ -231,19 +239,19 @@ cm_close (VenusFid fid, int flag, CredCacheEntry* ce) error = fcache_get (&entry, fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } if (flag & XFS_WRITE) { - error = write_data (entry, ce); + error = write_data (entry, status, ce); if (error) { - ReleaseWriteLock (&entry->lock); + fcache_release(entry); arla_warn (ADEBCM, error, "writing back file"); - ret.res = -1 ; - ret.error = EPERM ; + ret.res = -1; + ret.error = error; return ret; } } @@ -252,8 +260,9 @@ cm_close (VenusFid fid, int flag, CredCacheEntry* ce) fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique, flag); - ReleaseWriteLock (&entry->lock); - ret.res = 0; + fcache_release(entry); + ret.res = 0; + ret.error = 0; return ret; } @@ -274,15 +283,15 @@ cm_getattr (VenusFid fid, error = fcache_get (&entry, fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_attr (entry, ce); if (error) { - ReleaseWriteLock (&entry->lock); - ret.res = -1; + fcache_release(entry); + ret.res = -1; ret.error = error; return ret; } @@ -291,10 +300,10 @@ cm_getattr (VenusFid fid, entry->status.FileType == TYPE_FILE ? AREAD : ALIST, ce)) { *attr = entry->status; - ret.res = 0; + ret.res = 0; + ret.error = 0; entry->flags.attrusedp = TRUE; - entry->flags.kernelp = TRUE; - entry->tokens |= XFS_ATTR_R; + entry->flags.kernelp = TRUE; if (ae != NULL) *ae = entry->acccache; @@ -305,12 +314,8 @@ cm_getattr (VenusFid fid, ret.res = -1; ret.error = EACCES; } - if(entry->flags.mountp) - *realfid = entry->realfid; - else - *realfid = fid; - - ReleaseWriteLock (&entry->lock); + *realfid = entry->realfid; + fcache_release(entry); ret.tokens = entry->tokens; return ret; } @@ -329,32 +334,31 @@ cm_setattr (VenusFid fid, AFSStoreStatus *attr, CredCacheEntry* ce) error = fcache_get (&entry, fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_attr (entry, ce); if (error) { - ReleaseWriteLock (&entry->lock); - ret.res = -1; + fcache_release(entry); + ret.res = -1; ret.error = error; return ret; } if (checkright (entry, AWRITE, ce)) { arla_warnx (ADEBCM, "cm_setattr: Writing status"); - ret.res = write_attr (entry, attr, ce); - if (ret.res != 0) - ret.error = ret.res; + ret.res = write_attr (entry, attr, ce); + ret.error = ret.res; log_operation ("setattr (%ld,%lu,%lu,%lu)\n", fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique); } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } - ReleaseWriteLock (&entry->lock); + fcache_release(entry); return ret; } @@ -371,30 +375,31 @@ cm_ftruncate (VenusFid fid, off_t size, CredCacheEntry* ce) error = fcache_get (&entry, fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_attr (entry, ce); if (error) { - ReleaseWriteLock (&entry->lock); - ret.res = -1; + fcache_release(entry); + ret.res = -1; ret.error = error; return ret; } if (checkright (entry, AWRITE, ce)) { - ret.res = truncate_file (entry, size, ce); + ret.res = truncate_file (entry, size, ce); + ret.error = ret.res; log_operation ("ftruncate (%ld,%lu,%lu,%lu) %lu\n", fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique, (unsigned long)size); } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } - ReleaseWriteLock (&entry->lock); + fcache_release(entry); return ret; } @@ -411,30 +416,31 @@ cm_access (VenusFid fid, int mode, CredCacheEntry* ce) error = fcache_get (&entry, fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_attr (entry, ce); if (error) { - ReleaseWriteLock (&entry->lock); - ret.res = -1; + fcache_release(entry); + ret.res = -1; ret.error = error; return ret; } if (checkright (entry, AWRITE, ce)) { - ret.res = 0; /**/ + ret.res = 0; /**/ + ret.error = 0; } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } log_operation ("access (%ld,%lu,%lu,%lu)\n", fid.Cell, fid.fid.Volume, fid.fid.Vnode, fid.fid.Unique); - ReleaseWriteLock (&entry->lock); + fcache_release(entry); return ret; } @@ -519,6 +525,7 @@ cm_lookup (VenusFid dir_fid, } else { ret.res = 0; ret.tokens = 0; + ret.error = 0; } /* Assume that this means a bad .. */ @@ -532,25 +539,29 @@ cm_lookup (VenusFid dir_fid, error = fcache_get (&e, dir_fid, *ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_attr (e, *ce); if (error) { - ReleaseWriteLock (&e->lock); - ret.res = -1; + fcache_release(e); + ret.res = -1; ret.error = error; return ret; } assert (e->flags.mountp); +#if 0 + *res = e->mp_traversal->parent; +#endif *res = e->parent; - ret.res = 0; + ret.res = 0; + ret.error = 0; ret.tokens = e->tokens; - ReleaseWriteLock (&e->lock); + fcache_release(e); } log_operation ("lookup (%ld,%lu,%lu,%lu) %s\n", @@ -576,14 +587,14 @@ cm_create (VenusFid dir_fid, const char *name, AFSStoreStatus *store_attr, error = fcache_get (&dire, dir_fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_data (dire, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; goto out; } @@ -592,19 +603,20 @@ cm_create (VenusFid dir_fid, const char *name, AFSStoreStatus *store_attr, error = create_file (dire, name, store_attr, res, fetch_attr, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { error = adir_creat (dire, name, res->fid); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { - ret.res = 0; + ret.res = 0; + ret.error = 0; } } } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } out: @@ -613,7 +625,7 @@ out: dir_fid.fid.Volume, dir_fid.fid.Vnode, dir_fid.fid.Unique, name); - ReleaseWriteLock (&dire->lock); + fcache_release(dire); return ret; } @@ -633,14 +645,14 @@ cm_mkdir (VenusFid dir_fid, const char *name, error = fcache_get (&dire, dir_fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_data (dire, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; goto out; } @@ -649,19 +661,20 @@ cm_mkdir (VenusFid dir_fid, const char *name, error = create_directory (dire, name, store_attr, res, fetch_attr, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { error = adir_creat (dire, name, res->fid); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { - ret.res = 0; + ret.res = 0; + ret.error = 0; } } } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } @@ -671,7 +684,7 @@ cm_mkdir (VenusFid dir_fid, const char *name, name); out: - ReleaseSharedLock (&dire->lock); + ReleaseWriteLock (&dire->lock); return ret; } @@ -686,52 +699,81 @@ cm_symlink (VenusFid dir_fid, const char *contents, CredCacheEntry* ce) { - FCacheEntry *dire; + FCacheEntry *dire, *symlink_entry; Result ret; int error; error = fcache_get (&dire, dir_fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_data (dire, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; goto out; } - if (checkright (dire, AINSERT, ce)) { - error = create_symlink (dire, name, store_attr, - res, fetch_attr, - contents, ce); - if (error) { - ret.res = -1; - ret.error = error; - } else { - error = adir_creat (dire, name, res->fid); - if (error) { - ret.res = -1; - ret.error = error; - } else { - ret.res = 0; - } - } - } else { - ret.res = -1; - ret.error = EACCES; + if (!checkright (dire, AINSERT, ce)) { + ret.res = -1; + ret.error = EACCES; + goto out; } + + error = create_symlink (dire, name, store_attr, + res, fetch_attr, + contents, ce); + if (error) { + ret.res = -1; + ret.error = error; + goto out; + } + + error = adir_creat (dire, name, res->fid); + if (error) { + ret.res = -1; + ret.error = error; + goto out; + } + + error = followmountpoint(res, &dir_fid, &ce); + if (error) { + ret.res = -1; + ret.error = error; + goto out; + } + + error = fcache_get (&symlink_entry, *res, ce); + if (error) { + ret.res = -1; + ret.error = error; + goto out; + } + + error = fcache_get_attr (symlink_entry, ce); + if (error) { + fcache_release (symlink_entry); + ret.res = -1; + ret.error = error; + goto out; + } + + *fetch_attr = symlink_entry->status; + fcache_release (symlink_entry); + ret.res = 0; + ret.error = 0; + log_operation ("symlink (%ld,%lu,%lu,%lu) %s %s\n", - dir_fid.Cell, - dir_fid.fid.Volume, dir_fid.fid.Vnode, dir_fid.fid.Unique, - name, - contents); + dir_fid.Cell, + dir_fid.fid.Volume, dir_fid.fid.Vnode, dir_fid.fid.Unique, + name, + contents); out: - ReleaseWriteLock (&dire->lock); + fcache_release(dire); return ret; } @@ -752,52 +794,52 @@ cm_link (VenusFid dir_fid, error = fcache_get (&dire, dir_fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_data (dire, ce); if (error) { - ReleaseWriteLock (&dire->lock); - ret.res = -1; + fcache_release(dire); + ret.res = -1; ret.error = error; return ret; } error = fcache_get (&file, existing_fid, ce); if (error) { - ReleaseWriteLock (&dire->lock); - ret.res = -1; + fcache_release(dire); + ret.res = -1; ret.error = error; return ret; } error = fcache_get_attr (file, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; goto out; } if (checkright (dire, AINSERT, ce)) { - error = create_link (dire, name, - file, ce); + error = create_link (dire, name, file, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { error = adir_creat (dire, name, existing_fid.fid); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { *existing_status = file->status; - ret.res = 0; + ret.res = 0; + ret.error = 0; } } } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } log_operation ("link (%ld,%lu,%lu,%lu) (%ld,%lu,%lu,%lu) %s\n", @@ -810,12 +852,13 @@ cm_link (VenusFid dir_fid, name); out: - ReleaseWriteLock (&dire->lock); - ReleaseWriteLock (&file->lock); + fcache_release(dire); + fcache_release(file); return ret; } + /* - * + * Remove the file named `name' in the directory `dir_fid'. */ Result @@ -828,14 +871,14 @@ cm_remove(VenusFid dir_fid, error = fcache_get (&dire, dir_fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_data (dire, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; goto out; } @@ -843,19 +886,20 @@ cm_remove(VenusFid dir_fid, if (checkright (dire, ADELETE, ce)) { error = remove_file (dire, name, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { error = adir_remove (dire, name); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { - ret.res = 0; + ret.res = 0; + ret.error = 0; } } } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } log_operation ("remove (%ld,%lu,%lu,%lu) %s\n", @@ -864,12 +908,12 @@ cm_remove(VenusFid dir_fid, name); out: - ReleaseWriteLock (&dire->lock); + fcache_release(dire); return ret; } /* - * + * Remove the directory named `name' in the directory `dir_fid'. */ Result @@ -882,14 +926,14 @@ cm_rmdir(VenusFid dir_fid, error = fcache_get (&dire, dir_fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_data (dire, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; goto out; } @@ -897,19 +941,20 @@ cm_rmdir(VenusFid dir_fid, if (checkright (dire, ADELETE, ce)) { error = remove_directory (dire, name, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { error = adir_remove (dire, name); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { - ret.res = 0; + ret.res = 0; + ret.error = 0; } } } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } @@ -919,12 +964,12 @@ cm_rmdir(VenusFid dir_fid, name); out: - ReleaseWriteLock (&dire->lock); + fcache_release(dire); return ret; } /* - * + * Rename (old_parent_fid, old_name) -> (new_parent_fid, new_name) */ Result @@ -941,15 +986,15 @@ cm_rename(VenusFid old_parent_fid, const char *old_name, error = fcache_get (&old_dir, old_parent_fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; return ret; } error = fcache_get_data (old_dir, ce); if (error) { - ReleaseWriteLock (&old_dir->lock); - ret.res = -1; + fcache_release(old_dir); + ret.res = -1; ret.error = error; return ret; } @@ -961,15 +1006,15 @@ cm_rename(VenusFid old_parent_fid, const char *old_name, error = fcache_get (&new_dir, new_parent_fid, ce); if (error) { - ReleaseWriteLock (&old_dir->lock); - ret.res = -1; + fcache_release(old_dir); + ret.res = -1; ret.error = error; return ret; } error = fcache_get_data (new_dir, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; goto out; } @@ -985,32 +1030,50 @@ cm_rename(VenusFid old_parent_fid, const char *old_name, new_dir, new_name, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { - VenusFid foo_fid; + VenusFid new_fid, old_fid; + + /* + * Lookup the old name (to get the fid of the new name) + */ - ReleaseWriteLock (&old_dir->lock); - error = adir_lookup (old_dir->fid, old_name, &foo_fid, ce); - ObtainWriteLock (&old_dir->lock); + error = adir_lookup_fcacheentry (old_dir, old_name, &new_fid, ce); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; goto out; } - error = adir_remove (old_dir, old_name) - || adir_creat (new_dir, new_name, foo_fid.fid); + + /* + * Lookup the new name, if it exists we need to clear it out. + * XXX Should we check the lnkcount and clear it from fcache ? + */ + + error = adir_lookup_fcacheentry (new_dir, new_name, &old_fid, ce); + if (error == 0) + adir_remove (new_dir, new_name); + + /* + * Now do the rename, ie create the new name and remove + * the old name. + */ + + error = adir_creat (new_dir, new_name, new_fid.fid) + || adir_remove (old_dir, old_name); if (error) { - ret.res = -1; + ret.res = -1; ret.error = error; } else { - ret.res = 0; + ret.res = 0; + ret.error = 0; } } } else { - ret.res = -1; + ret.res = -1; ret.error = EACCES; } @@ -1026,9 +1089,9 @@ cm_rename(VenusFid old_parent_fid, const char *old_name, old_name, new_name); out: - ReleaseWriteLock (&old_dir->lock); + fcache_release(old_dir); if (old_parent_fid.fid.Vnode != new_parent_fid.fid.Vnode || old_parent_fid.fid.Unique != new_parent_fid.fid.Unique) - ReleaseWriteLock (&new_dir->lock); + fcache_release(new_dir); return ret; } diff --git a/usr.sbin/afs/src/arlad/inter.h b/usr.sbin/afs/src/arlad/inter.h index 96296728f82..31d87159437 100644 --- a/usr.sbin/afs/src/arlad/inter.h +++ b/usr.sbin/afs/src/arlad/inter.h @@ -1,4 +1,4 @@ -/* $OpenBSD: inter.h,v 1.1.1.1 1998/09/14 21:52:57 art Exp $ */ +/* $OpenBSD: inter.h,v 1.2 1999/04/30 01:59:08 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * The interface to the cache manager. */ -/* $KTH: inter.h,v 1.14 1998/07/22 07:04:06 assar Exp $ */ +/* $KTH: inter.h,v 1.16 1999/01/10 20:25:58 map Exp $ */ #ifndef _INTER_H_ #define _INTER_H_ @@ -54,9 +54,9 @@ */ typedef struct { - int res; - int error; - u_int tokens; + int res; /* result */ + int error; /* error if res == -1 */ + u_int tokens; /* resulting tokens (if res == 0) */ } Result; void @@ -66,10 +66,11 @@ void cm_store_state (void); Result -cm_open (VenusFid fid, CredCacheEntry *ce, u_int tokens); +cm_open (VenusFid fid, CredCacheEntry *ce, u_int tokens, + xfs_cache_handle *, char *, size_t); Result -cm_close (VenusFid fid, int flag, CredCacheEntry *ce); +cm_close (VenusFid fid, int flag, AFSStoreStatus *, CredCacheEntry *ce); Result cm_getattr (VenusFid fid, diff --git a/usr.sbin/afs/src/arlad/kernel.c b/usr.sbin/afs/src/arlad/kernel.c index de6a0229c9a..61aa36be09a 100644 --- a/usr.sbin/afs/src/arlad/kernel.c +++ b/usr.sbin/afs/src/arlad/kernel.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kernel.c,v 1.1.1.1 1998/09/14 21:52:57 art Exp $ */ +/* $OpenBSD: kernel.c,v 1.2 1999/04/30 01:59:08 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -38,7 +38,7 @@ */ #include "arla_local.h" -RCSID("$KTH: kernel.c,v 1.12 1998/07/13 19:19:02 assar Exp $"); +RCSID("$KTH: kernel.c,v 1.17 1998/12/06 20:48:40 lha Exp $"); /* * The fd we use to talk with the kernel on. @@ -54,26 +54,42 @@ static unsigned recv_count[20]; static unsigned recv_count_overflow; +/* + * Number of workers used and high + */ + +static unsigned long workers_high, workers_used; + + +unsigned long +kernel_highworkers(void) +{ + return workers_high; +} + +unsigned long +kernel_usedworkers(void) +{ + return workers_used; +} + +/* + * + */ + static int -process_message (int fd) +process_message (int msg_length, char *msg) { - static char data[MAX_XMSG_SIZE]; - int res; struct xfs_message_header *header; char *p; int cnt; - res = read (fd, data, sizeof (data)); - - if (res < 0) { - arla_warn (ADEBWARN, errno, "read"); - /* XXX process the errno? Are we supposed to exit on every error?*/ - return -1; - } cnt = 0; - for (p = data; res > 0; p += header->size, res -= header->size) { + for (p = msg; + msg_length > 0; + p += header->size, msg_length -= header->size) { header = (struct xfs_message_header *)p; - xfs_message_receive (fd, header, header->size); + xfs_message_receive (kernel_fd, header, header->size); ++cnt; } if (cnt < sizeof(recv_count)/sizeof(recv_count[0])) @@ -84,16 +100,66 @@ process_message (int fd) return 0; } +/* + * The work threads. + */ + +struct worker { + char data[MAX_XMSG_SIZE]; + PROCESS pid; + int msg_length; + int busyp; + int number; +} *workers; + +static void +sub_thread (void *v_myself) +{ + struct worker *self = (struct worker *)v_myself; + + for (;;) { + arla_warnx (ADEBKERNEL, "worker %d waiting", self->number); + LWP_WaitProcess (self); + self->busyp = 1; + ++workers_used; + arla_warnx (ADEBKERNEL, "worker %d: processing", self->number); + process_message (self->msg_length, self->data); + arla_warnx (ADEBKERNEL, "worker %d: done", self->number); + --workers_used; + self->busyp = 0; + } +} + +#define WORKER_STACKSIZE (16*1024) + void -kernel_interface (char *device) +kernel_interface (struct kernel_args *args) { int fd; + int i; - fd = open (device, O_RDWR); + fd = open (args->device, O_RDWR); if (fd < 0) - arla_err (1, ADEBERROR, errno, "open %s", device); + arla_err (1, ADEBERROR, errno, "open %s", args->device); kernel_fd = fd; + workers = malloc (sizeof(*workers) * args->num_workers); + if (workers == NULL) + arla_err (1, ADEBERROR, errno, "malloc %u failed", + sizeof(*workers) * args->num_workers); + + workers_high = args->num_workers; + workers_used = 0; + + for (i = 0; i < args->num_workers; ++i) { + workers[i].busyp = 0; + workers[i].number = i; + if (LWP_CreateProcess (sub_thread, WORKER_STACKSIZE, 1, + (char *)&workers[i], + "worker", &workers[i].pid)) + arla_errx (1, ADEBERROR, "CreateProcess of worker failed"); + } + arla_warnx(ADEBKERNEL, "Arla: selecting on fd: %d", fd); for (;;) { @@ -111,9 +177,21 @@ kernel_interface (char *device) arla_warnx (ADEBKERNEL, "Arla: select returned with 0. strange."); else if (FD_ISSET(fd, &readset)) { - - if (process_message (fd)) - arla_errx (1, ADEBKERNEL, "error processing message"); + for (i = 0; i < args->num_workers; ++i) { + if (workers[i].busyp == 0) { + ret = read (fd, workers[i].data, + sizeof(workers[i].data)); + if (ret <= 0) { + arla_warn (ADEBWARN, errno, "read"); + } else { + workers[i].msg_length = ret; + LWP_SignalProcess (&workers[i]); + } + break; + } + } + if (i == args->num_workers) + arla_warnx (ADEBWARN, "kernel: all workers busy"); } } } diff --git a/usr.sbin/afs/src/arlad/kernel.h b/usr.sbin/afs/src/arlad/kernel.h index 97de7190d50..4824fb4f254 100644 --- a/usr.sbin/afs/src/arlad/kernel.h +++ b/usr.sbin/afs/src/arlad/kernel.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kernel.h,v 1.1.1.1 1998/09/14 21:52:57 art Exp $ */ +/* $OpenBSD: kernel.h,v 1.2 1999/04/30 01:59:08 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,13 +37,25 @@ * SUCH DAMAGE. */ -/* $KTH: kernel.h,v 1.2 1998/02/19 05:48:20 assar Exp $ */ +/* $KTH: kernel.h,v 1.4 1998/12/06 20:49:11 lha Exp $ */ #ifndef _KERNEL_H_ #define _KERNEL_H_ -void kernel_interface (char *device); +struct kernel_args { + const char *device; + unsigned num_workers; +}; + +void kernel_interface (struct kernel_args *args); extern int kernel_fd; +unsigned long +kernel_highworkers(void); + +unsigned long +kernel_usedworkers(void); + + #endif /* _KERNEL_H_ */ diff --git a/usr.sbin/afs/src/arlad/messages.c b/usr.sbin/afs/src/arlad/messages.c index 9c185ed8b8b..5cb24e8db5a 100644 --- a/usr.sbin/afs/src/arlad/messages.c +++ b/usr.sbin/afs/src/arlad/messages.c @@ -1,6 +1,6 @@ -/* $OpenBSD: messages.c,v 1.1.1.1 1998/09/14 21:52:54 art Exp $ */ +/* $OpenBSD: messages.c,v 1.2 1999/04/30 01:59:09 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,17 +38,21 @@ */ #include "arla_local.h" -RCSID("$KTH: messages.c,v 1.79 1998/08/17 21:03:20 art Exp $"); +RCSID("$KTH: messages.c,v 1.126 1999/04/14 15:27:36 map Exp $"); #include <xfs/xfs_message.h> #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif -#include <kerberosIV/kafs.h> +#include <kafs.h> #include "messages.h" +/* XXX */ +int Log_is_open; +DARLA_file log_data; + static int xfs_message_wakeup (int, struct xfs_message_wakeup*, u_int); @@ -124,7 +128,9 @@ NULL, /* invalidnode */ (xfs_message_function)xfs_message_rmdir, /* rmdir */ (xfs_message_function)xfs_message_rename, /* rename */ (xfs_message_function)xfs_message_pioctl, /* pioctl */ -NULL /* wakeup_data */ +NULL, /* wakeup_data */ +NULL, /* updatefid */ +NULL /* advlock */ }; static u_int *seqnums; @@ -169,12 +175,18 @@ static char *rcvfuncs_name[] = "rename", "pioctl", "wakeup_data", + "updatefid", + "advlock" }; +/* + * + */ + long afsfid2inode (VenusFid *fid) { - return ((fid->fid.Volume & 0x7FFF) << 16 | (fid->fid.Vnode & 0xFFFFFFFF)); + return ((fid->fid.Volume & 0x7FFF) << 16 | (fid->fid.Vnode & 0xFFFFFFFF)); } /* @@ -209,9 +221,9 @@ afsstatus2xfs_attr (AFSFetchStatus *status, XA_SET_UID(attr,status->Owner); XA_SET_GID(attr, status->Group); attr->xa_mode |= status->UnixModeBits; - XA_SET_ATIME(attr, status->ServerModTime); - XA_SET_MTIME(attr, status->ServerModTime); - XA_SET_CTIME(attr, status->ServerModTime); + XA_SET_ATIME(attr, status->ClientModTime); + XA_SET_MTIME(attr, status->ClientModTime); + XA_SET_CTIME(attr, status->ClientModTime); XA_SET_FILEID(attr, afsfid2inode(fid)); } @@ -268,7 +280,7 @@ fcacheentry2xfsnode (VenusFid *fid, } } -static int +int xfs_attr2afsstorestatus(struct xfs_attr *xa, AFSStoreStatus *storestatus) { @@ -290,10 +302,10 @@ xfs_attr2afsstorestatus(struct xfs_attr *xa, storestatus->ClientModTime = xa->xa_mtime; mask |= SS_MODTIME; } - storestatus->Mask = mask ; + storestatus->Mask = mask; /* SS_SegSize */ - storestatus->SegSize = 0 ; + storestatus->SegSize = 0; return 0; } @@ -340,6 +352,10 @@ xfs_message_receive (int fd, struct xfs_message_header *h, u_int size) return (*rcvfuncs[opcode])(fd, h, size); } +/* + * + */ + static int xfs_message_send (int fd, struct xfs_message_header *h, u_int size) { @@ -384,7 +400,6 @@ xfs_message_wakeup (int fd, struct xfs_message_wakeup *h, u_int size) return 0; } -#ifdef notyet static int xfs_message_sleep (struct xfs_message_header *h) { @@ -393,7 +408,7 @@ xfs_message_sleep (struct xfs_message_header *h) return ((struct xfs_message_wakeup *)h)->error; } -static int +static int __attribute__ ((unused)) xfs_message_rpc (int fd, struct xfs_message_header *h, u_int size) { if (size < sizeof (struct xfs_message_wakeup)) { @@ -402,7 +417,6 @@ xfs_message_rpc (int fd, struct xfs_message_header *h, u_int size) } return xfs_message_send (fd, h, size) || xfs_message_sleep (h); } -#endif static int xfs_send_message_wakeup (int fd, u_int seqnum, int error) @@ -517,6 +531,67 @@ xfs_send_message_wakeup_data (int fd, u_int seqnum, int error, sizeof(msg)); } +/* + * Return true iff we should retry the operation. + * Magic with `ce' has to be done as well. + */ + +static int +try_again (int *ret, CredCacheEntry **ce, xfs_cred *cred, VenusFid *fid) +{ + switch (*ret) { +#ifdef KERBEROS + case RXKADEXPIRED : + cred_expire (*ce); + cred_free (*ce); + *ce = cred_get (0, cred->pag, CRED_ANY); + assert (*ce != NULL); + return TRUE; +#endif + case ARLA_VSALVAGE : + *ret = EIO; + return FALSE; + case ARLA_VNOVNODE : + *ret = ENOENT; + return FALSE; + case ARLA_VMOVED : + case ARLA_VNOVOL : + if (fid) { + volcache_invalidate (fid->fid.Volume, fid->Cell); + return TRUE; + } else { + *ret = ENOENT; + return FALSE; + } + case ARLA_VOFFLINE : + *ret = ENETDOWN; + return FALSE; + case ARLA_VDISKFULL : + *ret = ENOSPC; + return FALSE; + case ARLA_VOVERQUOTA: +#ifdef EDQUOT + *ret = EDQUOT; +#else + *ret = ENOSPC; +#endif + return FALSE; + case ARLA_VBUSY : + arla_warnx (ADEBWARN, "Waiting for busy volume..."); + IOMGR_Sleep (1); + return TRUE; + case ARLA_VRESTARTING: + arla_warnx (ADEBWARN, "Waiting fileserver to restart..."); + IOMGR_Sleep (1); + return TRUE; + case ARLA_VIO : + *ret = EIO; + return FALSE; + default : + return FALSE; + } +} + static int xfs_message_getroot (int fd, struct xfs_message_getroot *h, u_int size) { @@ -533,29 +608,23 @@ xfs_message_getroot (int fd, struct xfs_message_getroot *h, u_int size) ce = cred_get (0, h->cred.pag, CRED_ANY); assert (ce != NULL); + do { + ret = getroot (&root_fid, ce); - ret = getroot (&root_fid, ce); - if (ret) - goto out; - - result = cm_getattr(root_fid, &status, &real_fid, ce, &ae); - if (result.res == -1) { - ret = result.error; - goto out; - } - - fcacheentry2xfsnode (&root_fid, &real_fid, - &status, &msg.node, ae); + if (ret == 0) { + result = cm_getattr(root_fid, &status, &real_fid, ce, &ae); + if (result.res == -1) + ret = result.error; + } + } while (try_again (&ret, &ce, &h->cred, &root_fid)); - msg.header.opcode = XFS_MSG_INSTALLROOT; - h0 = (struct xfs_message_header *)&msg; - h0_len = sizeof(msg); + if (ret == 0) { + fcacheentry2xfsnode (&root_fid, &real_fid, + &status, &msg.node, ae); -out: - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_getroot (fd, h, size); + msg.header.opcode = XFS_MSG_INSTALLROOT; + h0 = (struct xfs_message_header *)&msg; + h0_len = sizeof(msg); } cred_free (ce); @@ -564,7 +633,7 @@ out: ret, h0, h0_len, NULL, 0); - return ret; + return 0; } static int @@ -580,37 +649,38 @@ xfs_message_getnode (int fd, struct xfs_message_getnode *h, u_int size) AccessEntry *ae; struct xfs_message_header *h0 = NULL; size_t h0_len = 0; + int ret; ce = cred_get (dirfid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - res = cm_lookup (*dirfid, h->name, &fid, &ce); - if (res.res == 0) { - res = cm_getattr (fid, &status, &real_fid, ce, &ae); - if (res.res == 0) { - fcacheentry2xfsnode (&fid, &real_fid, - &status, &msg.node, ae); - - msg.node.tokens = res.tokens & ~XFS_DATA_MASK; - msg.parent_handle = h->parent_handle; - strcpy (msg.name, h->name); - - msg.header.opcode = XFS_MSG_INSTALLNODE; - h0 = (struct xfs_message_header *)&msg; - h0_len = sizeof(msg); - } - } + do { + res = cm_lookup (*dirfid, h->name, &fid, &ce); + if (res.res == 0) + res = cm_getattr (fid, &status, &real_fid, ce, &ae); + + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, &fid)); - if (res.res != 0 && res.error == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_getnode (fd, h, size); + if (ret == 0) { + fcacheentry2xfsnode (&fid, &real_fid, &status, &msg.node, ae); + + msg.node.tokens = res.tokens; + msg.parent_handle = h->parent_handle; + strcpy (msg.name, h->name); + + msg.header.opcode = XFS_MSG_INSTALLNODE; + h0 = (struct xfs_message_header *)&msg; + h0_len = sizeof(msg); } cred_free (ce); xfs_send_message_wakeup_multiple (fd, h->header.sequence_num, - res.res == -1 ? res.error : res.res, + ret, h0, h0_len, NULL, 0); return 0; @@ -628,70 +698,95 @@ xfs_message_getattr (int fd, struct xfs_message_getattr *h, u_int size) AccessEntry *ae; struct xfs_message_header *h0 = NULL; size_t h0_len = 0; + int ret; fid = (VenusFid *)&h->handle; - ce = cred_get (fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - res = cm_getattr (*fid, &status, &real_fid, ce, &ae); - if (res.res == 0) { - fcacheentry2xfsnode (fid, &real_fid, - &status, &msg.node, ae); + do { + res = cm_getattr (*fid, &status, &real_fid, ce, &ae); + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, fid)); + + if (ret == 0) { + fcacheentry2xfsnode (fid, &real_fid, &status, &msg.node, ae); msg.node.tokens = res.tokens & ~XFS_DATA_MASK; + /* XXX - should not clear data mask if kernel already has data */ msg.header.opcode = XFS_MSG_INSTALLATTR; h0 = (struct xfs_message_header *)&msg; h0_len = sizeof(msg); } - if (res.res != 0 && res.error == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_getattr (fd, h, size); - } - cred_free (ce); xfs_send_message_wakeup_multiple (fd, h->header.sequence_num, - res.res ? res.error : res.res, + ret, h0, h0_len, NULL, 0); return 0; } - static int xfs_message_putattr (int fd, struct xfs_message_putattr *h, u_int size) { + struct xfs_message_installattr msg; VenusFid *fid; AFSStoreStatus status; + AFSFetchStatus fetch_status; Result res; CredCacheEntry *ce; + AccessEntry *ae; + VenusFid real_fid; + struct xfs_message_header *h0 = NULL; + size_t h0_len = 0; + int ret; fid = (VenusFid *)&h->handle; - + xfs_attr2afsstorestatus(&h->attr, &status); ce = cred_get (fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - xfs_attr2afsstorestatus(&h->attr, &status); - res.res = 0; - if (XA_VALID_SIZE(&h->attr)) - res = cm_ftruncate (*fid, h->attr.xa_size, ce); + do { + res.res = 0; + if (XA_VALID_SIZE(&h->attr)) + res = cm_ftruncate (*fid, h->attr.xa_size, ce); - if (res.res == 0) - res = cm_setattr(*fid, &status, ce); + if (res.res == 0) + res = cm_setattr(*fid, &status, ce); - if (res.res != 0 && res.error == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_putattr (fd, h, size); + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, fid)); + + if (ret == 0) { + res = cm_getattr (*fid, &fetch_status, &real_fid, ce, &ae); + if (res.res == 0) { + fcacheentry2xfsnode (fid, &real_fid, + &fetch_status, &msg.node, ae); + + msg.node.tokens = res.tokens & ~XFS_DATA_MASK; + msg.header.opcode = XFS_MSG_INSTALLATTR; + h0 = (struct xfs_message_header *)&msg; + h0_len = sizeof(msg); + } else { + ret = res.error; + } } cred_free (ce); - xfs_send_message_wakeup (fd, h->header.sequence_num, - res.res ? res.error : res.res); + xfs_send_message_wakeup_multiple (fd, + h->header.sequence_num, + ret, + h0, h0_len, + NULL, 0); return 0; } @@ -713,20 +808,25 @@ xfs_message_create (int fd, struct xfs_message_create *h, u_int size) size_t h1_len = 0; struct xfs_message_header *h2 = NULL; size_t h2_len = 0; + FCacheEntry *dir_entry; parent_fid = (VenusFid *)&h->parent_handle; - + xfs_attr2afsstorestatus(&h->attr, &store_status); ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - xfs_attr2afsstorestatus(&h->attr, &store_status); - res = cm_create(*parent_fid, h->name, &store_status, - &child_fid, &fetch_status, ce); + do { + res = cm_create(*parent_fid, h->name, &store_status, + &child_fid, &fetch_status, ce); + + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, parent_fid)); + if (res.res == 0) { - FCacheEntry *dir_entry; FCacheEntry *child_entry; - char tmp[5]; - VenusFid realfid; ret = fcache_get (&dir_entry, *parent_fid, ce); if (ret) @@ -734,29 +834,29 @@ xfs_message_create (int fd, struct xfs_message_create *h, u_int size) ret = fcache_get_data (dir_entry, ce); if (ret) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); goto out; } - res = conv_dir (dir_entry, tmp, sizeof(tmp), ce, 0); /* XXX */ + res = conv_dir (dir_entry, ce, 0, + &msg1.cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); if (res.res == -1) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); ret = res.error; goto out; } - strncpy((char *)&msg1.cache_handle, tmp, 4); - msg1.node.tokens = res.tokens; - if (dir_entry->flags.mountp) - realfid = dir_entry->realfid; - else - realfid = *parent_fid; + msg1.node.tokens = res.tokens; - fcacheentry2xfsnode (parent_fid, &realfid, + fcacheentry2xfsnode (parent_fid, + &dir_entry->realfid, &dir_entry->status, &msg1.node, dir_entry->acccache); - ReleaseWriteLock (&dir_entry->lock); + msg1.flag = 0; + fcache_release(dir_entry); ret = fcache_get (&child_entry, child_fid, ce); if (ret) @@ -764,12 +864,15 @@ xfs_message_create (int fd, struct xfs_message_create *h, u_int size) ret = fcache_get_data (child_entry, ce); if (ret) { - ReleaseWriteLock (&child_entry->lock); + fcache_release(child_entry); goto out; } - sprintf (tmp, "%04X", (unsigned)child_entry->inode); /* XXX */ - ReleaseWriteLock (&child_entry->lock); + msg3.cache_handle = child_entry->handle; + fcache_file_name (child_entry, + msg3.cache_name, sizeof(msg3.cache_name)); + msg3.flag = 0; + fcache_release(child_entry); msg1.header.opcode = XFS_MSG_INSTALLDATA; h0 = (struct xfs_message_header *)&msg1; @@ -788,20 +891,24 @@ xfs_message_create (int fd, struct xfs_message_create *h, u_int size) msg3.node = msg2.node; msg3.header.opcode = XFS_MSG_INSTALLDATA; - strncpy((char *)&msg3.cache_handle, tmp, 4); /* XXX */ + h2 = (struct xfs_message_header *)&msg3; h2_len = sizeof(msg3); } - if (res.res == -1) { - ret = res.error; - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_create (fd, h, size); - } - } else - ret = 0; + if (connected_mode != CONNECTED && res.res == 0) { + struct vcache log_ent_parent, log_ent_child; + + log_ent_parent.fid = *parent_fid; + log_ent_parent.DataVersion = dir_entry->status.DataVersion; + log_ent_parent.cred = h->cred; + + log_ent_child.fid = child_fid; + log_ent_child.DataVersion = 1; + + log_dis_create (&log_ent_parent, &log_ent_child, h->name); + } + out: cred_free (ce); xfs_send_message_wakeup_multiple (fd, @@ -826,10 +933,14 @@ xfs_message_mkdir (int fd, struct xfs_message_mkdir *h, u_int size) int ret; struct xfs_message_installdata msg1; struct xfs_message_installnode msg2; + struct xfs_message_installdata msg3; + struct xfs_message_header *h0 = NULL; size_t h0_len = 0; struct xfs_message_header *h1 = NULL; size_t h1_len = 0; + struct xfs_message_header *h2 = NULL; + size_t h2_len = 0; parent_fid = (VenusFid *)&h->parent_handle; @@ -837,12 +948,19 @@ xfs_message_mkdir (int fd, struct xfs_message_mkdir *h, u_int size) assert (ce != NULL); xfs_attr2afsstorestatus(&h->attr, &store_status); - res = cm_mkdir(*parent_fid, h->name, &store_status, - &child_fid, &fetch_status, ce); + + do { + res = cm_mkdir(*parent_fid, h->name, &store_status, + &child_fid, &fetch_status, ce); + if (res.res) + ret = res.error; + else + ret = res.res; + } while(try_again (&ret, &ce, &h->cred, parent_fid)); + if (res.res == 0) { FCacheEntry *dir_entry; - char tmp[5]; - VenusFid realfid; + FCacheEntry *child_entry; ret = fcache_get (&dir_entry, *parent_fid, ce); if (ret) @@ -850,55 +968,73 @@ xfs_message_mkdir (int fd, struct xfs_message_mkdir *h, u_int size) ret = fcache_get_data (dir_entry, ce); if (ret) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); goto out; } - res = conv_dir (dir_entry, tmp, sizeof(tmp), ce, 0); /* XXX */ + res = conv_dir (dir_entry, ce, 0, + &msg1.cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); if (res.res == -1) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); ret = res.error; goto out; } - strncpy((char *)&msg1.cache_handle, tmp, 4); msg1.node.tokens = res.tokens; - if (dir_entry->flags.mountp) - realfid = dir_entry->realfid; - else - realfid = *parent_fid; - - fcacheentry2xfsnode (parent_fid, &realfid, + fcacheentry2xfsnode (parent_fid, + &dir_entry->realfid, &dir_entry->status, &msg1.node, dir_entry->acccache); + msg1.flag = 0; msg1.header.opcode = XFS_MSG_INSTALLDATA; h0 = (struct xfs_message_header *)&msg1; h0_len = sizeof(msg1); - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); + + ret = fcache_get (&child_entry, child_fid, ce); + if (ret) + goto out; + + ret = fcache_get_data (child_entry, ce); + if (ret) { + fcache_release(child_entry); + goto out; + } + + res = conv_dir (child_entry, ce, 0, + &msg3.cache_handle, + msg3.cache_name, + sizeof(msg3.cache_name)); + if (res.res == -1) { + fcache_release(child_entry); + ret = res.error; + goto out; + } + msg3.flag = 0; + + msg2.node.tokens = res.tokens; fcacheentry2xfsnode (&child_fid, &child_fid, - &fetch_status, &msg2.node, + &child_entry->status, &msg2.node, dir_entry->acccache); - msg2.node.tokens = XFS_ATTR_R; /* XXX */ msg2.parent_handle = h->parent_handle; strcpy (msg2.name, h->name); msg2.header.opcode = XFS_MSG_INSTALLNODE; h1 = (struct xfs_message_header *)&msg2; h1_len = sizeof(msg2); + fcache_release(child_entry); + + msg3.header.opcode = XFS_MSG_INSTALLDATA; + msg3.node = msg2.node; + h2 = (struct xfs_message_header *)&msg3; + h2_len = sizeof(msg3); } - if (res.res == -1) { - ret = res.error; - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_mkdir (fd, h, size); - } - } else - ret = 0; out: cred_free (ce); xfs_send_message_wakeup_multiple (fd, @@ -906,6 +1042,7 @@ out: ret, h0, h0_len, h1, h1_len, + h2, h2_len, NULL, 0); return ret; @@ -932,12 +1069,17 @@ xfs_message_link (int fd, struct xfs_message_link *h, u_int size) ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - res = cm_link (*parent_fid, h->name, *existing_fid, - &fetch_status, ce); + do { + res = cm_link (*parent_fid, h->name, *existing_fid, + &fetch_status, ce); + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, parent_fid)); + if (res.res == 0) { FCacheEntry *dir_entry; - char tmp[5]; - VenusFid realfid; ret = fcache_get (&dir_entry, *parent_fid, ce); if (ret) @@ -945,32 +1087,31 @@ xfs_message_link (int fd, struct xfs_message_link *h, u_int size) ret = fcache_get_data (dir_entry, ce); if (ret) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); goto out; } - res = conv_dir (dir_entry, tmp, sizeof(tmp), ce, 0); /* XXX */ + res = conv_dir (dir_entry, ce, 0, + &msg1.cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); if (res.res == -1) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); ret = res.error; goto out; } - strncpy((char *)&msg1.cache_handle, tmp, 4); msg1.node.tokens = res.tokens; - if (dir_entry->flags.mountp) - realfid = dir_entry->realfid; - else - realfid = *parent_fid; - - fcacheentry2xfsnode (parent_fid, &realfid, + fcacheentry2xfsnode (parent_fid, + &dir_entry->realfid, &dir_entry->status, &msg1.node, dir_entry->acccache); + msg1.flag = 0; msg1.header.opcode = XFS_MSG_INSTALLDATA; h0 = (struct xfs_message_header *)&msg1; h0_len = sizeof(msg1); - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); fcacheentry2xfsnode (existing_fid, existing_fid, &fetch_status, &msg2.node, @@ -985,15 +1126,6 @@ xfs_message_link (int fd, struct xfs_message_link *h, u_int size) h1_len = sizeof(msg2); } - if (res.res == -1) { - ret = res.error; - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_link (fd, h, size); - } - } else - ret = 0; out: cred_free (ce); xfs_send_message_wakeup_multiple (fd, @@ -1028,13 +1160,20 @@ xfs_message_symlink (int fd, struct xfs_message_symlink *h, u_int size) assert (ce != NULL); xfs_attr2afsstorestatus(&h->attr, &store_status); - res = cm_symlink(*parent_fid, h->name, &store_status, - &child_fid, &fetch_status, - h->contents, ce); + + do { + res = cm_symlink(*parent_fid, h->name, &store_status, + &child_fid, &fetch_status, + h->contents, ce); + ret = res.error; + } while (try_again (&ret, &ce, &h->cred, parent_fid)); + + cred_free (ce); + ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + if (res.res == 0) { FCacheEntry *dir_entry; - char tmp[5]; - VenusFid realfid; ret = fcache_get (&dir_entry, *parent_fid, ce); if (ret) @@ -1042,32 +1181,31 @@ xfs_message_symlink (int fd, struct xfs_message_symlink *h, u_int size) ret = fcache_get_data (dir_entry, ce); if (ret) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); goto out; } - res = conv_dir (dir_entry, tmp, sizeof(tmp), ce, 0); /* XXX */ + res = conv_dir (dir_entry, ce, 0, + &msg1.cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); if (res.res == -1) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); ret = res.error; goto out; } - strncpy((char *)&msg1.cache_handle, tmp, 4); + msg1.flag = 0; msg1.node.tokens = res.tokens; - if (dir_entry->flags.mountp) - realfid = dir_entry->realfid; - else - realfid = *parent_fid; - - fcacheentry2xfsnode (parent_fid, &realfid, + fcacheentry2xfsnode (parent_fid, + &dir_entry->realfid, &dir_entry->status, &msg1.node, dir_entry->acccache); msg1.header.opcode = XFS_MSG_INSTALLDATA; h0 = (struct xfs_message_header *)&msg1; h0_len = sizeof(msg1); - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); fcacheentry2xfsnode (&child_fid, &child_fid, &fetch_status, &msg2.node, @@ -1082,15 +1220,6 @@ xfs_message_symlink (int fd, struct xfs_message_symlink *h, u_int size) h1_len = sizeof(msg2); } - if (res.res == -1) { - ret = res.error; - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_symlink (fd, h, size); - } - } else - ret = 0; out: cred_free (ce); xfs_send_message_wakeup_multiple (fd, @@ -1118,11 +1247,17 @@ xfs_message_remove (int fd, struct xfs_message_remove *h, u_int size) ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - res = cm_remove(*parent_fid, h->name, ce); + do { + res = cm_remove(*parent_fid, h->name, ce); + + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, parent_fid)); + if (res.res == 0) { FCacheEntry *dir_entry; - char tmp[5]; - VenusFid realfid; ret = fcache_get (&dir_entry, *parent_fid, ce); if (ret) @@ -1130,43 +1265,34 @@ xfs_message_remove (int fd, struct xfs_message_remove *h, u_int size) ret = fcache_get_data (dir_entry, ce); if (ret) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); goto out; } - res = conv_dir (dir_entry, tmp, sizeof(tmp), ce, 0); /* XXX */ + res = conv_dir (dir_entry, ce, 0, + &msg.cache_handle, + msg.cache_name, + sizeof(msg.cache_name)); if (res.res == -1) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); ret = res.error; goto out; } - strncpy((char *)&msg.cache_handle, tmp, 4); - msg.node.tokens = res.tokens; - if (dir_entry->flags.mountp) - realfid = dir_entry->realfid; - else - realfid = *parent_fid; + msg.flag = XFS_INVALID_DNLC; + msg.node.tokens = res.tokens; - fcacheentry2xfsnode (parent_fid, &realfid, + fcacheentry2xfsnode (parent_fid, + &dir_entry->realfid, &dir_entry->status, &msg.node, dir_entry->acccache); msg.header.opcode = XFS_MSG_INSTALLDATA; h0 = (struct xfs_message_header *)&msg; h0_len = sizeof(msg); - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); } - if (res.res == -1) { - ret = res.error; - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_remove (fd, h, size); - } - } else - ret = 0; out: cred_free (ce); xfs_send_message_wakeup_multiple (fd, @@ -1193,11 +1319,16 @@ xfs_message_rmdir (int fd, struct xfs_message_rmdir *h, u_int size) ce = cred_get (parent_fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - res = cm_rmdir(*parent_fid, h->name, ce); + do { + res = cm_rmdir(*parent_fid, h->name, ce); + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, parent_fid)); + if (res.res == 0) { FCacheEntry *dir_entry; - char tmp[5]; - VenusFid realfid; ret = fcache_get (&dir_entry, *parent_fid, ce); if (ret) @@ -1205,43 +1336,33 @@ xfs_message_rmdir (int fd, struct xfs_message_rmdir *h, u_int size) ret = fcache_get_data (dir_entry, ce); if (ret) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); goto out; } - res = conv_dir (dir_entry, tmp, sizeof(tmp), ce, 0); /* XXX */ + res = conv_dir (dir_entry, ce, 0, + &msg.cache_handle, + msg.cache_name, + sizeof(msg.cache_name)); if (res.res == -1) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); ret = res.error; goto out; } - strncpy((char *)&msg.cache_handle, tmp, 4); + msg.flag = XFS_INVALID_DNLC; msg.node.tokens = res.tokens; - if (dir_entry->flags.mountp) - realfid = dir_entry->realfid; - else - realfid = *parent_fid; - - fcacheentry2xfsnode (parent_fid, &realfid, + fcacheentry2xfsnode (parent_fid, + &dir_entry->realfid, &dir_entry->status, &msg.node, dir_entry->acccache); msg.header.opcode = XFS_MSG_INSTALLDATA; h0 = (struct xfs_message_header *)&msg; h0_len = sizeof(msg); - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); } - if (res.res == -1) { - ret = res.error; - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_rmdir (fd, h, size); - } - } else - ret = 0; out: cred_free (ce); xfs_send_message_wakeup_multiple (fd, @@ -1273,14 +1394,18 @@ xfs_message_rename (int fd, struct xfs_message_rename *h, u_int size) ce = cred_get (old_parent_fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - res = cm_rename(*old_parent_fid, h->old_name, - *new_parent_fid, h->new_name, - ce); + do { + res = cm_rename(*old_parent_fid, h->old_name, + *new_parent_fid, h->new_name, + ce); + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, old_parent_fid)); if (res.res == 0) { FCacheEntry *dir_entry; - char tmp[5]; - VenusFid realfid; ret = fcache_get (&dir_entry, *old_parent_fid, ce); if (ret) @@ -1288,78 +1413,67 @@ xfs_message_rename (int fd, struct xfs_message_rename *h, u_int size) ret = fcache_get_data (dir_entry, ce); if (ret) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); goto out; } - res = conv_dir (dir_entry, tmp, sizeof(tmp), ce, 0); /* XXX */ + res = conv_dir (dir_entry, ce, 0, + &msg1.cache_handle, + msg1.cache_name, + sizeof(msg1.cache_name)); if (res.res == -1) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); ret = res.error; goto out; } - strncpy((char *)&msg1.cache_handle, tmp, 4); + msg1.flag = XFS_INVALID_DNLC; msg1.node.tokens = res.tokens; - if (dir_entry->flags.mountp) - realfid = dir_entry->realfid; - else - realfid = *old_parent_fid; - - fcacheentry2xfsnode (old_parent_fid, &realfid, + fcacheentry2xfsnode (old_parent_fid, + &dir_entry->realfid, &dir_entry->status, &msg1.node, dir_entry->acccache); msg1.header.opcode = XFS_MSG_INSTALLDATA; h0 = (struct xfs_message_header *)&msg1; h0_len = sizeof(msg1); - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); /* new parent */ ret = fcache_get (&dir_entry, *new_parent_fid, ce); if (ret) goto out; - + ret = fcache_get_data (dir_entry, ce); if (ret) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); goto out; } - - res = conv_dir (dir_entry, tmp, sizeof(tmp), ce, 0); /* XXX */ + + res = conv_dir (dir_entry, ce, 0, + &msg2.cache_handle, + msg2.cache_name, + sizeof(msg2.cache_name)); if (res.res == -1) { - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); ret = res.error; goto out; } - strncpy((char *)&msg2.cache_handle, tmp, 4); + msg2.flag = XFS_INVALID_DNLC; msg2.node.tokens = res.tokens; - - if (dir_entry->flags.mountp) - realfid = dir_entry->realfid; - else - realfid = *new_parent_fid; - - fcacheentry2xfsnode (new_parent_fid, &realfid, + + fcacheentry2xfsnode (new_parent_fid, + &dir_entry->realfid, &dir_entry->status, &msg2.node, dir_entry->acccache); msg2.header.opcode = XFS_MSG_INSTALLDATA; h1 = (struct xfs_message_header *)&msg2; h1_len = sizeof(msg2); - ReleaseWriteLock (&dir_entry->lock); + fcache_release(dir_entry); } - if (res.res == -1) { - ret = res.error; - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_rename (fd, h, size); - } - } else - ret = 0; out: cred_free (ce); xfs_send_message_wakeup_multiple (fd, @@ -1378,22 +1492,25 @@ xfs_message_putdata (int fd, struct xfs_message_putdata *h, u_int size) VenusFid *fid; Result res; CredCacheEntry *ce; + int ret; + AFSStoreStatus status; fid = (VenusFid *)&h->handle; + xfs_attr2afsstorestatus(&h->attr, &status); ce = cred_get (fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - res = cm_close(*fid, h->flag, ce); - if (res.res != 0) - arla_warn (ADEBMSG, res.error, "xfs_message_putdata: cm_close"); - - if (res.res != 0 && res.error == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_putdata (fd, h, size); - } - + do { + res = cm_close(*fid, h->flag, &status, ce); + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, fid)); + + if (ret) + arla_warn (ADEBMSG, ret, "xfs_message_putdata: cm_close"); cred_free (ce); xfs_send_message_wakeup (fd, h->header.sequence_num, @@ -1409,7 +1526,6 @@ xfs_message_getdata (int fd, struct xfs_message_getdata *h, u_int size) VenusFid real_fid; Result res; AFSFetchStatus status; - char tmp[5]; CredCacheEntry *ce; int ret; AccessEntry *ae; @@ -1421,7 +1537,14 @@ xfs_message_getdata (int fd, struct xfs_message_getdata *h, u_int size) ce = cred_get (fid->Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - res = cm_getattr (*fid, &status, &real_fid, ce, &ae); + do { + res = cm_getattr (*fid, &status, &real_fid, ce, &ae); + if (res.res) + ret = res.error; + else + ret = res.res; + } while (try_again (&ret, &ce, &h->cred, fid)); + if (res.res == 0) { fcacheentry2xfsnode (fid, &real_fid, &status, &msg.node, ae); if (status.FileType == TYPE_DIR) { @@ -1433,23 +1556,24 @@ xfs_message_getdata (int fd, struct xfs_message_getdata *h, u_int size) ret = fcache_get_data (entry, ce); if (ret) { - ReleaseWriteLock (&entry->lock); + fcache_release(entry); goto out; } - res = conv_dir (entry, tmp, sizeof(tmp), ce, h->tokens); + res = conv_dir (entry, ce, h->tokens, + &msg.cache_handle, + msg.cache_name, + sizeof(msg.cache_name)); if (res.res != -1) { - strncpy ((char *)&msg.cache_handle, tmp, 4); /* XXX */ - msg.node.tokens = res.tokens; + msg.node.tokens = res.tokens; + msg.flag = XFS_INVALID_DNLC; } - ReleaseWriteLock(&entry->lock); + fcache_release(entry); } else { - res = cm_open (*fid, ce, h->tokens); - if (res.res != -1) { - sprintf (tmp, "%04X", res.res); /* XXX */ - strncpy ((char *)&msg.cache_handle, tmp, 4); /* XXX */ - msg.node.tokens = res.tokens; - } + res = cm_open (*fid, ce, h->tokens, &msg.cache_handle, + msg.cache_name, sizeof(msg.cache_name)); + if (res.res != -1) + msg.node.tokens = res.tokens; } } @@ -1458,21 +1582,12 @@ xfs_message_getdata (int fd, struct xfs_message_getdata *h, u_int size) h0 = (struct xfs_message_header *)&msg; h0_len = sizeof(msg); } - if (res.res == -1) { - ret = res.error; - if (ret == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return xfs_message_getdata (fd, h, size); - } - } else - ret = 0; out: cred_free (ce); xfs_send_message_wakeup_multiple (fd, h->header.sequence_num, - ret, + res.res ? res.error : res.res, h0, h0_len, NULL, 0); @@ -1486,10 +1601,42 @@ break_callback (VenusFid fid) msg.header.opcode = XFS_MSG_INVALIDNODE; memcpy (&msg.handle, &fid, sizeof(fid)); - xfs_message_send (kernel_fd , (struct xfs_message_header *)&msg, + xfs_message_send (kernel_fd, (struct xfs_message_header *)&msg, + sizeof(msg)); +} + +/* + * Send an unsolicited install-attr for the node in `e' + */ + +void +install_attr (FCacheEntry *e) +{ + struct xfs_message_installattr msg; + + msg.header.opcode = XFS_MSG_INSTALLATTR; + fcacheentry2xfsnode (&e->fid, &e->realfid, &e->status, &msg.node, + e->acccache); + msg.node.tokens = e->tokens; + if (!e->flags.datausedp) + msg.node.tokens &= ~XFS_DATA_MASK; + + xfs_message_send (kernel_fd, (struct xfs_message_header *)&msg, sizeof(msg)); } +void +update_kernelfid(VenusFid oldfid, VenusFid newfid) +{ + struct xfs_message_updatefid msg; + + msg.header.opcode = XFS_MSG_UPDATEFID; + memcpy (&msg.old_handle, &oldfid, sizeof(oldfid)); + memcpy (&msg.new_handle, &newfid, sizeof(newfid)); + xfs_message_send (kernel_fd, (struct xfs_message_header *)&msg, + sizeof(msg)); +} + static int xfs_message_inactivenode (int fd, struct xfs_message_inactivenode *h, u_int size) @@ -1512,14 +1659,26 @@ xfs_message_inactivenode (int fd, struct xfs_message_inactivenode *h, return 0; } if (h->flag & XFS_NOREFS) - entry->flags.datausedp = entry->flags.attrusedp = FALSE; + fcache_unused (entry); if (h->flag & XFS_DELETE) entry->flags.kernelp = FALSE; - ReleaseWriteLock (&entry->lock); + fcache_release(entry); return 0; } +/* + * Do we have powers for changing stuff? + */ +static Bool +all_powerful_p (const xfs_cred *cred) +{ + return cred->uid == 0; +} + +/* + * Flush the contents of a volume + */ static int viocflushvolume (int fd, struct xfs_message_pioctl *h, u_int size) @@ -1539,6 +1698,7 @@ viocflushvolume (int fd, struct xfs_message_pioctl *h, u_int size) fid.Cell, fid.fid.Volume); fcache_purge_volume(fid); + volcache_invalidate (fid.fid.Volume, fid.Cell); return 0 ; } @@ -1565,13 +1725,11 @@ viocgetacl(int fd, struct xfs_message_pioctl *h, u_int size) ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); assert (ce != NULL); - error = getacl (fid, ce, &opaque); + do { + error = getacl (fid, ce, &opaque); + } while (try_again (&error, &ce, &h->cred, &fid)); - if (error == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return viocgetacl (fd, h, size); - } else if (error != 0 && error != EACCES) + if (error != 0 && error != EACCES) error = EINVAL; cred_free (ce); @@ -1614,13 +1772,11 @@ viocsetacl(int fd, struct xfs_message_pioctl *h, u_int size) opaque.len=h->insize; memcpy(opaque.val, h->msg, h->insize); - error = setacl (fid, ce, &opaque); + do { + error = setacl (fid, ce, &opaque); + } while (try_again (&error, &ce, &h->cred, &fid)); - if (error == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return viocsetacl (fd, h, size); - } else if (error != 0 && error != EACCES) + if (error != 0 && error != EACCES) error = EINVAL; cred_free (ce); @@ -1664,16 +1820,14 @@ viocgetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) memset (motd, 0, AFSOPAQUEMAX); memset (out, 0, SYSNAMEMAXLEN); - error = getvolstat (fid, ce, &volstat, volumename, - offlinemsg, motd); + do { + error = getvolstat (fid, ce, &volstat, volumename, + offlinemsg, motd); + } while (try_again (&error, &ce, &h->cred, &fid)); cred_free (ce); - if (error == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return viocgetvolstat (fd, h, size); - } else if (error != 0 && error != EACCES) + if (error != 0 && error != EACCES) error = EINVAL; memcpy (out, (char *) &volstat, sizeof (AFSFetchVolumeStatus)); @@ -1746,6 +1900,7 @@ viocsetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) ptr = h->msg + sizeof (AFSFetchVolumeStatus); +#if 0 if (*ptr) { strncpy (volumename, ptr, AFSNAMEMAX); ptr += strlen (ptr); @@ -1765,15 +1920,18 @@ viocsetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) } strncpy (motd, ptr, AFSOPAQUEMAX); +#else + volumename[0] = '\0'; + offlinemsg[0] = '\0'; + motd[0] = '\0'; +#endif - error = setvolstat (fid, ce, &outvolstat, volumename, - offlinemsg, motd); + do { + error = setvolstat (fid, ce, &outvolstat, volumename, + offlinemsg, motd); + } while (try_again (&error, &ce, &h->cred, &fid)); - if (error == RXKADEXPIRED) { - cred_expire (ce); - cred_free (ce); - return viocsetvolstat (fd, h, size); - } else if (error != 0 && error != EACCES) + if (error != 0 && error != EACCES) error = EINVAL; cred_free (ce); @@ -1784,89 +1942,150 @@ viocsetvolstat(int fd, struct xfs_message_pioctl *h, u_int size) } /* - * Get info for a mount point. + * Get the mount point from (fid, filename) and return in `fbuf'. + * Return 0 or error. */ static int -vioc_afs_stat_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) +read_mount_point (VenusFid fid, const char *filename, fbuf *the_fbuf, + CredCacheEntry *ce, + FCacheEntry **ret_mp_entry) { - VenusFid fid; - VenusFid res; - CredCacheEntry *ce; - FCacheEntry *e; - fbuf the_fbuf; - char *buf; + FCacheEntry *mp_entry; + VenusFid mp_fid; int error; - int symlink_fd; + int mp_fd; + char *buf; - if (!h->handle.a && !h->handle.b && !h->handle.c && !h->handle.d) + if (fid.fid.Volume == 0 && fid.fid.Vnode == 0 && fid.fid.Unique == 0) return EINVAL; - fid.Cell = h->handle.a; - fid.fid.Volume = h->handle.b; - fid.fid.Vnode = h->handle.c; - fid.fid.Unique = h->handle.d; - - ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); - assert (ce != NULL); - - error = adir_lookup(fid, h->msg, &res, ce); + error = adir_lookup(fid, filename, &mp_fid, ce); if (error) { - cred_free(ce); return error; } - error = fcache_get(&e, res, ce); + + error = fcache_get(&mp_entry, mp_fid, ce); if (error) { - cred_free(ce); return error; } - error = fcache_get_attr (e, ce); + + error = fcache_get_attr (mp_entry, ce); if (error) { - ReleaseWriteLock (&e->lock); - cred_free(ce); + fcache_release(mp_entry); return error; } - if (e->status.FileType != TYPE_LINK) { /* Is not a mount point */ - ReleaseWriteLock (&e->lock); - cred_free(ce); + if (mp_entry->status.FileType != TYPE_LINK) { /* Is not a mount point */ + fcache_release(mp_entry); return EINVAL; } - error = fcache_get_data (e, ce); + error = fcache_get_data (mp_entry, ce); if (error) { - ReleaseWriteLock (&e->lock); - cred_free(ce); + fcache_release(mp_entry); return error; } - symlink_fd = fcache_open_file (e, O_RDONLY, 0); - if (symlink_fd < 0) { - ReleaseWriteLock (&e->lock); - cred_free(ce); + mp_fd = fcache_open_file (mp_entry, O_RDONLY); + if (mp_fd < 0) { + fcache_release(mp_entry); return errno; } - error = fbuf_create (&the_fbuf, symlink_fd, e->status.Length, FBUF_READ); + error = fbuf_create (the_fbuf, mp_fd, mp_entry->status.Length, + FBUF_READ); if (error) { - ReleaseWriteLock (&e->lock); - cred_free(ce); + fcache_release(mp_entry); return error; } - buf = (char *)(the_fbuf.buf); + buf = (char *)(the_fbuf->buf); if (buf[0] != '#' && buf[0] != '%') { /* Is not a mount point */ - ReleaseWriteLock (&e->lock); - fbuf_end (&the_fbuf); - cred_free (ce); + fbuf_end (the_fbuf); + fcache_release(mp_entry); return EINVAL; } + if(ret_mp_entry) + *ret_mp_entry = mp_entry; + else { + fbuf_end (the_fbuf); + fcache_release (mp_entry); + } + return 0; +} + +/* + * Get info for a mount point. + */ + +static int +vioc_afs_stat_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) +{ + VenusFid fid; + int error; + fbuf the_fbuf; + CredCacheEntry *ce; + FCacheEntry *e; + + fid.Cell = h->handle.a; + fid.fid.Volume = h->handle.b; + fid.fid.Vnode = h->handle.c; + fid.fid.Unique = h->handle.d; + + h->msg[min(h->insize, sizeof(h->msg)-1)] = '\0'; + + ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + error = read_mount_point (fid, h->msg, &the_fbuf, ce, &e); + if (error) { + cred_free(ce); + return error; + } + xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, the_fbuf.buf, the_fbuf.len - 1); - - ReleaseWriteLock (&e->lock); fbuf_end (&the_fbuf); cred_free (ce); - + fcache_release (e); return 0; } +/* + * Handle the VIOC_AFS_DELETE_MT_PT message in `h' by deleting the + * mountpoint. + */ + +static int +vioc_afs_delete_mt_pt(int fd, struct xfs_message_pioctl *h, u_int size) +{ + VenusFid fid; + int error = 0; + fbuf the_fbuf; + CredCacheEntry *ce; + struct xfs_message_remove remove_msg; + + h->msg[min(h->insize, sizeof(h->msg)-1)] = '\0'; + + fid.Cell = h->handle.a; + fid.fid.Volume = h->handle.b; + fid.fid.Vnode = h->handle.c; + fid.fid.Unique = h->handle.d; + + ce = cred_get (fid.Cell, h->cred.pag, CRED_ANY); + assert (ce != NULL); + + error = read_mount_point (fid, h->msg, &the_fbuf, ce, NULL); + cred_free (ce); + if (error) + return error; + + remove_msg.header = h->header; + remove_msg.header.size = sizeof(remove_msg); + remove_msg.parent_handle = h->handle; + strcpy(remove_msg.name, h->msg); + remove_msg.cred = h->cred; + + return xfs_message_remove (fd, &remove_msg, sizeof(remove_msg)); +} + static int viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) { @@ -1895,7 +2114,7 @@ viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) } error = fcache_get_attr (e, ce); if (error) { - ReleaseWriteLock (&e->lock); + fcache_release(e); cred_free(ce); return error; } @@ -1906,14 +2125,18 @@ viocwhereis(int fd, struct xfs_message_pioctl *h, u_int size) xfs_send_message_wakeup_data (fd, h->header.sequence_num, error, addresses, sizeof(long) * 8); - ReleaseWriteLock (&e->lock); + fcache_release(e); cred_free (ce); return 0; } +/* + * Return all db servers for a particular cell. + */ + static int -viocgetcell(int fd, struct xfs_message_pioctl *h, u_int size) +vioc_get_cell(int fd, struct xfs_message_pioctl *h, u_int size) { int i; int32_t index; @@ -1921,22 +2144,26 @@ viocgetcell(int fd, struct xfs_message_pioctl *h, u_int size) int cellname_len; int outsize; char out[8 * sizeof(int32_t) + MAXPATHLEN]; /* XXX */ + const cell_db_entry *dbservers; + int num_dbservers; index = *((int32_t *) h->msg); cellname = cell_num2name(index); if (cellname == NULL) - return EDOM; + return xfs_send_message_wakeup (fd, h->header.sequence_num, EDOM); + dbservers = cell_dbservers (index, &num_dbservers); + + if (dbservers == NULL) + return xfs_send_message_wakeup (fd, h->header.sequence_num, EDOM); + memset(out, 0, sizeof(out)); - cellname_len = strlen(cellname) + 1; - if (cellname_len > MAXPATHLEN) - cellname_len = MAXPATHLEN; + cellname_len = min(strlen(cellname), MAXPATHLEN - 1); memcpy(out + 8 * sizeof(int32_t), cellname, cellname_len); - outsize = 8 * sizeof(int32_t) + cellname_len; - for (i = 0; i < 8; i++) { - u_long addr = cell_listdbserver(index, i); - if (addr == 0) - break; + out[8 * sizeof(int32_t) + cellname_len] = '\0'; + outsize = 8 * sizeof(int32_t) + cellname_len + 1; + for (i = 0; i < min(num_dbservers, 8); ++i) { + u_int32_t addr = dbservers[i].addr.s_addr; memcpy (&out[i * sizeof(int32_t)], &addr, sizeof(int32_t)); } @@ -1946,6 +2173,124 @@ viocgetcell(int fd, struct xfs_message_pioctl *h, u_int size) return 0; } +/* + * Return status information about a cell. + */ + +static int +vioc_get_cellstatus(int fd, struct xfs_message_pioctl *h, u_int size) +{ + char *cellname; + int32_t cellid; + u_int32_t out = 0; + + cellname = h->msg; + cellname[h->insize-1] = '\0'; + + cellid = cell_name2num (cellname); + if (cellid == -1) + return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); + + if (cellid == 0) + out |= CELLSTATUS_PRIMARY; + if (cell_issuid_by_num (cellid)) + out |= CELLSTATUS_SETUID; + + xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + &out, sizeof(out)); + + return 0; +} + +/* + * Set status information about a cell. + */ + +static int +vioc_set_cellstatus(int fd, struct xfs_message_pioctl *h, u_int size) +{ + int32_t cellid; + char *cellname; + u_int32_t in = 0; + int ret; + + if (!all_powerful_p (&h->cred)) + return xfs_send_message_wakeup (fd, h->header.sequence_num, EACCES); + + if (h->insize < sizeof (in) + 2) /* terminating NUL and one char */ + return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + + cellname = h->msg + sizeof (in); + cellname[h->insize-1-sizeof(in)] = '\0'; + + cellid = cell_name2num (cellname); + if (cellid == -1) + return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); + + if (in & CELLSTATUS_SETUID) { + ret = cell_setsuid_by_num (cellid); + if (ret) + return xfs_send_message_wakeup (fd, h->header.sequence_num,EINVAL); + } + + xfs_send_message_wakeup (fd, h->header.sequence_num, 0); + + return 0; +} + +/* + * Set information about a cell or add a new one. + */ + +static int +vioc_new_cell(int fd, struct xfs_message_pioctl *h, u_int size) +{ + const char *cellname; + cell_entry *ce; + int count, i; + u_int32_t *hp; + cell_db_entry *dbs; + + if (!all_powerful_p (&h->cred)) + return xfs_send_message_wakeup (fd, h->header.sequence_num, EPERM); + + if (h->insize < 9) + return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + + hp = (u_int32_t *)h->msg; + for (count = 0; *hp != 0; ++hp) + ++count; + + dbs = malloc (count * sizeof(*dbs)); + if (dbs == NULL) + return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOMEM); + + hp = (u_int32_t *)h->msg; + for (i = 0; i < count; ++i) { + dbs[i].name = NULL; + dbs[i].addr.s_addr = hp[i]; + } + + cellname = h->msg + 8 * sizeof(u_int32_t); + ce = cell_get_by_name (cellname); + if (ce == NULL) { + ce = cell_new (cellname); + + if (ce == NULL) { + free (dbs); + return xfs_send_message_wakeup (fd, h->header.sequence_num, + ENOMEM); + } + } else { + free (ce->dbservers); + } + + ce->ndbservers = count; + ce->dbservers = dbs; + + return xfs_send_message_wakeup (fd, h->header.sequence_num, 0); +} + #ifdef KERBEROS /* @@ -1967,7 +2312,7 @@ token_for_cell (int fd, struct xfs_message_pioctl *h, u_int size, ct.AuthHandle = cred->kvno; memcpy (ct.HandShakeKey, cred->session, sizeof(cred->session)); - ct.ViceId = h->cred.pag; + ct.ViceId = h->cred.uid; ct.BeginTimestamp = cred->issue_date + 1; ct.EndTimestamp = ce->expire; @@ -2046,8 +2391,79 @@ viocgettok (int fd, struct xfs_message_pioctl *h, u_int size) } return 0; } + +/* + * Handle the SETTOK message in `h' + */ + +static int +viocsettok (int fd, struct xfs_message_pioctl *h, u_int size) +{ + struct ClearToken ct; + CREDENTIALS c; + long cell; + int32_t sizeof_x; + char *t = h->msg; + + /* someone probed us */ + if (h->insize == 0) { + return EINVAL; + } + + /* Get ticket_st */ + memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; + c.ticket_st.length = sizeof_x ; + arla_warnx (ADEBMSG, "ticket_st has size %d", sizeof_x); + t += sizeof(sizeof_x) ; + + memcpy(c.ticket_st.dat, t, sizeof_x) ; + t += sizeof_x ; + + /* Get ClearToken */ + memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; + t += sizeof(sizeof_x) ; + + memcpy(&ct, t, sizeof_x) ; + t += sizeof_x ; + + /* Get primary cell ? */ + memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; + t += sizeof(sizeof_x) ; + + /* Get Cellname */ + strncpy(c.realm, t, REALM_SZ) ; + c.realm[REALM_SZ-1] = '\0' ; + + /* Make this a sane world again */ + c.kvno = ct.AuthHandle; + memcpy (c.session, ct.HandShakeKey, sizeof(c.session)); + c.issue_date = ct.BeginTimestamp - 1; + + cell = cell_name2num(strlwr(c.realm)); + + conn_clearcred (cell, h->cred.pag, 2); + fcache_purge_cred(h->cred.pag, cell); + cred_add (h->cred.pag, CRED_KRB4, 2, cell, ct.EndTimestamp, + &c, sizeof(c), ct.ViceId); + return 0; +} + +static int +viocunlog (int fd, struct xfs_message_pioctl *h, u_int size) +{ + pag_t cred = h->cred.pag; + + cred_remove(cred); + fcache_purge_cred(cred, -1); + return 0; +} + #endif /* KERBEROS */ +/* + * Flush the fid in `h->handle' from the cache. + */ + static int viocflush (int fd, struct xfs_message_pioctl *h, u_int size) { @@ -2057,9 +2473,9 @@ viocflush (int fd, struct xfs_message_pioctl *h, u_int size) if (!h->handle.a && !h->handle.b && !h->handle.c && !h->handle.d) return EINVAL; - fid.Cell = h->handle.a; + fid.Cell = h->handle.a; fid.fid.Volume = h->handle.b; - fid.fid.Vnode = h->handle.c; + fid.fid.Vnode = h->handle.c; fid.fid.Unique = h->handle.d; arla_warnx(ADEBMSG, @@ -2102,12 +2518,30 @@ viocconnect(int fd, struct xfs_message_pioctl *h, u_int size) } break; case CONNMODE_CONN: + if (Log_is_open) { + DARLA_Close(&log_data); + Log_is_open = 0; + + do_replay(ARLACACHEDIR"/discon_log", + log_data.log_entries, 0); + } + if (connected_mode == DISCONNECTED) { + connected_mode = CONNECTED ; + fcache_reobtain_callbacks (); + } connected_mode = CONNECTED ; break; case CONNMODE_FETCH: connected_mode = FETCH_ONLY ; break; case CONNMODE_DISCONN: + ret = DARLA_Open(&log_data, ARLACACHEDIR"/discon_log", + O_WRONLY | O_CREAT | O_BINARY); + if (ret < 0) { + arla_warn (ADEBERROR, errno, "DARLA_Open"); + } else { + Log_is_open = 1; + } connected_mode = DISCONNECTED; break; default: @@ -2121,7 +2555,7 @@ viocconnect(int fd, struct xfs_message_pioctl *h, u_int size) return 0; } -static void +static int getrxkcrypt(int fd, struct xfs_message_pioctl *h, u_int size) { if (h->outsize == sizeof(u_int32_t)) { @@ -2134,13 +2568,13 @@ getrxkcrypt(int fd, struct xfs_message_pioctl *h, u_int size) #endif n = 0; - xfs_send_message_wakeup_data (fd, - h->header.sequence_num, - 0, - &n, - sizeof(n)); + return xfs_send_message_wakeup_data (fd, + h->header.sequence_num, + 0, + &n, + sizeof(n)); } else - xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); } static int @@ -2246,79 +2680,250 @@ vioc_fpriostatus (int fd, struct xfs_message_pioctl *h, u_int size) } static int -xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) +viocgetfid (int fd, struct xfs_message_pioctl *h, u_int size) { - int32_t sizeof_x; - char *t; - int error; + return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + &h->handle, sizeof(VenusFid)); +} - t = h->msg ; - switch(h->opcode) { -#ifdef KERBEROS - case VIOCSETTOK: { - struct ClearToken ct; - CREDENTIALS c; - long cell; - - /* someone probed us */ - if (h->insize == 0) { - error = EINVAL ; - break; - } +static int +viocvenuslog (int fd, struct xfs_message_pioctl *h, u_int size) +{ + if (!all_powerful_p(&h->cred)) + return EPERM; + + conn_status (); + volcache_status (); + cred_status (); + fcache_status (); + fprio_status (); +#ifdef RXDEBUG + rx_PrintStats(stderr); +#endif + return 0; +} + +/* + * Set or get the sysname + */ - /* Get ticket_st */ - memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; - c.ticket_st.length = sizeof_x ; - arla_warnx (ADEBMSG, "ticket_st has size %d", sizeof_x); - t += sizeof(sizeof_x) ; +static int +vioc_afs_sysname (int fd, struct xfs_message_pioctl *h, u_int size) +{ + char *t = h->msg; + int32_t parm = *((int32_t *)t); + + if (parm) { + if (!all_powerful_p (&h->cred)) + return xfs_send_message_wakeup (fd, + h->header.sequence_num, + EPERM); + t += sizeof(int32_t); + arla_warnx (ADEBMSG, "VIOC_AFS_SYSNAME: setting sysname: %s", t); + memcpy(arlasysname, t, h->insize); + arlasysname[h->insize] = '\0'; + return xfs_send_message_wakeup(fd, h->header.sequence_num, 0); + } else { + char *buf; + size_t sysname_len = strlen (arlasysname); + int ret; + + buf = malloc (sysname_len + 4 + 1); + if (buf == NULL) + return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOMEM); + *((u_int32 *)buf) = sysname_len; + memcpy (buf + 4, arlasysname, sysname_len); + buf[sysname_len + 4] = '\0'; + + ret = xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + buf, sysname_len + 5); + free (buf); + return ret; + } +} - memcpy(c.ticket_st.dat, t, sizeof_x) ; - t += sizeof_x ; +static int +viocfilecellname (int fd, struct xfs_message_pioctl *h, u_int size) +{ + char *cellname; - /* Get ClearToken */ - memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; - t += sizeof(sizeof_x) ; + cellname = (char *) cell_num2name(h->handle.a); - memcpy(&ct, t, sizeof_x) ; - t += sizeof_x ; + if (cellname) + return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + cellname, strlen(cellname)+1); + else + return xfs_send_message_wakeup_data(fd, h->header.sequence_num, EINVAL, + NULL, 0); +} - /* Get primary cell ? */ - memcpy(&sizeof_x, t, sizeof(sizeof_x)) ; - t += sizeof(sizeof_x) ; +static int +viocgetwscell (int fd, struct xfs_message_pioctl *h, u_int size) +{ + char *cellname; - /* Get Cellname */ - strncpy(c.realm, t, REALM_SZ) ; - c.realm[REALM_SZ-1] = '\0' ; + cellname = (char*) cell_getthiscell(); + return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + cellname, strlen(cellname)+1); +} +static int +viocsetcachesize (int fd, struct xfs_message_pioctl *h, u_int size) +{ + u_int32_t *s = (u_int32_t *)h->msg; - /* Make this a sane world again */ - c.kvno = ct.AuthHandle; - memcpy (c.session, ct.HandShakeKey, sizeof(c.session)); - c.issue_date = ct.BeginTimestamp - 1; + if (!all_powerful_p (&h->cred)) + return EPERM; - cell = cell_name2num(strlwr(c.realm)); + if (h->insize >= sizeof(int32_t) * 4) + return fcache_reinit(s[0], s[1], s[2], s[3]); + else + return fcache_reinit(*s/2, *s, *s*500, *s*1000); +} - /* XXX fix ct.ViceId */ - conn_clearcred (cell, h->cred.pag, 2); - fcache_purge_cred(h->cred.pag, cell); - cred_add (h->cred.pag, CRED_KRB4, 2, cell, ct.EndTimestamp, - &c, sizeof(c)); - +/* + * VIOCCKSERV + * + * in: flags - bitmask (1 - dont ping, use cached data, 2 - check fsservers only) + * cell - string (optional) + * out: hosts - u_int32_t number of hosts, followed by list of hosts being down. + */ - error = 0 ; - break; +static int +viocckserv (int fd, struct xfs_message_pioctl *h, u_int size) +{ + int32_t cell = 0; /* Default local cell */ + int flags = 0; + int num_entries; + u_int32_t hosts[CKSERV_MAXSERVERS + 1]; + int msg_size; + + if (h->insize < sizeof(int32_t)) + return xfs_send_message_wakeup (fd, h->header.sequence_num, EINVAL); + + memset (hosts, 0, sizeof(hosts)); + + flags = *(u_int32_t *)h->msg; + flags &= CKSERV_DONTPING|CKSERV_FSONLY; + + if (h->insize > sizeof(int32_t)) { + h->msg[min(h->insize, sizeof(h->msg)-1)] = '\0'; + + cell = cell_name2num (((char *)h->msg) + sizeof(int32_t)); + if (cell == -1) + return xfs_send_message_wakeup (fd, h->header.sequence_num, ENOENT); } + + num_entries = CKSERV_MAXSERVERS; + + conn_downhosts(cell, hosts + 1, &num_entries, flags); + + hosts[0] = num_entries; + msg_size = sizeof(hosts[0]) * (num_entries + 1); + return xfs_send_message_wakeup_data (fd, h->header.sequence_num, 0, + hosts, msg_size); +} + + +/* + * Return the number of used KBs and reserved KBs + */ + +static int +viocgetcacheparms (int fd, struct xfs_message_pioctl *h, u_int size) +{ + u_int32_t parms[16]; + + memset(parms, 0, sizeof(parms)); + parms[0] = fcache_highbytes() / 1024; + parms[1] = fcache_usedbytes() / 1024; + parms[2] = fcache_highvnodes(); + parms[3] = fcache_usedvnodes(); + + h->outsize = sizeof(parms); + return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + parms, sizeof(parms)); +} + +/* + * debugging interface to give out statistics of the cache + */ + +static int +viocaviator (int fd, struct xfs_message_pioctl *h, u_int size) +{ + u_int32_t parms[16]; + + memset(parms, 0, sizeof(parms)); + parms[0] = kernel_highworkers(); + parms[1] = kernel_usedworkers(); + + h->outsize = sizeof(parms); + return xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, + parms, sizeof(parms)); +} + +/* + * Get/set arla debug level + */ + +static int +vioc_arladebug (int fd, struct xfs_message_pioctl *h, u_int size) +{ + if (h->insize != 0) { + if (h->insize < sizeof(int32_t)) + return xfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); + if (!all_powerful_p (&h->cred)) + return xfs_send_message_wakeup (fd, h->header.sequence_num, + EPERM); + arla_log_set_level_num (*((int32_t *)h->msg)); + } + if (h->outsize != 0) { + int32_t debug_level; + + if (h->outsize < sizeof(int32_t)) + return xfs_send_message_wakeup (fd, h->header.sequence_num, + EINVAL); + + debug_level = arla_log_get_level_num (); + return xfs_send_message_wakeup_data (fd, h->header.sequence_num, + 0, &debug_level, + sizeof(debug_level)); + } + return xfs_send_message_wakeup (fd, h->header.sequence_num, 0); +} + +/* + * GC pags --- there shouldn't be any need to do anything here. + */ + +static int +vioc_gcpags (int fd, struct xfs_message_pioctl *h, u_int size) +{ + return 0; +} + +/* + * Handle a pioctl message in `h' + */ + +static int +xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) +{ + int error; + + switch(h->opcode) { +#ifdef KERBEROS + case VIOCSETTOK: + error = viocsettok (fd, h, size); + break; case VIOCGETTOK : return viocgettok (fd, h, size); case VIOCUNPAG: - case VIOCUNLOG: { - pag_t cred = h->cred.pag ; - - cred_remove(cred) ; - fcache_purge_cred(cred, -1); - error = 0; - break ; - } + case VIOCUNLOG: + error = viocunlog (fd, h, size); + break; #endif /* KERBEROS */ case VIOCCONNECTMODE: error = viocconnect(fd, h, size); @@ -2330,9 +2935,7 @@ xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) error = viocflushvolume(fd, h, size); break; case VIOCGETFID: - error = xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0, - &h->handle, sizeof(VenusFid)); - break; + return viocgetfid (fd, h, size); case VIOCGETAL: error = viocgetacl(fd, h, size); break; @@ -2348,6 +2951,9 @@ xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) case VIOC_AFS_STAT_MT_PT: error = vioc_afs_stat_mt_pt(fd, h, size); break; + case VIOC_AFS_DELETE_MT_PT: + error = vioc_afs_delete_mt_pt(fd, h, size); + break; case VIOCWHEREIS: error = viocwhereis(fd, h, size); break; @@ -2355,92 +2961,44 @@ xfs_message_pioctl (int fd, struct xfs_message_pioctl *h, u_int size) error = EINVAL; break; case VIOCGETCELL: - error = viocgetcell(fd, h, size); - break; + return vioc_get_cell(fd, h, size); + case VIOC_GETCELLSTATUS: + return vioc_get_cellstatus(fd, h, size); + case VIOC_SETCELLSTATUS: + return vioc_set_cellstatus(fd, h, size); + case VIOCNEWCELL: + return vioc_new_cell(fd, h, size); case VIOC_VENUSLOG: - if (h->cred.uid != 0) { - error = EACCES; - break ; - } - - conn_status (stderr); - volcache_status (stderr); - cred_status (stderr); - fcache_status (stderr); - rx_PrintStats(stderr); - error = 0 ; + error = viocvenuslog (fd, h, size); break; - case VIOC_AFS_SYSNAME: { - char str[SYSNAMEMAXLEN+sizeof(int32_t)]; - - error = 0 ; - - if (*((int32_t *)t)) { - t += sizeof(int32_t); - arla_warnx (ADEBMSG, "VIOC_AFS_SYSNAME: setting sysname: %s", t); - memcpy(arlasysname, t, h->insize); - arlasysname[h->insize] = '\0'; - xfs_send_message_wakeup_data(fd, h->header.sequence_num, error, - str, 0); - } else { - t = str; - sizeof_x = strlen(arlasysname); - memcpy(t, &sizeof_x, sizeof(sizeof_x)); - t += sizeof(sizeof_x); - h->outsize = sizeof_x; - strncpy(t, arlasysname, SYSNAMEMAXLEN); - xfs_send_message_wakeup_data(fd, h->header.sequence_num, error, - str, sizeof_x + sizeof(sizeof_x)); - } - return 0; - } - - case VIOC_FILE_CELL_NAME: { - char *cellname ; - - error = 0 ; - cellname = (char *) cell_num2name(h->handle.a); - - if (cellname) - xfs_send_message_wakeup_data(fd, h->header.sequence_num, error, - cellname, strlen(cellname)+1); - else - xfs_send_message_wakeup_data(fd, h->header.sequence_num, EINVAL, - NULL, 0); - return 0; - } - case VIOC_GET_WS_CELL: { - char *cellname; - - cellname = (char*) cell_getthiscell(); - xfs_send_message_wakeup_data(fd, h->header.sequence_num, 0 /*error*/, - cellname, strlen(cellname)); - - return 0; - } - case VIOCSETCACHESIZE: { - u_int32_t *s = (u_int32_t *)t; - - if (h->cred.uid != 0) { - error = EPERM; - break ; - } - - if (h->insize >= sizeof(int32_t) * 4) - error = fcache_reinit(s[0], s[1], s[2], s[3]); - else - error = fcache_reinit(*s/2, *s, *s*500, *s*1000); + case VIOC_AFS_SYSNAME: + return vioc_afs_sysname (fd, h, size); + case VIOC_FILE_CELL_NAME: + return viocfilecellname (fd, h, size); + case VIOC_GET_WS_CELL: + return viocgetwscell (fd, h, size); + case VIOCSETCACHESIZE: + error = viocsetcachesize (fd, h, size); break; - } + case VIOCCKSERV: + return viocckserv (fd, h, size); + case VIOCGETCACHEPARAMS: + return viocgetcacheparms (fd, h, size); case VIOC_GETRXKCRYPT : - getrxkcrypt(fd, h, size); - return 0; + return getrxkcrypt(fd, h, size); case VIOC_SETRXKCRYPT : error = setrxkcrypt(fd, h, size); break; case VIOC_FPRIOSTATUS: error = vioc_fpriostatus(fd, h, size); break; + case VIOC_AVIATOR: + return viocaviator (fd, h, size); + case VIOC_ARLADEBUG : + return vioc_arladebug (fd, h, size); + case VIOC_GCPAGS : + error = vioc_gcpags (fd, h, size); + break; default: arla_warnx (ADEBMSG, "unknown pioctl call %d", h->opcode); error = EINVAL ; diff --git a/usr.sbin/afs/src/arlad/messages.h b/usr.sbin/afs/src/arlad/messages.h index 0d210c93d94..4e55a431658 100644 --- a/usr.sbin/afs/src/arlad/messages.h +++ b/usr.sbin/afs/src/arlad/messages.h @@ -1,4 +1,4 @@ -/* $OpenBSD: messages.h,v 1.1.1.1 1998/09/14 21:52:57 art Exp $ */ +/* $OpenBSD: messages.h,v 1.2 1999/04/30 01:59:10 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * */ -/* $KTH: messages.h,v 1.5 1998/03/25 03:27:20 assar Exp $ */ +/* $KTH: messages.h,v 1.8 1998/12/02 16:53:41 lha Exp $ */ #ifndef _MESSAGES_H_ #define _MESSAGES_H_ @@ -49,6 +49,15 @@ void xfs_message_init (void); int xfs_message_receive (int fd, struct xfs_message_header *h, u_int size); void break_callback (VenusFid fid); +void install_attr (FCacheEntry *e); + long afsfid2inode(VenusFid *fid); +int +xfs_attr2afsstorestatus(struct xfs_attr *xa, + AFSStoreStatus *storestatus); + +void +update_kernelfid(VenusFid oldfid, VenusFid newfid); + #endif /* _MESSAGES_H_ */ diff --git a/usr.sbin/afs/src/arlad/reconnect.c b/usr.sbin/afs/src/arlad/reconnect.c new file mode 100644 index 00000000000..bebb4b82e41 --- /dev/null +++ b/usr.sbin/afs/src/arlad/reconnect.c @@ -0,0 +1,2172 @@ +/* $OpenBSD: reconnect.c,v 1.1 1999/04/30 01:59:10 art Exp $ */ +/* COPYRIGHT (C) 1998 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS + * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS + * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF + * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY + * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE + * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE + * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE + * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY + * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST + * ALSO BE INCLUDED. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +/* + * Do merging of the files that changed with we was in disconnected mode + */ + +#include "arla_local.h" + +RCSID("$KTH: reconnect.c,v 1.11 1999/02/15 04:49:43 art Exp $"); + +static int reconnect_nonmute(struct vcache *, int, struct timeval); +static int reconnect_putattr(struct vcache *, struct xfs_attr *); +static int reconnect_putdata(struct vcache *); +static int reconnect_remove(struct vcache *, FCacheEntry *childentry, char *); +static int reconnect_rename(struct vcache *, struct vcache *, char *, char *); +static int reconnect_rmdir(struct vcache *vcp, FCacheEntry *childEntry, + char *name); +static int reconnect_mkdir(struct vcache *parent, struct vcache *curdir, + AFSStoreStatus *store_status, char *name); +static int reconnect_link(struct vcache *parent, struct vcache *existing, + char *name); +static int reconnect_symlink(struct vcache *parent, struct vcache *child, + AFSStoreStatus *store_attr, char *name, + char *contents); +static int reconnect_create(struct vcache *parent, struct vcache *child, + char *name); +static int reconnect_mut_chk(FCacheEntry *fce, CredCacheEntry *ce, + int version); + +static int check_log_todo(log_ent_t * , VenusFid *, VenusFid *); +static int is_done_before(int no); +static void add_done_list(int no); +static void clear_log_entry(void); +static void clear_index_list(void); + +typedef struct _fid_trans{ + VenusFid logged_fid; + VenusFid fetched_fid; + struct _fid_trans *next, *prev; +} fid_trans; + +typedef struct _fid_keep{ + char name[MAX_NAME]; + AFSFid kept_fid; + struct _fid_keep *next; +} fid_keep; + +typedef struct _index_list{ + int index; + struct _index_list * next; +} index_list; + +fid_trans *fid_AD_head, *fid_AD_tail; +fid_keep *fid_KP_head; +index_list * index_head; +extern log_ent_t log_head; + + +/* + * + */ + +static void +set_fid_value(VenusFid *new, VenusFid *old) +{ + if(old==0) { + new->fid.Volume = 0; + new->fid.Vnode = 0; + new->fid.Unique = 0; + } else { + new->fid.Volume = old->fid.Volume; + new->fid.Vnode = old->fid.Vnode; + new->fid.Unique = old->fid.Unique; + } +} + +/* + * + */ + +void +do_replay(char *log_file, int log_entries, VenusFid *changed_fid) +{ + int fd, len, i; + log_ent_t *cur_log; + struct vcache vc, vc_new; + char *name, *name_new; + fid_trans *fid_tmp; + fid_keep * fid_KP_tail; + VenusFid new_fid; + + int count=1; /* Used to record how may actions we have done*/ + + fid_AD_tail = fid_AD_head; + cur_log = (log_ent_t *) malloc(sizeof(log_ent_t)); + fd = open(log_file, O_RDONLY | O_BINARY); + + set_fid_value(&new_fid , 0); + + while (read(fd, cur_log, sizeof(int))){ + + if (cur_log->log_len < sizeof(*cur_log) - sizeof(cur_log->log_data) || + cur_log->log_len > sizeof(log_ent_t)) { + arla_log(ADEBDISCONN, "do_replay: corrupt log entry, log_len %d", + cur_log->log_len); + goto terminate; + } + + len = cur_log->log_len - sizeof(int); + + if (!read(fd, ((char *)cur_log + sizeof(int)), len)){ + arla_log(ADEBDISCONN, "do_replay: read bad log entry..."); + goto terminate; + } + + arla_log(ADEBDISCONN, + "do_replay: read %d bytes of log entry.", + cur_log->log_len); + + if (is_done_before(cur_log->log_index)==1) + continue; /* the log entry has been executed */ + else { + if (changed_fid !=0) { + int is_log_todo = 0; + + is_log_todo = check_log_todo(cur_log, changed_fid, &new_fid); + if (is_log_todo ==0) + continue; /* This log should not be executed */ + } + } + + add_done_list(cur_log->log_index); + + /* big case/switch statement to switch log_op */ + switch (cur_log->log_op){ + + case DIS_STORE: + vc.fid = cur_log->st_fid; + vc.DataVersion = cur_log->st_origdv-1; + vc.flag = cur_log->st_flag; + vc.cred = cur_log->cred; + arla_log(ADEBDISCONN, + "%d action is to do_replay: **replay** (putdata) op...", + count++); + reconnect_putdata(&vc); + break; + case DIS_SETATTR: + vc.fid = cur_log->sa_fid; + vc.DataVersion = cur_log->sa_origdv; + vc.flag = 0; + vc.cred = cur_log->cred; + arla_log(ADEBDISCONN, + "%d action is to do_replay: **replay** (putattr) op...", + count++); + reconnect_putattr(&vc, &(cur_log->sa_vattr)); + break; + case DIS_REMOVE: { + FCacheEntry *childentry; + vc.fid = cur_log->rm_filefid; + vc.DataVersion = cur_log->rm_origdv; + vc.flag = 0; + vc.cred = cur_log->cred; + childentry = cur_log->rm_chentry; + name = cur_log->rm_name; + arla_log(ADEBDISCONN, + "%d action is to do_replay: **replay** " + "(file remove) op...", + count++); + reconnect_remove(&vc, childentry, name); + break; + } + case DIS_RMDIR: { + FCacheEntry *child; + vc.fid = cur_log->rd_parentfid; + name = cur_log->rd_name; + vc.cred = cur_log->cred; + child = cur_log->rd_direntry; + arla_log (ADEBDISCONN, + "%d action is to do_replay: **rmdir** " + "(directory remove) op...", + count++); + reconnect_rmdir(&vc, child, name); + break; + } + case DIS_RENAME: + vc.fid = cur_log->rn_oparentfid; + vc.DataVersion = cur_log->rn_origdv; + vc.flag = 0; + vc.cred = cur_log->cred; + vc_new.fid = cur_log->rn_nparentfid; + vc_new.DataVersion = cur_log->rn_overdv; + vc_new.flag = 0; + vc_new.cred = cur_log->cred; + name = cur_log->rn_names; + for (i=0; *(name+i)!='\0';++i); + name_new = name+i+1; + arla_log(ADEBDISCONN, + "%d action is to do_replay: **replay** (rename) op...", + count++); + reconnect_rename(&vc, &vc_new, name, name_new); + break; + case DIS_MKDIR: { + AFSStoreStatus store_status; + vc.fid = cur_log->md_parentfid; + vc.cred = cur_log->cred; + store_status = cur_log->md_vattr; + vc_new.fid = cur_log->md_dirfid; + /*Ba Wu: child's data vers*/ + vc_new.DataVersion = cur_log->md_dversion; + name = cur_log->md_name; + arla_log(ADEBDISCONN, + "%d action is to DO_Replay: **replay** (mkdir) op...", + count++); + reconnect_mkdir(&vc, &vc_new, &store_status, name); + break; + } + case DIS_LINK: + vc.cred = cur_log->cred; + vc.fid = cur_log->ln_parentfid; + vc_new.fid = cur_log->ln_linkfid; + name = cur_log->ln_name; + arla_log(ADEBDISCONN, + "%d action is to do_replay: **replay** (link) op...", + count++); + reconnect_link(&vc, &vc_new, name); + break; + case DIS_SYMLINK: { + char *new_name; + AFSStoreStatus store_attr; + + vc.fid = cur_log->sy_parentfid; + vc.cred = cur_log->cred; + name = cur_log->sy_name; + new_name = cur_log->sy_content; + vc_new.fid = cur_log->sy_filefid; + store_attr = cur_log->sy_attr; + arla_log(ADEBDISCONN, + "%d action is to do_replay: **replay** (symlink) op...", + count++); + reconnect_symlink(&vc, &vc_new, &store_attr, name, new_name); + break; + } + case DIS_CREATE: + vc.fid = cur_log->cr_parentfid; + vc.cred = cur_log->cred; + + vc_new.fid = cur_log->cr_filefid; + vc_new.DataVersion = cur_log->cr_origdv; + arla_log(ADEBDISCONN, + "%d action is to DO_Replay: **replay** (create) op...", + count++); + name = cur_log->cr_name; + reconnect_create(&vc, &vc_new, name); + break; + case DIS_ACCESS: + vc.fid = cur_log->nm_fid; + vc.DataVersion = cur_log->nm_origdv; + vc.cred = cur_log->cred; + arla_log(ADEBDISCONN, + "%d action is to do_replay: **replay** (nonmutating) op", + count++); + reconnect_nonmute(&vc, cur_log->log_op, cur_log->log_time); + break; + + default: + arla_log(ADEBDISCONN, + "%d action is to do_replay: skipping the current op=%d", + count++,cur_log->log_op); + } + } + + if (changed_fid ==0) { + clear_index_list(); /* clean all index when after discon */ + clear_log_entry(); + /* clean up, remove all associative data structures */ + fid_AD_tail = fid_AD_head; + while(fid_AD_tail) + { + fid_tmp = fid_AD_tail->next; + free(fid_AD_tail); + fid_AD_tail = fid_tmp; + } + /* SWW Qiyue 28: We need to reset head to 0*/ + fid_AD_head = 0; + fid_KP_tail = fid_KP_head; + while(fid_KP_tail) + { + fid_keep *fid_tmp; + + fid_tmp = fid_KP_tail->next; + free(fid_KP_tail); + fid_KP_tail = fid_tmp; + } + + fid_KP_head = 0; + } + terminate: + + arla_warnx (ADEBDISCONN,"We have done total %d replays",count-1); + close(fd); + free(cur_log); + return; +} + +/* + * + */ + +static int +check_rm_fid (VenusFid v1, VenusFid v2) +{ + if(v1.fid.Vnode == v2.fid.Vnode && + v1.fid.Volume == v2.fid.Volume && + v1.fid.Unique == v2.fid.Unique ) + return 1; + else + return 0; +} + +/* + * + */ + +static int +check_log_fid(struct vcache vc, VenusFid *fid) +{ + log_ent_t *temp = log_head.next; + + if (vc.fid.fid.Vnode == fid->fid.Vnode && + vc.fid.fid.Volume == fid->fid.Volume && + vc.fid.fid.Unique == fid->fid.Unique) + return 1; + + while (temp!=0) { + switch(temp->log_op) { + case DIS_RENAME: + if (check_rm_fid(temp->rn_oparentfid,*fid)==1) + return 1; + default: + temp = temp->next; + break; + } + } + return 0; +} + +/* + * + */ + +static int +check_log_todo(log_ent_t * cur_log , VenusFid *fid, VenusFid *newfid) +{ + VenusFid *lookfid; + struct vcache vc, vc_new; + int will_do = 0; + + if (newfid->fid.Vnode ==0 && + newfid->fid.Volume == 0 && + newfid->fid.Unique ==0) + lookfid = fid; + else + lookfid = newfid; /* For create and putdata */ + + switch (cur_log->log_op){ + case DIS_STORE: + vc.fid = cur_log->st_fid; + will_do = check_log_fid(vc, lookfid); + if (will_do==1) { + set_fid_value(newfid, 0); + return 1; + } + break; + case DIS_SETATTR: + vc.fid = cur_log->sa_fid; + will_do = check_log_fid(vc, lookfid); + if (will_do==1) { + set_fid_value(newfid , &cur_log->sa_fid); + return 1; + } + break; + case DIS_REMOVE: + vc.fid = cur_log->rm_filefid; + will_do = check_log_fid(vc, lookfid); + if (will_do==1) { + return 1; + } + break; + case DIS_RMDIR: + vc.fid = cur_log->rd_parentfid; + will_do = check_log_fid(vc, lookfid); + if (will_do==1) { + return 1; + } + break; + case DIS_RENAME: + vc.fid = cur_log->rn_oparentfid; + will_do = check_log_fid(vc, lookfid); + if (will_do==1) { + return 1; + } + vc_new.fid = cur_log->rn_nparentfid; + will_do = check_log_fid(vc_new, lookfid); + if (will_do==1) { + return 1; + } + break; + case DIS_MKDIR: + vc.fid = cur_log->md_parentfid; + will_do = check_log_fid(vc, lookfid); + if (will_do==1) { + return 1; + } + break; + case DIS_LINK: + break; + case DIS_SYMLINK: + will_do = check_log_fid(vc, lookfid); + if (will_do==1) { + return 1; + } + break; + case DIS_CREATE: + vc.fid = cur_log->cr_parentfid; + will_do = check_log_fid(vc, lookfid); + if (will_do==1) { + set_fid_value(newfid , &cur_log->cr_filefid); + return 1; + } + break; + case DIS_FSYNC: + case DIS_ACCESS: + case DIS_READDIR: + case DIS_READLINK: + case DIS_INFO: + case DIS_START_OPT: + case DIS_END_OPT: + case DIS_REPLAYED: + /* A no op */ + break; + } + return 0; +} + + +#if 0 + +/* + * + */ + +void +keepfid_newrename(char *name, + AFSFid fid) +{ + if (fid_KP_head == 0) { + fid_KP_head = (fid_keep *)malloc(sizeof(fid_keep)); + assert(fid_KP_head); + + strcpy(fid_KP_head->name, name); + fid_KP_head->kept_fid = fid; + fid_KP_head->next = 0; + } + else { + fid_keep *temp; + + temp = (fid_keep *)malloc(sizeof(fid_keep)); + assert(temp); + + strcpy(temp->name, name); + temp->name[strlen(name)] = '\0'; + temp->kept_fid = fid; + temp->next = fid_KP_head->next; + fid_KP_head->next = temp; + } +} + +#endif + +/* + * + */ + +static int +find_venus (char *name, VenusFid *fid) +{ + fid_keep *fid_temp; + + if(fid_KP_head == 0 ) + return 1; /*error */ + + fid_temp = fid_KP_head; + + while(fid_temp) { + if (strcmp(fid_temp->name,name) == 0) { + fid->fid.Volume = fid_temp->kept_fid.Volume; + fid->fid.Vnode = fid_temp->kept_fid.Vnode; + fid->fid.Unique = fid_temp->kept_fid.Unique; + return 0; + } + fid_temp = fid_temp->next; + } + arla_warnx (ADEBDISCONN, "find_venus: *PANIC* not found fid for %s", name); + return 1; +} + + +/* + * + */ + +static VenusFid * +fid_translate(VenusFid *fid_in) +{ + fid_trans *fid_tmp; + VenusFid *fid_ret; + + if (!fid_AD_head) + return fid_in; + + fid_tmp = fid_AD_head; + + while(fid_tmp){ + + fid_ret=&fid_tmp->logged_fid; + + if ((fid_ret->Cell == fid_in->Cell) && + (fid_ret->fid.Volume == fid_in->fid.Volume) && + (fid_ret->fid.Vnode == fid_in->fid.Vnode) && + (fid_ret->fid.Unique == fid_in->fid.Unique)) + return &fid_tmp->fetched_fid; + + fid_tmp = fid_tmp->next; + } + return fid_in; +} + +/* + * + */ + +static void +clear_index_list(void) +{ + index_list *temp=index_head; + + while(temp!=0) { + index_list *tmp; + + tmp = temp->next; + free(temp); + temp = tmp; + } + index_head = 0; +} + +/* + * + */ + +static void +clear_log_entry(void) +{ + log_ent_t *temp=log_head.next; + + while(temp!=0) { + log_ent_t *tmp; + + tmp = temp->next; + free(temp); + temp = tmp; + } + log_head.next = 0; +} + +/* + * + */ + +static int +is_done_before(int no) +{ + index_list * temp = index_head; + + while(temp !=0) { + if (temp->index == no) + return 1; + else + temp = temp->next; + } + return 0; +} + +/* + * + */ + +static void +add_done_list(int no) +{ + if (!index_head) { + index_head = (index_list *)malloc(sizeof(index_list)); + assert(index_head); + index_head->index = no; + index_head->next = 0; + } else { + index_list * temp; + temp = (index_list *) malloc(sizeof(index_list)); + assert(temp); + temp->next = index_head->next; + index_head->next = temp; + temp->index = no; + } +} + +/* + * + */ + +static void +alloc_fid_trans(VenusFid *logged_fid) +{ + if (!fid_AD_head) + { + /*SWW Qiyue 28 Make sure we have the memory*/ + fid_AD_head = (fid_trans *) malloc(sizeof(fid_trans)); + assert(fid_AD_head); + + fid_AD_head->prev=fid_AD_head->next = 0; + fid_AD_tail = fid_AD_head; + fid_AD_tail->logged_fid = *logged_fid; + + } else{ + + /*SWW Qiyue 28 Make sure we have the memory*/ + fid_AD_tail->next = (fid_trans *) malloc(sizeof(fid_trans)); + assert(fid_AD_tail->next); + + fid_AD_tail->next->prev = fid_AD_tail; + fid_AD_tail->next->next = 0; + fid_AD_tail = fid_AD_tail->next; /*Ba ba: move tail ahead */ + fid_AD_tail->logged_fid = *logged_fid; + } +} + +/* + * + */ + +static void +fill_fid_trans (VenusFid *fetched_fid) +{ + fid_AD_tail->fetched_fid = *fetched_fid; +} + +/* + * + */ + +#if 0 +void +update_entry_flag (FCacheEntry *entry) +{ + entry->flags.attrp = FALSE; + entry->flags.datap = FALSE; +} +#endif + +/* + * + */ + +int reconnect_nonmute(struct vcache *vcp, int op, struct timeval log_time) +{ + FCacheEntry *fce, fce_fetched; + CredCacheEntry *ce; + int error; + VenusFid *fid; +#if 0 + ConnCacheEntry *conn; +#endif + + arla_warnx (ADEBDISCONN, + "Start of reconnect_nonmute by sww"); /*SWW Qiyue 25*/ + + fid = &(vcp->fid); + if (fid->Cell == -1) /* newly created file, skip reconnect */ + return 0; + + error = fcache_find(&fce, *fid); + /* assert(fce); */ + if (error) /* nonmute op on nonexisting data */ + { + arla_log(ADEBDISCONN, + "reconnect: nonmute op %d performed on cache " + "entry no longer exist locally!", + op); + return -1; + } + + arla_log(ADEBDISCONN, + "reconnect: DISCONNECTED nonmute " + "on fid.Cell=0x%x, fid.fid.Volume= 0x%x, fid.fid.Vnode=0x%x, " + "fid.fid.Unique=0x%x", fid->Cell, + fid->fid.Volume, + fid->fid.Vnode, + fid->fid.Unique); + + ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); + assert (ce != NULL); + error = 0; + + /* setting some stuff so do_read_attr would work */ + fce->flags.attrp = TRUE; + fce->callback.CallBackType = 2; + fce_fetched = *fce; + /*conn = findconn (fce, ce);*/ + + error = read_attr(&fce_fetched, ce); + + arla_log(ADEBDISCONN, + "reconnect: logged DataVersion=%d, " + "fetched DataVersion=%d", + vcp->DataVersion, + fce_fetched.status.DataVersion); + + if (vcp->DataVersion < fce_fetched.status.DataVersion) + { + if (log_time.tv_usec >= fce_fetched.status.ServerModTime) + arla_log(ADEBDISCONN, + "Warning: nonmutating operation %d read stale data!", + op); + else if (log_time.tv_usec <= fce_fetched.status.ServerModTime && + (vcp->DataVersion +1) == fce_fetched.status.DataVersion) + arla_log(ADEBDISCONN, + "Notice: file modified once after nonmutating " + "operation %d.", + op); + else + arla_log(ADEBDISCONN, + "Warning: nonmutating operation %d might have read " + "stale data!", op); + } + + ReleaseWriteLock(&fce->lock); + cred_free(ce); + /*conn_free(conn);*/ + + return error; +} + +/* + * + */ + +int reconnect_remove(struct vcache *vcp, FCacheEntry *childentry, char *name) +{ + FCacheEntry *fce; + CredCacheEntry *ce; + int error; + VenusFid *fid, tempfid; /* Ba san: to check the deletion of file*/ + Result res; + int isupdate; + + ConnCacheEntry *conn; + fs_server_context context; + AFSFetchStatus status; + AFSVolSync volsync; + char tmp[5]; + xfs_cache_handle cache_handle; + + fid = &(vcp->fid); /* points to the VenusFid structure */ + fid = fid_translate(fid); + + arla_log(ADEBDISCONN, "reconnect: DISCONNECTED remove on " + "fid.Cell=0x%x, fid.fid. Volume= 0x%x, fid.fid.Vnode=0x%x, " + "fid.fid.Unique=0x%x", + fid->Cell, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique); + + /* ObtainWriteLock called in fcache_find */ + error = fcache_find(&fce, *fid); + assert (error == 0); + + ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); + assert (ce != NULL); + + if (connected_mode != CONNMODE_PARCONNECTED) { + ObtainWriteLock(&childentry->lock); + isupdate = reconnect_mut_chk(childentry, ce, + childentry->status.DataVersion); + ReleaseWriteLock(&childentry->lock); + + if (isupdate) + { + xfs_cache_handle cache_handle; + + arla_log(ADEBDISCONN, + "reconnect_remove: can't remove because file modified!"); + cred_free(ce); + adir_creat (fce, name, childentry->fid.fid); + childentry->flags.attrp = FALSE; + ReleaseWriteLock(&fce->lock); + conv_dir (fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); + ReleaseWriteLock(&fce->lock); + return -1; + } + } /* Ba ershi: we dont need to do it in parconn */ + + res.res = 0; + + assert (CheckLock(&fce->lock) == -1); + + conn = find_first_fs (fce, ce, &context); + +/* Ba san: check the file exists + + ReleaseWriteLock(&fce->lock); + error = adir_lookup(fce->fid, name, &tempfid, ce); + assert (error == 0); + ObtainWriteLock(&fce->lock); */ + + res.res = RXAFS_RemoveFile (conn->connection, + &fce->fid.fid, + name, + &status, + &volsync); + if (res.res) { + arla_log (ADEBDISCONN, "Could not RemoveFile: %s (%d)", + koerr_gettext(res.res), res.res); + goto out; + } + + arla_warnx (ADEBDISCONN,"In reconnect_remove: Remove the file %s",name); + +/* Ba san: Chcek the deletion of the file */ + ReleaseWriteLock(&fce->lock); + error = adir_lookup(fce->fid, name, &tempfid, ce); + ObtainWriteLock(&fce->lock); + + if (error == 0) { + int result; + + arla_warnx (ADEBDISCONN, + "In reconnect_remove: file %s needs to be deleted", + name); + result = adir_remove (fce,name); + assert ( result == 0); + } /* This is for the file produced during disconnect mode, + if error==ENOENT then the file is created during connect mode*/ + + + fce->status = status; + fce->volsync = volsync; + childentry->host = 0; /* Ba shiliu dont get callback */ + + volcache_update_volsync (fce->volume, fce->volsync); + conv_dir (fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); + + out: + + cred_free(ce); + free_fs_server_context(&context); + ReleaseWriteLock(&fce->lock); + return error; +} + +/* + * + */ + +int +reconnect_rmdir(struct vcache *vcp, FCacheEntry *childEntry, char *name) +{ + FCacheEntry *fce; + CredCacheEntry *ce; + int error; + VenusFid *fid, tempfid; /* Ba san: to check the deletion of file*/ + Result res; + char tmp[5]; + int ret = 0; + Result tempres; + xfs_cache_handle cache_handle; + + ConnCacheEntry *conn; + fs_server_context context; + AFSFetchStatus status; + AFSVolSync volsync; + + fid = &(vcp->fid); /* points to the VenusFid structure */ + fid = fid_translate(fid); + + ret = fcache_find(&fce, *fid); + assert (ret == 0); + + ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); + assert (ce != NULL); + + assert (CheckLock(&fce->lock) == -1); + + conn = find_first_fs (fce, ce, &context); + + ret = RXAFS_RemoveDir (conn->connection, + &fce->fid.fid, + name, + &status, + &volsync); + if (ret) { + arla_log (ADEBDISCONN, + "Could not RemoveDir : %s (%d)", + koerr_gettext(res.res),res.res); + goto out; + } + +/* Ba san: Chcek the deletion of the file */ + ReleaseWriteLock(&fce->lock); + error = adir_lookup(fce->fid, name, &tempfid, ce); + ObtainWriteLock(&fce->lock); + + if (error == 0) { + int result; + + arla_warnx (ADEBDISCONN, + "In reconnect_rmdir: file %s needs to be deleted",name); + result = adir_remove (fce,name); + assert ( result == 0); + } /* This is for the file produced during disconnect mode, + if error==ENOENT then the file is created during connect mode*/ + + fce->status = status; + fce->volsync = volsync; + + volcache_update_volsync (fce->volume, fce->volsync); + + tempres = conv_dir(fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); + + childEntry->host = 0; /*Ba shiqi: no callback for this entry*/ + + out: + + cred_free(ce); + free_fs_server_context(&context); + ReleaseWriteLock(&fce->lock); + return error; +} + +/* + * + */ + +static int +reconnect_mut_chk(FCacheEntry *fce, CredCacheEntry *ce, int version) +{ + ConnCacheEntry *conn; + fs_server_context context; + FCacheEntry fetched = *fce; + int ret; + + AFSFetchStatus status; + AFSCallBack callback; + AFSVolSync volsync; + + assert (CheckLock (&fetched.lock) == -1); + +/*SWW Aug 01: >= is changed into > */ + conn = find_first_fs (&fetched, ce, &context); + + ret = RXAFS_FetchStatus (conn->connection, + &fce->fid.fid, + &status, + &callback, + &volsync); + if (ret) { + if (ret == -1) + ret = ENETDOWN; + free_fs_server_context(&context); + arla_warn (ADEBFCACHE, ret, "fetch-status"); + return ret; + } + + if (status.DataVersion > version) + { + arla_log(ADEBDISCONN, "reconnect_mut_chk: concurrent writes detected!"); + return 1; + } + free_fs_server_context(&context); + return 0; +} + +/* + * + */ + +void fcache_backfile_name(char *name, size_t len) +{ + static int no = 1; + + snprintf (name, len, "%04X",no++); + strcat (name, "bak"); + name[strlen(name)+1] = '\0'; +} + +/* + * + */ + +void +copy_cached_file(int from, int to) +{ + char tmpname[5],name_from[21],name_to[27]; + int fd_from, n, fd_to; + char buf[BUFSIZE]; + + strcpy(name_from,ARLACACHEDIR); + strcpy(name_to,ARLACACHEDIR); + sprintf(tmpname,"%04X",from); + strcat(name_from, tmpname); + sprintf(tmpname,"%04X",to); + strcat(name_to, tmpname); + fd_from = open(name_from,O_RDONLY | O_BINARY); + fd_to = open(name_to, O_WRONLY | O_CREAT | O_BINARY); + + while((n = read(fd_from, buf, BUFSIZE)) > 0) + write(fd_to, buf, n); + +#if 0 + if(fstat(fd_to, &statinfo)<0) { + arla_warnx(ADEBDISCONN,"ERROR"); + } +#endif + + close(fd_from); + close(fd_to); +} + +/* + * + */ + +int +reconnect_mut_newfile(FCacheEntry **fcep, pag_t cred,VenusFid *new_fid) +{ + + FCacheEntry *parent_fce; + u_long host; + char name[9],tmp[5]; + AFSStoreStatus store_attr; + AFSFetchStatus fetch_attr; + CredCacheEntry *ce; + AccessEntry *ae; + VenusFid newfid; + int ret; + int from, to; + xfs_cache_handle cache_handle; + + ret = fcache_find (&parent_fce, (*fcep)->parent); + assert (ret == 0); + + host = (*fcep)->host; + + ce = cred_get((*fcep)->parent.Cell, cred, CRED_ANY); + + fcache_backfile_name (name, sizeof(name)); + + store_attr.Mask = 8; + store_attr.ClientModTime = 430144; + store_attr.Owner = 1957724; + store_attr.Group = 21516; + store_attr.UnixModeBits = 420; + store_attr.SegSize = 0; + + create_file(parent_fce, name, &store_attr, &newfid, &fetch_attr, ce); + + (*fcep)->flags.datap = FALSE; /* Ba shiqi: we need to get the old from FS*/ + *new_fid = newfid; + from = (*fcep)->index; + ret = fcache_find(fcep, newfid); + assert (ret == 0); + to = (*fcep)->index; + (*fcep)->host = host; + (*fcep)->flags.attrp = TRUE; + (*fcep)->flags.datap = TRUE; + findaccess(ce->cred, (*fcep)->acccache, &ae); /*Ba shijiu obtain access */ + ae->cred = ce->cred; + ae->access = (*fcep)->status.CallerAccess; + + ReleaseWriteLock(&(*fcep)->lock); + + copy_cached_file(from, to); + ret = adir_creat (parent_fce, name, newfid.fid); + assert (ret ==0); + conv_dir (parent_fce, ce, 0, &cache_handle, tmp, sizeof(tmp)); + ReleaseWriteLock(&parent_fce->lock); + + return 0; +} + + +/* + * + */ + +int reconnect_putattr(struct vcache *vcp, struct xfs_attr *xap) +{ + + ConnCacheEntry *conn; + fs_server_context context; + struct rx_call *call; + VenusFid *fid; + CredCacheEntry *ce; + FCacheEntry *fce, *tempce; + AFSFetchStatus status; + Result res; + u_int32_t sizefs; + AFSStoreStatus storestatus; + AFSCallBack callback; + AFSVolSync volsync; + int ret; + + fid = &(vcp->fid); /* points to the VenusFid structure */ + fid = fid_translate(fid); + +#if 0 + arla_log(ADEBDISCONN, "reconnect: DISCONNECTED write on fid.Cell=0x%x, " + "fid.fid.Volume= 0x%x, fid.fid.Vnode=0x%x, fid.fid.Unique=0x%x", + fid->Cell, + fid->fid.Volume, + fid->fid.Vnode, + fid->fid.Unique); +#endif + + ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); + assert (ce != NULL); + res.res = 0; + +#if 0 +/* Ba shier: should we send the file back to server? */ + if (XA_VALID_SIZE(xap)){ + res = cm_ftruncate (*fid, xap->xa_size, ce); + } +#endif + + ret = fcache_find(&fce, *fid); + assert (ret == 0); + tempce = fce; + + sizefs=fce->status.Length; + + /* some people have written to the file while we are disconnected */ + /* we have to give it a different name on the server */ + if (reconnect_mut_chk(fce, ce, vcp->DataVersion)) + { + VenusFid new_fid; + + alloc_fid_trans(fid); + reconnect_mut_newfile(&fce,vcp->cred.pag,&new_fid); + fce->status.Length = sizefs; + ReleaseWriteLock(&tempce->lock); + fill_fid_trans(&new_fid); + tempce->flags.attrp = FALSE; + tempce->flags.kernelp = FALSE; + } + +#if 0 + usedbytes -= entry->status.Length; + usedbytes += size; + + fce->status.Length = size; +#endif + + /* code from truncate file XXX join */ + conn = find_first_fs (fce, ce, &context); + + call = rx_NewCall (conn->connection); + if (call == NULL) { + arla_log (ADEBDISCONN, "Cannot call"); + res.res = ENOMEM; + goto out; + } + + storestatus.Mask = 0; + res.res = StartRXAFS_StoreData (call, + &(fce->fid.fid), + &storestatus, + 0, 0, fce->status.Length); + if(res.res) { + arla_log (ADEBDISCONN, "Could not start store, %s (%d)", + koerr_gettext(res.res), res.res); + rx_EndCall(call, 0); + goto out; + } + + sizefs = htonl (sizefs); + if (rx_Write (call, &sizefs, sizeof(sizefs)) != sizeof(sizefs)) { + res.res = rx_Error(call); + arla_log (ADEBDISCONN, "Error writing length: %d", res.res); + rx_EndCall(call, 0); + goto out; + } + + if (rx_Write (call, 0, 0) != 0) { + res.res = rx_Error(call); + arla_log (ADEBDISCONN, "Error writing: %d", res.res); + rx_EndCall(call, 0); + goto out; + } + + res.res = rx_EndCall (call, EndRXAFS_StoreData (call, + &status, + &callback, + &volsync)); + if (res.res) { + arla_log (ADEBDISCONN, "Error rx_EndCall: %s (%d)", + koerr_gettext(res.res), res.res); + goto out; + } + + fce->status = status; + fce->callback = callback; + fce->volsync = volsync; + + volcache_update_volsync (fce->volume, fce->volsync); + + /* code from write_attr XXX join */ + xfs_attr2afsstorestatus(xap, &storestatus); + + res.res = RXAFS_StoreStatus (conn->connection, + &fce->fid.fid, + &storestatus, + &status, + &volsync); + if (res.res) { + arla_log (ADEBDISCONN, "Could not make store-status call, %s (%d)", + koerr_gettext(res.res), res.res); + goto out; + } + arla_log(ADEBDISCONN, + "write_attr: status.Length = %d", status.Length); + fce->status = status; + fce->volsync = volsync; + + volcache_update_volsync (fce->volume, fce->volsync); + + out: + + free_fs_server_context(&context); + ReleaseWriteLock(&fce->lock); + cred_free(ce); + return res.res; +} + +/* + * + */ + +static int +reconnect_putdata(struct vcache *vcp) +{ + VenusFid *fid; + FCacheEntry *fce; + CredCacheEntry *ce; + Result res; + + u_int32_t sizefs; + int fd = -1; + struct rx_call *call; + ConnCacheEntry *conn; + fs_server_context context; + struct stat statinfo; + AFSStoreStatus storestatus; + AFSFetchStatus status; + AFSCallBack callback; + AFSVolSync volsync; + int ret; + + fid = &(vcp->fid); /* points to the VenusFid structure */ + arla_log(ADEBDISCONN, "reconnect: putdata before fid_translate, " + "fid->Cell=0x%x, fid->fid.Volume=0x%x, fid->fid.Vnode=0x%x, " + "fid->fid.Unique=0x%x", + fid->Cell, + fid->fid.Volume, + fid->fid.Vnode, + fid->fid.Unique); + + fid = fid_translate(fid); + + arla_log(ADEBDISCONN, "reconnect: putdata after fid_translate, " + "fid->Cell=0x%x, fid->fid.Volume=0x%x, fid->fid.Vnode=0x%x, " + "fid->fid.Unique=0x%x", + fid->Cell, + fid->fid.Volume, + fid->fid.Vnode, + fid->fid.Unique); + + + ce = cred_get (fid->Cell, vcp->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_find (&fce, *fid); + assert (ret == 0); + +#if 0 + isupdate = reconnect_mut_chk(fce, ce, vcp->DataVersion); + if (isupdate) + { + arla_log(ADEBDISCONN, + "reconnect_putdata: send data back because " + "the file was modified!"); + cred_free(ce); + ReleaseWriteLock(&fce->lock); + reconnect_mut_newfile(&fce, vcp->cred.pag); + return -1; + } + + if (reconnect_mut_chk (fce, ce)) { + arla_log (ADEBDISCONN, "Reconnect_putdata: can not send the file" + "to FS becausethis file has been modified!"); + ReleaseWriteLock(&fce->lock); + return -1; + } +#endif + + /* code taken from write_data XXX join */ + assert (CheckLock(&fce->lock) == -1); + + conn = find_first_fs (fce, ce, &context); + + fd = fcache_open_file (fce, O_RDONLY); + if (fd < 0) { + arla_log (ADEBDISCONN, "open %u failed", fce->index); + res.res = errno; + goto out; + } + + if (fstat (fd, &statinfo) < 0) { + arla_log (ADEBDISCONN, "Cannot stat file %u", fce->index); + res.res = errno; + goto out; + } + + sizefs = statinfo.st_size; + + call = rx_NewCall (conn->connection); + if (call == NULL) { + arla_log (ADEBDISCONN, "Cannot call"); + res.res = ENOMEM; + goto out; + } + + storestatus.Mask = 0; /* Dont save anything */ + res.res = StartRXAFS_StoreData (call, &fce->fid.fid, + &storestatus, + 0, + sizefs, + sizefs); + if (res.res) { + arla_log (ADEBDISCONN, "Could not start store, %s (%d)", + koerr_gettext(res.res), res.res); + rx_EndCall(call, 0); + goto out; + } + + res.res = copyfd2rx (fd, call, sizefs); + if (res.res) { + rx_EndCall(call, res.res); + arla_log (ADEBDISCONN, "copyfd2rx failed: %d", res.res); + goto out; + } + + res.res = rx_EndCall (call, EndRXAFS_StoreData (call, + &status, + &callback, + &volsync)); + if (res.res) { + arla_log (ADEBDISCONN, "Error rx_EndCall: %s (%d)", + koerr_gettext(res.res), res.res); + goto out; + } + if (status.DataVersion > fce->status.DataVersion) + arla_log(ADEBDISCONN, + "reconnect: putdata, server incremented DataVersion!"); + + fce->status = status; + fce->callback = callback; + fce->volsync = volsync; + + volcache_update_volsync (fce->volume, fce->volsync); + + out: + + ReleaseWriteLock(&fce->lock); + if (fd != -1) + close (fd); + free_fs_server_context (&context); + + cred_free(ce); + return res.res; +} + +/* + * + */ + +int reconnect_rename(struct vcache *vcp_old, struct vcache *vcp_new, + char *name_old, char *name_new) +{ + + FCacheEntry *fce_old, *fce_new; + CredCacheEntry *ce; + VenusFid *fid_old, *fid_new,foo_fid,*tempnew_fid; + int error; + + int ret = 0; + Result res; + char tmp[5]; + int isnewpar = 0; + ConnCacheEntry *conn; + fs_server_context context; + AFSFetchStatus orig_status, new_status; + AFSVolSync volsync; + xfs_cache_handle cache_handle; + + fid_old = &vcp_old->fid; + fid_old = fid_translate(fid_old); + + ret = fcache_find (&fce_old, *fid_old); + assert (ret == 0); + + /* ReleaseWriteLock(&fce_old->lock); SWW Qiyue 28 Maybe we dont need it*/ + assert(fce_old); + arla_log(ADEBDISCONN, "reconnect: old rename on Cell=0x%x, " + "fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", + fce_old->fid.Cell, + fce_old->fid.fid.Volume, + fce_old->fid.fid.Vnode, + fce_old->fid.fid.Unique); + + fid_new = tempnew_fid = &vcp_new->fid; + fid_new = fid_translate(fid_new); + + if (tempnew_fid->fid.Volume != fid_new->fid.Volume || + tempnew_fid->fid.Vnode != fid_new->fid.Vnode || + tempnew_fid->fid.Unique != fid_new->fid.Unique) + isnewpar = 1; + +/*Ba ba: the parent dir was created during disconnected */ + + if (fid_old->fid.Volume == fid_new->fid.Volume && + fid_old->fid.Vnode == fid_new->fid.Vnode && + fid_old->fid.Unique == fid_new->fid.Unique ) + ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ + + ret = fcache_find (&fce_new, *fid_new); + assert (ret == 0); + + arla_log(ADEBDISCONN, "reconnect: new rename on Cell=0x%x, " + "fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", + fce_new->fid.Cell, + fce_new->fid.fid.Volume, + fce_new->fid.fid.Vnode, + fce_new->fid.fid.Unique); + + + + arla_log(ADEBDISCONN, + "reconnect_rename: fce_old = 0x%x, fce_new = 0x%x", + fce_old, fce_new); + + ce = cred_get (vcp_old->fid.Cell, vcp_old->cred.pag, CRED_ANY); + assert (ce != NULL); + + assert (CheckLock(&fce_old->lock) == -1 + && CheckLock(&fce_new->lock) == -1); + + conn = find_first_fs (fce_old, ce, &context); + + error = RXAFS_Rename (conn->connection, + &fce_old->fid.fid, + name_old, + &fce_new->fid.fid, + name_new, + &orig_status, + &new_status, + &volsync); + + if (error) { + arla_log (ADEBDISCONN, "Could not Rename: %s (%d)", koerr_gettext(error), error); + goto out; } + + fce_old->status = orig_status; + fce_new->status = new_status; + + fce_old->volsync = fce_new->volsync = volsync; + + volcache_update_volsync (fce_old->volume, fce_old->volsync); + + +/*SWW Aug 01 */ + arla_warnx (ADEBDISCONN, + "reconnect_rename: we delete the old one %s volumn=0x%x, " + "vnode=0x%x,unique=0x%x", + name_old,fce_old->fid.fid.Volume, + fce_old->fid.fid.Vnode, + fce_old->fid.fid.Unique); + +/*Ba Yi: get the VenuseFid for new file */ + #if 0 + if (fid_old->fid.Volume == fid_new->fid.Volume && + fid_old->fid.Vnode == fid_new->fid.Vnode && + fid_old->fid.Unique == fid_new->fid.Unique ) ; +#endif + ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ + + error = adir_lookup (fce_old->fid, name_old, &foo_fid, ce); + +#if 0 + if (fid_old->fid.Volume == fid_new->fid.Volume && + fid_old->fid.Vnode == fid_new->fid.Vnode && + fid_old->fid.Unique == fid_new->fid.Unique ); +#endif + ObtainWriteLock (&fce_old->lock); + +/*Ba San: delete the old which was created during dis */ + if (error == 0) { + arla_warnx (ADEBDISCONN,"reconnect_rename: we delete the old one %s " + "volumn=0x%x,vnode=0x%x,unique=0x%x", + name_old, + foo_fid.fid.Volume, + foo_fid.fid.Vnode, + foo_fid.fid.Unique); + + adir_remove(fce_old,name_old); + adir_remove(fce_new,name_new); + + res = conv_dir (fce_old, ce, 0, &cache_handle, tmp, sizeof(tmp)); + + } else { + /* if found delete it */ +/*Ba San: try to find the previous VenuseFid for old name */ + if (error == ENOENT) { +#if 0 + if (fid_old->fid.Volume == fid_new->fid.Volume && + fid_old->fid.Vnode == fid_new->fid.Vnode && + fid_old->fid.Unique == fid_new->fid.Unique ); +#endif + ReleaseWriteLock(&fce_new->lock); + + error = adir_lookup (fce_new->fid, name_new, &foo_fid, ce); + +#if 0 + if (fid_old->fid.Volume == fid_new->fid.Volume && + fid_old->fid.Vnode == fid_new->fid.Vnode && + fid_old->fid.Unique == fid_new->fid.Unique ); +#endif + ObtainWriteLock (&fce_new->lock); + if (error == 0) /*Ba Si: We need delete the faked new */ + adir_remove(fce_new,name_new); + else if (error == ENOENT) { + int venusret; + + venusret = find_venus (name_new,&foo_fid); + assert (venusret==0); + arla_warnx (ADEBDISCONN,"I MUST WRITE A PROGRAM HERE"); + if (isnewpar == 1) { + + arla_warnx(ADEBDISCONN,"In reconnect_rename: " + "new Volume=0x%x,Vnode=0x%x,Unique=0x%x", + fce_new->fid.fid.Volume, + fce_new->fid.fid.Vnode, + fce_new->fid.fid.Unique); +#if 0 + error = adir_creat(fce_new, name_new, foo_fid.fid); +#endif + } + } + } + } + + arla_warnx (ADEBDISCONN,"reconnect_rename: we add the new one %s " + "volumn=0x%x,vnode=0x%x,unique=0x%x", + name_new, + foo_fid.fid.Volume, + foo_fid.fid.Vnode, + foo_fid.fid.Unique); + error = adir_creat (fce_new, name_new, foo_fid.fid); + res = conv_dir (fce_new, ce, 0, &cache_handle, tmp, sizeof(tmp)); + +/* Aug 1 */ + + out: + + free_fs_server_context (&context); + + ReleaseWriteLock(&fce_new->lock); + + if (fid_old->fid.Volume != fid_new->fid.Volume || + fid_old->fid.Vnode != fid_new->fid.Vnode || + fid_old->fid.Unique != fid_new->fid.Unique ) + ReleaseWriteLock(&fce_old->lock); /* old and new are the same*/ + + cred_free(ce); + return error; +} + +/* XXX */ + +/* + * + */ + +static void +recon_hashtabdel (FCacheEntry *e) +{ +} + +/* + * + */ + +static void +recon_hashtabadd (FCacheEntry *e) +{ +} + +/* + * + */ + +int reconnect_create(struct vcache *parent, struct vcache *child, char *name) +{ + + ConnCacheEntry *conn; + fs_server_context context; + VenusFid *parent_fid; + VenusFid *child_fid; + VenusFid fakeFid; + + CredCacheEntry *ce; + FCacheEntry *parentEntry; + FCacheEntry *childEntry; + + AFSFetchStatus fetch_attr; + AFSStoreStatus store_attr; + + Result res; + AFSFetchStatus status; + AFSCallBack callback; + AFSVolSync volsync; + int ret; + char tmp[5]; + xfs_cache_handle cache_handle; + int32_t type; + + parent_fid = &(parent->fid); /* points to the VenusFid structure */ + child_fid = &(child->fid); + fakeFid = *child_fid; + + /*Ba Liu: the parent dir may be created during dison mode*/ + parent_fid = fid_translate(parent_fid); + + ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_find (&parentEntry, *parent_fid); + assert (ret == 0); + +#if 0 + is_change = reconnect_mut_chk(parentEntry, + ce, + parentEntry->status.DataVersion); +#endif + +/*SWW Qiyue 30 delete the old file entry in dir */ + arla_warnx (ADEBDISCONN, + "reconnect_rename: we delete the old one volumn=0x%x, " + "vnode=0x%x,unique=0x%x", + parentEntry->fid.fid.Volume, + parentEntry->fid.fid.Vnode, + parentEntry->fid.fid.Unique); + + adir_remove(parentEntry,name); + + conn = find_first_fs (parentEntry, ce, &context); + + if (conn == NULL) { + arla_log (ADEBDISCONN, "Cannot call"); + res.res = ENOMEM; + goto out; + } + + ret = fcache_find (&childEntry, *child_fid); + assert (ret == 0); + + recon_hashtabdel(childEntry); + +#if 0 + fetch_attr = &childEntry->status; +#endif + + store_attr.Mask = 8; + store_attr.ClientModTime = childEntry->status.ClientModTime; + store_attr.Owner = childEntry->status.Owner; + store_attr.Group = childEntry->status.Group; + store_attr.UnixModeBits = childEntry->status.UnixModeBits; + store_attr.SegSize = childEntry->status.SegSize; + + arla_log(ADEBDISCONN, + "reconnect: create before RXAFS_CreateFile, " + "Cell=0x%x, fid.Volume= 0x%x, fid.Vnode=0x%x, fid.Unique=0x%x", + childEntry->fid.Cell, + childEntry->fid.fid.Volume, + childEntry->fid.fid.Vnode, + childEntry->fid.fid.Unique); + + alloc_fid_trans(&childEntry->fid); + + + ret = RXAFS_CreateFile (conn->connection, + &(parentEntry->fid.fid), + name, &store_attr, + &(childEntry->fid.fid), &fetch_attr, + &status, + &callback, + &volsync); + + if (ret) { + if (ret == 17) { + ReleaseWriteLock(&parentEntry->lock); + reconnect_mut_newfile(&childEntry, + parent->cred.pag, + &childEntry->fid); + ObtainWriteLock(&parentEntry->lock); + fill_fid_trans(&childEntry->fid); + recon_hashtabadd(childEntry); + childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); + update_kernelfid(fakeFid, childEntry->fid); + } else { + arla_log (ADEBDISCONN, "Could not CreateFile: %s (%d)", + koerr_gettext(ret), ret); + } + goto out; + } + + parentEntry->status = status; + parentEntry->callback = callback; + parentEntry->volsync = volsync; + + childEntry->fid.Cell = parentEntry->fid.Cell; + + arla_log(ADEBDISCONN, "reconnect: create after RXAFS_CreateFile, " + "Cell=0x%x, fid.Volume= 0x%x, fid .Vnode=0x%x, fid.Unique=0x%x", + childEntry->fid.Cell, + childEntry->fid.fid.Volume, + childEntry->fid.fid.Vnode, + childEntry->fid.fid.Unique); + + fill_fid_trans(&childEntry->fid); + +#if 0 + ReleaseWriteLock(&childEntry->lock); +#endif + + + ret = volcache_getbyid (childEntry->fid.fid.Volume, + childEntry->fid.Cell, + ce, + &childEntry->volume, + &type); + + recon_hashtabadd(childEntry); + + arla_log(ADEBDISCONN, + "reconnect: create after volcache_getbyid, Cell=0x%x, " + "fid.Volume= 0x%x, fid .Vnode=0x%x, fid.Unique=0x%x", + childEntry->fid.Cell, + childEntry->fid.fid.Volume, + childEntry->fid.fid.Vnode, + childEntry->fid.fid.Unique); + +/* SWW Qiyue 30: add the new file entry in dir */ + arla_warnx (ADEBDISCONN,"reconnect_rename: we add the new one " + "volumn=0x%x,vnode=0x%x,unique=0x%x", + parentEntry->fid.fid.Volume, + parentEntry->fid.fid.Vnode, + parentEntry->fid.fid.Unique); + + adir_creat (parentEntry, name, childEntry->fid.fid); + + childEntry->status = fetch_attr; + + childEntry->flags.attrp = TRUE; + childEntry->flags.kernelp = TRUE; + + childEntry->flags.datap = TRUE; + childEntry->tokens |= XFS_ATTR_R | XFS_DATA_R | XFS_DATA_W; + + volcache_update_volsync (parentEntry->volume, parentEntry->volsync); + + + +/*SWW Qiyue 28: Set the host for child entry */ + + childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); + assert(childEntry->host); + +/*SWW Qiyue 29: */ + arla_warnx (ADEBDISCONN, + "Replace fid.Volume=0x%x,Vnode=0x%x,Unique=0x%x with " + "Volume=0x%x,Vnode=0x%x,Unqiue=0x%x", + fakeFid.fid.Volume, + fakeFid.fid.Vnode, + fakeFid.fid.Unique, + childEntry->fid.fid.Volume, + childEntry->fid.fid.Vnode, + childEntry->fid.fid.Unique); + + update_kernelfid(fakeFid, childEntry->fid); + + conv_dir(parentEntry, ce, 0, &cache_handle, tmp, sizeof(tmp)); + + ReleaseWriteLock(&childEntry->lock); + + out: + + ReleaseWriteLock(&parentEntry->lock); + ReleaseWriteLock(&childEntry->lock); + free_fs_server_context(&context); + cred_free(ce); + return ret; +} + +/* + * + */ + +int reconnect_mkdir(struct vcache *parent, struct vcache *curdir, + AFSStoreStatus *store_status, char *name) +{ + ConnCacheEntry *conn; + fs_server_context context; + CredCacheEntry *ce; + VenusFid *parent_fid; + VenusFid *child_fid; + VenusFid fakeFid; + + FCacheEntry *parentEntry, *childEntry, *tempEntry, *tempparEntry; + Result tempres; + Result res; + int ret = 0; + int tempret = 0; + struct timeval tv; + char tmp[5]; + + AFSFid Outfid; /* Ba Wu: These are used to get the info from FS*/ + AFSFetchStatus fetch_attr; + AFSFetchStatus status; + AFSCallBack callback; + AFSVolSync volsync; + xfs_cache_handle cache_handle; + int32_t type; + + parent_fid = &(parent->fid); /* points to the VenusFid structure */ + child_fid = &(curdir->fid); + fakeFid = *child_fid; + + parent_fid = fid_translate(parent_fid); + + ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_find (&parentEntry, *parent_fid); + assert (ret == 0); + + tempparEntry = parentEntry; + +/*Ba ba: used to check whether name can be find Deleted !!! + ReleaseWriteLock(&parentEntry->lock); + tempret = adir_lookup (parentEntry->fid , name , &foo_fid , ce); */ +/*Ba ba: used to check whether name can be find Deleted !!! */ + + /*Ba Wu Remove the dir name from itsparent dir */ + tempret = adir_remove(parentEntry,name); + conn = find_first_fs (parentEntry, ce, &context); + + if (conn == NULL) { + arla_log (ADEBDISCONN,"Cannot make this connection"); + res.res = ENOMEM; + goto out; + } + + ret = fcache_find(&childEntry, *child_fid);/*Ba Wu: remove the newly created dir */ + assert (ret == 0); + + recon_hashtabdel(childEntry); + + alloc_fid_trans(&childEntry->fid); + + gettimeofday(&tv, NULL); + + ret = RXAFS_MakeDir (conn->connection, + &parentEntry->fid.fid, + name, + store_status, + &Outfid, + &fetch_attr, + &status, + &callback, + &volsync); + + if (ret) { + arla_log (ADEBDISCONN, "Could not CreateFile: %s (%d)", + koerr_gettext(ret), ret); + goto out; + } + + parentEntry->status = status; + parentEntry->callback = callback; + parentEntry->callback.ExpirationTime += tv.tv_sec; + parentEntry->volsync = volsync; + + childEntry->fid.Cell = parentEntry->fid.Cell; + childEntry->fid.fid = Outfid; + childEntry->status = fetch_attr; + childEntry->flags.attrp = TRUE; + childEntry->flags.kernelp = TRUE; + childEntry->flags.datap = TRUE; + childEntry->tokens |= XFS_ATTR_R | XFS_DATA_R | XFS_DATA_W; + + fill_fid_trans(&childEntry->fid); + + ret = volcache_getbyid (childEntry->fid.fid.Volume, + childEntry->fid.Cell, + ce, + &childEntry->volume, + &type); + + recon_hashtabadd(childEntry); + +/*Ba ba: Need to change later!!! */ +#if 0 + ReleaseWriteLock(&tempparEntry->lock); + tempret = adir_changefid (tempparEntry->fid ,name, &Outfid, ce); + ReleaseWriteLock(&tempparEntry->lock); + tempret = adir_lookup (tempparEntry->fid ,name, &foo_fid, ce); +#endif + + tempret = adir_creat (parentEntry, name, childEntry->fid.fid); + + tempret = adir_mkdir (childEntry, childEntry->fid.fid,parentEntry->fid.fid); + + childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); + assert(childEntry->host); + + update_kernelfid(fakeFid, childEntry->fid); + + tempres = conv_dir(parentEntry, ce, 0, &cache_handle, + tmp, sizeof(tmp)); + + ReleaseWriteLock(&childEntry->lock); + + /*SWW Qiyue 29: This should be deleted later */ + ret = fcache_find (&tempEntry, childEntry->fid); + + assert (ret == 0); + assert (tempEntry == NULL); + + out: + + ReleaseWriteLock(&parentEntry->lock); + ReleaseWriteLock(&childEntry->lock); + free_fs_server_context(&context); + cred_free(ce); + return ret; +} + +/* + * + */ + +int reconnect_link(struct vcache *parent, struct vcache *existing, + char *name) +{ + ConnCacheEntry *conn; + fs_server_context context; + CredCacheEntry *ce; + VenusFid *parent_fid; + VenusFid *existing_fid; + char tmp[5]; + int ret = 0; + FCacheEntry *dir_entry,*existing_entry; + Result res; + + AFSFetchStatus new_status; + AFSFetchStatus status; + AFSVolSync volsync; + xfs_cache_handle cache_handle; + + + parent_fid = &(parent->fid); + existing_fid = &(existing->fid); + + parent_fid = fid_translate(parent_fid); + + ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_find (&dir_entry, *parent_fid); + assert (ret == 0); + + ret = fcache_find (&existing_entry, *existing_fid); + assert (ret == 0); + + conn = find_first_fs (dir_entry, ce, &context); + + if (conn == NULL) { + arla_log (ADEBDISCONN,"Cannot make this connection"); + res.res = ENOMEM; + goto out; + } + + ret = RXAFS_Link (conn->connection, + &dir_entry->fid.fid, + name, + &existing_entry->fid.fid, + &new_status, + &status, + &volsync); + if (ret) { + arla_warn (ADEBFCACHE, ret, "Link"); + goto out; + } + + dir_entry->status = status; + dir_entry->volsync = volsync; + + existing_entry->status = new_status; + + volcache_update_volsync (dir_entry->volume, dir_entry->volsync); + + res = conv_dir (dir_entry, ce, 0, &cache_handle, tmp, sizeof(tmp)); + + out: + ReleaseWriteLock(&dir_entry->lock); + ReleaseWriteLock(&existing_entry->lock); + free_fs_server_context (&context); + return ret; +} + +/* + * + */ + +int reconnect_symlink(struct vcache *parent, struct vcache *child, + AFSStoreStatus *store_attr, char *name, + char *contents) +{ + ConnCacheEntry *conn; + fs_server_context context; + CredCacheEntry *ce; + VenusFid *parent_fid, *child_fid, fakeFid; + char tmp[5]; + int ret = 0; + FCacheEntry *dir_entry, *childEntry; + Result res; + + AFSFetchStatus fetch_attr, new_status; + AFSVolSync volsync; + xfs_cache_handle cache_handle; + int32_t type; + + parent_fid = &(parent->fid); + child_fid = &(child->fid); + fakeFid = *child_fid; + parent_fid = fid_translate(parent_fid); + + ce = cred_get (parent->fid.Cell, parent->cred.pag, CRED_ANY); + assert (ce != NULL); + + ret = fcache_find (&dir_entry, *parent_fid); + assert (ret == 0); + + adir_remove(dir_entry,name); + + ret = fcache_find (&childEntry, *child_fid); + assert (ret == 0); + + recon_hashtabdel(childEntry); + + assert(ret==0); + conn = find_first_fs (dir_entry, ce, &context); + + if (conn == NULL) { + arla_log (ADEBDISCONN,"Cannot make this connection"); + goto out; + } + + alloc_fid_trans(&childEntry->fid); + + ret = RXAFS_Symlink (conn->connection, + &dir_entry->fid.fid, + name, + contents, + store_attr, + &(childEntry->fid.fid), + &fetch_attr, + &new_status, + &volsync); + if (ret) { + arla_warn (ADEBFCACHE, ret, "Symlink"); + goto out; + } + + child_fid->Cell = dir_entry->fid.Cell; + + fill_fid_trans (&childEntry->fid); + ret = volcache_getbyid (childEntry->fid.fid.Volume, + childEntry->fid.Cell, + ce, + &childEntry->volume, + &type); + + recon_hashtabadd (childEntry); + + adir_creat(dir_entry, name, childEntry->fid.fid); + + childEntry->status = fetch_attr; + childEntry->flags.attrp = TRUE; + childEntry->flags.kernelp = TRUE; + childEntry->tokens |= XFS_ATTR_R; + volcache_update_volsync (dir_entry->volume, dir_entry->volsync); + + childEntry->host = rx_HostOf (rx_PeerOf (conn->connection)); + assert(childEntry->host); + + update_kernelfid(fakeFid, childEntry->fid); + res = conv_dir (dir_entry, ce, 0, &cache_handle, tmp, sizeof(tmp)); + + out: + ReleaseWriteLock(&dir_entry->lock); + ReleaseWriteLock(&childEntry->lock); + free_fs_server_context(&context); + cred_free(ce); + return ret; +} + diff --git a/usr.sbin/afs/src/arlad/reconnect.h b/usr.sbin/afs/src/arlad/reconnect.h new file mode 100644 index 00000000000..de1b829a26e --- /dev/null +++ b/usr.sbin/afs/src/arlad/reconnect.h @@ -0,0 +1,39 @@ +/* $OpenBSD: reconnect.h,v 1.1 1999/04/30 01:59:10 art Exp $ */ +/* COPYRIGHT (C) 1998 + * THE REGENTS OF THE UNIVERSITY OF MICHIGAN + * ALL RIGHTS RESERVED + * + * PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS + * AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS + * FOR ANY PURPOSE, SO LONG AS THE NAME OF THE UNIVERSITY OF + * MICHIGAN IS NOT USED IN ANY ADVERTISING OR PUBLICITY + * PERTAINING TO THE USE OR DISTRIBUTION OF THIS SOFTWARE + * WITHOUT SPECIFIC, WRITTEN PRIOR AUTHORIZATION. IF THE + * ABOVE COPYRIGHT NOTICE OR ANY OTHER IDENTIFICATION OF THE + * UNIVERSITY OF MICHIGAN IS INCLUDED IN ANY COPY OF ANY + * PORTION OF THIS SOFTWARE, THEN THE DISCLAIMER BELOW MUST + * ALSO BE INCLUDED. + * + * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION + * FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY + * PURPOSE, AND WITHOUT WARRANTY BY THE UNIVERSITY OF + * MICHIGAN OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING + * WITHOUT LIMITATION THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + * REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE + * FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING + * OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN + * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES. + */ + +/* $KTH: reconnect.h,v 1.3 1998/12/21 21:54:43 assar Exp $ */ + +#ifndef _RECONNECT_H +#define _RECONNECT_H + +void +do_replay(char *log_file, int log_entries, VenusFid *changed_fid); + +#endif /* _RECONNECT_H */ diff --git a/usr.sbin/afs/src/arlad/service.h b/usr.sbin/afs/src/arlad/service.h index 36bddd11fc8..ca05251fca7 100644 --- a/usr.sbin/afs/src/arlad/service.h +++ b/usr.sbin/afs/src/arlad/service.h @@ -1,4 +1,4 @@ -/* $OpenBSD: service.h,v 1.1.1.1 1998/09/14 21:52:57 art Exp $ */ +/* $OpenBSD: service.h,v 1.2 1999/04/30 01:59:10 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,13 +37,14 @@ * SUCH DAMAGE. */ -/* $KTH: service.h,v 1.4 1998/07/14 16:00:50 lha Exp $ */ +/* $KTH: service.h,v 1.5 1998/09/03 18:45:36 lha Exp $ */ /* * Service IDs */ #define VLDB_SERVICE_ID 52 +#define VOLSER_SERVICE_ID 54 #define PR_SERVICE_ID 73 #define FS_SERVICE_ID 1 #define CM_SERVICE_ID 1 diff --git a/usr.sbin/afs/src/arlad/subr.h b/usr.sbin/afs/src/arlad/subr.h index 0073cfc2d0d..3341d17e17f 100644 --- a/usr.sbin/afs/src/arlad/subr.h +++ b/usr.sbin/afs/src/arlad/subr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: subr.h,v 1.1.1.1 1998/09/14 21:52:57 art Exp $ */ +/* $OpenBSD: subr.h,v 1.2 1999/04/30 01:59:10 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,14 +41,14 @@ * Header with prototypes for OS-specific functions. */ -/* $KTH: subr.h,v 1.5 1998/03/24 02:43:00 assar Exp $ */ +/* $KTH: subr.h,v 1.6 1998/09/08 08:24:39 assar Exp $ */ #ifndef _SUBR_H_ #define _SUBR_H_ Result -conv_dir (FCacheEntry *e, char *handle, size_t handle_size, - CredCacheEntry *ce, u_int tokens); +conv_dir (FCacheEntry *e, CredCacheEntry *ce, u_int tokens, + xfs_cache_handle *, char *, size_t); #endif /* _SUBR_H_ */ diff --git a/usr.sbin/afs/src/arlad/volcache.c b/usr.sbin/afs/src/arlad/volcache.c index 9fa5768d639..773802d32ff 100644 --- a/usr.sbin/afs/src/arlad/volcache.c +++ b/usr.sbin/afs/src/arlad/volcache.c @@ -1,6 +1,6 @@ -/* $OpenBSD: volcache.c,v 1.1.1.1 1998/09/14 21:52:57 art Exp $ */ +/* $OpenBSD: volcache.c,v 1.2 1999/04/30 01:59:10 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -42,7 +42,7 @@ */ #include "arla_local.h" -RCSID("$KTH: volcache.c,v 1.39 1998/07/29 21:31:06 assar Exp $") ; +RCSID("$KTH: volcache.c,v 1.67 1999/04/20 20:58:09 map Exp $") ; /* * Suffixes for volume names. @@ -169,27 +169,31 @@ recycle_entry (VolCacheEntry *e) int i; for (i = 0; i < MAXTYPES; ++i) { - if (e->name_ptr[i].ptr != NULL) { + if (e->num_ptr[i].ptr != NULL) { FCacheEntry *fe; int ret; VenusFid fid; - assert (e->num_ptr[i].ptr != NULL); - fid.Cell = e->cell; fid.fid.Vnode = fid.fid.Unique = 1; fid.fid.Volume = e->num_ptr[i].vol; ret = fcache_find (&fe, fid); if (ret == 0 && fe != NULL) { - assert (fe->refcount > 0 && fe->flags.mountp); - --fe->refcount; + if (fe->refcount > 0) + --fe->refcount; + fcache_release (fe); } - - hashtabdel (volnamehashtab, &e->name_ptr[i]); hashtabdel (volidhashtab, &e->num_ptr[i]); } + if (e->name_ptr[i].ptr != NULL) { + hashtabdel (volnamehashtab, &e->name_ptr[i]); + } } - memset (e, 0, sizeof(*e)); + memset (&e->entry, 0, sizeof(e->entry)); + memset (&e->volsync, 0, sizeof(e->volsync)); + e->flags.validp = FALSE; + memset (&e->name_ptr, 0, sizeof(e->name_ptr)); + memset (&e->num_ptr, 0, sizeof(e->num_ptr)); } /* @@ -348,42 +352,44 @@ volcache_init (unsigned nentries, Bool recover) } /* - * + * Add a clone to `e' of type `type' with suffix `slot_type' in slot + * slot_type */ -static int -get_info (VolCacheEntry *e, const char *volname, CredCacheEntry *ce) +static void +add_clone (VolCacheEntry *e, int type, int suffix_type) { - ConnCacheEntry *conn; - u_long addr = cell_finddbserver (e->cell).s_addr; - int error, i; - - conn = conn_get (e->cell, addr, afsvldbport, VLDB_SERVICE_ID, ce); - if (conn == NULL) { - struct in_addr ia; - - ia.s_addr = addr; - arla_warnx (ADEBVOLCACHE, - "volcache: failed to make rx-connection to vldb %s", - inet_ntoa(ia)); - return -1; + struct num_ptr *num_ptr = &e->num_ptr[type]; + struct name_ptr *name_ptr = &e->name_ptr[suffix_type]; + + if (type == suffix_type) { + num_ptr->cell = e->cell; + num_ptr->vol = e->entry.volumeId[type]; + num_ptr->ptr = e; + num_ptr->type = type; + hashtabadd (volidhashtab, (void *) num_ptr); } - error = VL_GetEntryByName(conn->connection, volname, &e->entry); - conn_free (conn); - if (error) { - arla_warn (ADEBVOLCACHE, error, - "VL_GetEntryByName(%s)", - volname); - return -1; - } - - i = min(strlen(volname), VLDB_MAXNAMELEN); - if (strncmp(volname, e->entry.name, i)) { - arla_warnx (ADEBERROR, "get_info: we asked for %s and got %s", - volname, e->entry.name); - } + name_ptr->cell = e->cell; + snprintf (name_ptr->name, VLDB_MAXNAMELEN, + "%s%s", e->entry.name, volsuffixes[suffix_type]); + name_ptr->ptr = e; + name_ptr->type = type; + hashtabadd (volnamehashtab, (void *) name_ptr); +} + +/* + * + */ +static int +get_info_common (VolCacheEntry *e) +{ + if (e->entry.flags & VLF_DFSFILESET) + arla_warnx (ADEBWARN, + "get_info: %s is really a DFS volume. " + "This might not work", + e->entry.name); if ((e->entry.volumeId[RWVOL] == e->entry.volumeId[ROVOL] && e->entry.flags & VLF_RWEXISTS && e->entry.flags & VLF_ROEXISTS) || @@ -393,58 +399,239 @@ get_info (VolCacheEntry *e, const char *volname, CredCacheEntry *ce) e->entry.flags & VLF_RWEXISTS && e->entry.flags & VLF_BOEXISTS)) { arla_warnx (ADEBERROR, "get_info: same id on diffrent volumes: %s", - volname); + e->entry.name); return -1; } - if (e->entry.flags & VLF_RWEXISTS) { - e->num_ptr[RWVOL].cell = e->cell; - e->num_ptr[RWVOL].vol = e->entry.volumeId[RWVOL]; - e->num_ptr[RWVOL].ptr = e; - hashtabadd (volidhashtab, (void *)&e->num_ptr[RWVOL]); + if (e->entry.flags & VLF_RWEXISTS) + add_clone (e, RWVOL, RWVOL); + else + add_clone (e, ROVOL, RWVOL); + if (e->entry.flags & VLF_ROEXISTS) + add_clone (e, ROVOL, ROVOL); + if (e->entry.flags & VLF_BOEXISTS) + add_clone (e, BACKVOL, BACKVOL); + e->flags.validp = TRUE; + return 0; +} + +/* + * A function for checking if a service is up. Return 0 if succesful. + */ - e->name_ptr[RWVOL].cell = e->cell; - snprintf (e->name_ptr[RWVOL].name, VLDB_MAXNAMELEN, - "%s%s", e->entry.name, volsuffixes[RWVOL]); - e->name_ptr[RWVOL].ptr = e; - hashtabadd (volnamehashtab, (void *)&e->name_ptr[RWVOL]); +static int +vl_probe (struct rx_connection *conn) +{ + return VL_Probe (conn); +} +/* + * Get all the db servers for `e->cell', sort them in order by rtt + * (with some fuzz) and try to retrieve the entry for `name'. + * + * Return 0 if succesful, else error. + */ + +static int +get_info_loop (VolCacheEntry *e, const char *name, CredCacheEntry *ce) +{ + const cell_db_entry *db_servers; + int num_db_servers; + int num_working_db_servers; + int error = 0; + int cell = e->cell; + ConnCacheEntry **conns; + int i, j; + Bool try_again; + + db_servers = cell_dbservers (cell, &num_db_servers); + if (db_servers == NULL || num_db_servers == 0) { + arla_warnx (ADEBWARN, + "Cannot find any db servers in cell %d(%s)", + cell, cell_num2name(cell)); + return ENOENT; + } + + conns = malloc (num_db_servers * sizeof(*conns)); + if (conns == NULL) + return ENOMEM; + + for (i = 0, j = 0; i < num_db_servers; ++i) { + ConnCacheEntry *conn; + + conn = conn_get (cell, db_servers[i].addr.s_addr, afsvldbport, + VLDB_SERVICE_ID, vl_probe, ce); + if (conn != NULL) { + conn->rtt = rx_PeerOf(conn->connection)->rtt + + rand() % RTT_FUZZ - RTT_FUZZ / 2; + conns[j++] = conn; + } } - if (e->entry.flags & VLF_ROEXISTS) { - e->num_ptr[ROVOL].cell = e->cell; - e->num_ptr[ROVOL].vol = e->entry.volumeId[ROVOL]; - e->num_ptr[ROVOL].ptr = e; - hashtabadd (volidhashtab, (void *)&e->num_ptr[ROVOL]); - - e->name_ptr[ROVOL].cell = e->cell; - snprintf (e->name_ptr[ROVOL].name, VLDB_MAXNAMELEN, - "%s%s", e->entry.name, volsuffixes[ROVOL]); - e->name_ptr[ROVOL].ptr = e; - hashtabadd (volnamehashtab, (void *)&e->name_ptr[ROVOL]); + num_working_db_servers = j; + + qsort (conns, num_working_db_servers, sizeof(*conns), + conn_rtt_cmp); + + try_again = TRUE; + + for (i = 0; i < num_working_db_servers; ++i) { + if (conns[i] != NULL) { + retry: + if (try_again) { + if (conns[i]->flags.old) { + vldbentry entry; + error = VL_GetEntryByName (conns[i]->connection, + name, &entry); + if (error == 0) + vldb2vldbN(&entry, &e->entry); + } else + error = VL_GetEntryByNameN (conns[i]->connection, + name, &e->entry); + if (error == RX_CALL_DEAD) + conn_dead (conns[i]); + switch (error) { + case 0 : + try_again = FALSE; + break; + case VL_NOENT : + error = ENOENT; + try_again = FALSE; + break; + case RXGEN_OPCODE: + if (conns[i]->flags.old == FALSE) { + conns[i]->flags.old = TRUE; + goto retry; + } + break; + default : + arla_warn (ADEBVOLCACHE, error, + "VL_GetEntryByName%s(%s)", + conns[i]->flags.old ? "" : "N", + name); + break; + } + } + conn_free (conns[i]); + } } - if (e->entry.flags & VLF_BOEXISTS) { - e->num_ptr[BACKVOL].cell = e->cell; - e->num_ptr[BACKVOL].vol = e->entry.volumeId[BACKVOL]; - e->num_ptr[BACKVOL].ptr = e; - hashtabadd (volidhashtab, (void *)&e->num_ptr[BACKVOL]); - - e->name_ptr[BACKVOL].cell = e->cell; - snprintf (e->name_ptr[BACKVOL].name, VLDB_MAXNAMELEN, - "%s%s", e->entry.name, volsuffixes[BACKVOL]); - e->name_ptr[BACKVOL].ptr = e; - hashtabadd (volnamehashtab, (void *)&e->name_ptr[BACKVOL]); + + free (conns); + + if (try_again) { + arla_warnx (ADEBWARN, + "Failed to contact any db servers in cell %d(%s)", + cell, cell_num2name(cell)); + error = ETIMEDOUT; } - e->flags.validp = TRUE; - return 0; + + return error; +} + +/* + * + */ + +static int +get_info_byid (VolCacheEntry *e, u_int32_t id, CredCacheEntry *ce) +{ + int error; + char s[11]; + + snprintf (s, sizeof(s), "%u", id); + error = get_info_loop (e, s, ce); + if (error) + return error; + return get_info_common (e); +} + + +/* + * + */ + +static int +get_info_byname (VolCacheEntry *e, const char *volname, CredCacheEntry *ce) +{ + int error; + int i; + size_t entry_name_len; + int name_matched; + + error = get_info_loop (e, volname, ce); + if (error) + return error; + + entry_name_len = strlen(e->entry.name); + name_matched = FALSE; + + for (i = 0; i < MAXTYPES; ++i) { + if (strncmp (volname, e->entry.name, entry_name_len) == 0 + && strcmp (volname + entry_name_len, volsuffixes[i]) == 0) { + name_matched = TRUE; + break; + } + } + + /* + * If the name we looked up is different from the one we got back, + * replace that one with the canonical looked up name. Otherwise, + * we're not going to be able to find the volume in question. + */ + + if (!name_matched) { + size_t volname_len = strlen(volname); + + arla_warnx (ADEBWARN, + "get_info: different volnames: %s - %s", + volname, e->entry.name); + + for (i = MAXTYPES - 1; i >= 0; --i) + if (strcmp (volname + volname_len - strlen(volsuffixes[i]), + volsuffixes[i]) == 0) { + volname_len -= strlen(volsuffixes[i]); + break; + } + + strncpy (e->entry.name, volname, volname_len); + e->entry.name[volname_len] = '\0'; + } + + return get_info_common (e); } /* * Add an entry for (volname, cell) to the hash table. */ -static VolCacheEntry * -add_entry (const char *volname, int32_t cell, CredCacheEntry *ce) +static int +add_entry_byname (VolCacheEntry **ret, const char *volname, + int32_t cell, CredCacheEntry *ce) +{ + VolCacheEntry *e; + int error; + + e = get_free_entry (); + + e->cell = cell; + e->refcount = 0; + + error = get_info_byname (e, volname, ce); + if (error == 0) { + *ret = e; + ++nactive_volcacheentries; + } + return error; +} + +/* + * Add an entry for (volname, cell) to the hash table. + */ + +static int +add_entry_byid (VolCacheEntry **ret, u_int32_t id, + int32_t cell, CredCacheEntry *ce) { + int error; VolCacheEntry *e; e = get_free_entry (); @@ -452,12 +639,12 @@ add_entry (const char *volname, int32_t cell, CredCacheEntry *ce) e->cell = cell; e->refcount = 0; - if(get_info (e, volname, ce) == 0) { + error = get_info_byid (e, id, ce); + if (error == 0) { ++nactive_volcacheentries; - return e; - } else { - return NULL; + *ret = e; } + return error; } /* @@ -465,10 +652,11 @@ add_entry (const char *volname, int32_t cell, CredCacheEntry *ce) * add it. */ -VolCacheEntry * -volcache_getbyname (const char *volname, int32_t cell, CredCacheEntry *ce) +int +volcache_getbyname (const char *volname, int32_t cell, CredCacheEntry *ce, + VolCacheEntry **e, int32_t *type) { - VolCacheEntry *e; + int error = 0; struct name_ptr *n; struct name_ptr key; @@ -476,22 +664,27 @@ volcache_getbyname (const char *volname, int32_t cell, CredCacheEntry *ce) strncpy (key.name, volname, VLDB_MAXNAMELEN); key.name[VLDB_MAXNAMELEN - 1] = '\0'; - n = (struct name_ptr *)hashtabsearch (volnamehashtab, (void *)&key); - if (n == NULL) - e = add_entry (volname, cell, ce); - else - e = n->ptr; - - if (e != NULL && !volume_uptodatep (e)) { - recycle_entry (e); - e->cell = cell; - if (get_info (e, volname, ce)) - e = NULL; + for(;;) { + n = (struct name_ptr *)hashtabsearch (volnamehashtab, (void *)&key); + if (n == NULL) { + error = add_entry_byname (e, volname, cell, ce); + if (error) + return error; + continue; + } + *e = n->ptr; + *type = n->type; + ++(*e)->refcount; + if (volume_uptodatep (*e)) { + return 0; + } else { + recycle_entry (*e); + error = get_info_byname (*e, volname, ce); + --(*e)->refcount; + if (error) + return error; + } } - - if (e != NULL) - ++e->refcount; - return e; } /* @@ -499,36 +692,38 @@ volcache_getbyname (const char *volname, int32_t cell, CredCacheEntry *ce) * add it. */ -VolCacheEntry * -volcache_getbyid (u_int32_t id, int32_t cell, CredCacheEntry *ce) +int +volcache_getbyid (u_int32_t volid, int32_t cell, CredCacheEntry *ce, + VolCacheEntry **e, int32_t *type) { - VolCacheEntry *e; + int error = 0; struct num_ptr *n; struct num_ptr key; - char s[11]; - - snprintf (s, sizeof(s), "%u", id); key.cell = cell; - key.vol = id; - - n = (struct num_ptr *)hashtabsearch (volidhashtab, (void *)&key); - if (n == NULL) { - e = add_entry (s, cell, ce); - } else { - e = n->ptr; - } - - if (e != NULL && !volume_uptodatep (e)) { - recycle_entry (e); - e->cell = cell; - if (get_info (e, s, ce)) - e = NULL; + key.vol = volid; + + for(;;) { + n = (struct num_ptr *)hashtabsearch (volidhashtab, (void *)&key); + if (n == NULL) { + error = add_entry_byid (e, volid, cell, ce); + if (error) + return error; + continue; + } + *e = n->ptr; + *type = n->type; + ++(*e)->refcount; + if (volume_uptodatep (*e)) { + return 0; + } else { + recycle_entry (*e); + error = get_info_byid (*e, volid, ce); + --(*e)->refcount; + if (error) + return error; + } } - - if (e != NULL) - ++e->refcount; - return e; } /* @@ -584,44 +779,56 @@ print_entry (void *ptr, void *arg) { struct num_ptr *n = (struct num_ptr *)ptr; VolCacheEntry *e = n->ptr; - FILE *f = (FILE *)arg; int i; struct in_addr tmp; if (n->vol != e->entry.volumeId[RWVOL]) return FALSE; - fprintf (f, "cell = %d (%s)\n" - "name = \"%s\", volumeType = %d(%s), nServers = %d\n", + arla_log(ADEBVLOG, "cell = %d (%s)\n" + "name = \"%s\", nServers = %d\n", e->cell, cell_num2name (e->cell), e->entry.name, - e->entry.volumeType, volsuffixes[e->entry.volumeType], e->entry.nServers); for (i = 0; i < e->entry.nServers; ++i) { tmp.s_addr = htonl(e->entry.serverNumber[i]); - fprintf (f, "%d: server = %s, part = %d(%c), flags = %d\n", + arla_log(ADEBVLOG, "%d: server = %s, part = %d(%c), flags = %d\n", i, inet_ntoa(tmp), e->entry.serverPartition[i], 'a' + e->entry.serverPartition[i], e->entry.serverFlags[i]); } if (e->entry.flags & VLF_RWEXISTS) - fprintf (f, "rw clone: %d\n", e->entry.volumeId[RWVOL]); + arla_log(ADEBVLOG, "rw clone: %d\n", e->entry.volumeId[RWVOL]); if (e->entry.flags & VLF_ROEXISTS) - fprintf (f, "ro clone: %d\n", e->entry.volumeId[ROVOL]); + arla_log(ADEBVLOG, "ro clone: %d\n", e->entry.volumeId[ROVOL]); if (e->entry.flags & VLF_BACKEXISTS) - fprintf (f, "rw clone: %d\n", e->entry.volumeId[BACKVOL]); - fprintf (f, "refcount = %u\n\n", e->refcount); + arla_log(ADEBVLOG, "rw clone: %d\n", e->entry.volumeId[BACKVOL]); + arla_log(ADEBVLOG, "refcount = %u\n\n", e->refcount); return FALSE; } /* + * + */ + +int +volume_make_uptodate (VolCacheEntry *e, CredCacheEntry *ce) +{ + if (connected_mode != CONNECTED || + volume_uptodatep (e)) + return 0; + + return get_info_byname (e, e->entry.name, ce); +} + +/* * Print some status on the volume cache on `f'. */ void -volcache_status (FILE *f) +volcache_status (void) { - fprintf (f, "%u(%u) volume entries\n", + arla_log(ADEBVLOG, "%u(%u) volume entries\n", nactive_volcacheentries, nvolcacheentries); - hashtabforeach (volidhashtab, print_entry, f); + hashtabforeach (volidhashtab, print_entry, NULL); } diff --git a/usr.sbin/afs/src/arlad/volcache.h b/usr.sbin/afs/src/arlad/volcache.h index a6900d50a0c..3db6e2880c6 100644 --- a/usr.sbin/afs/src/arlad/volcache.h +++ b/usr.sbin/afs/src/arlad/volcache.h @@ -1,4 +1,4 @@ -/* $OpenBSD: volcache.h,v 1.1.1.1 1998/09/14 21:52:57 art Exp $ */ +/* $OpenBSD: volcache.h,v 1.2 1999/04/30 01:59:10 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,7 +41,7 @@ * Our cache of volume information. */ -/* $KTH: volcache.h,v 1.13 1998/07/29 21:29:10 assar Exp $ */ +/* $KTH: volcache.h,v 1.17 1999/04/14 15:27:37 map Exp $ */ #ifndef _VOLCACHE_ #define _VOLCACHE_ @@ -56,16 +56,18 @@ struct num_ptr { int32_t cell; u_int32_t vol; struct volcacheentry *ptr; + int32_t type; }; struct name_ptr { int32_t cell; char name[VLDB_MAXNAMELEN]; struct volcacheentry *ptr; + int32_t type; }; struct volcacheentry { - vldbentry entry; + nvldbentry entry; AFSVolSync volsync; int32_t cell; unsigned refcount; @@ -84,13 +86,17 @@ void volcache_set_rootvolume (const char *volname); void volcache_init (unsigned nentries, Bool recover); -VolCacheEntry *volcache_getbyname (const char *volname, - int32_t cell, - CredCacheEntry *ce); +int volcache_getbyname (const char *volname, + int32_t cell, + CredCacheEntry *ce, + VolCacheEntry **e, + int32_t *type); -VolCacheEntry *volcache_getbyid (u_int32_t id, - int32_t cell, - CredCacheEntry *ce); +int volcache_getbyid (u_int32_t id, + int32_t cell, + CredCacheEntry *ce, + VolCacheEntry **e, + int32_t *type); void volcache_update_volsync (VolCacheEntry *e, AFSVolSync volsync); @@ -98,9 +104,12 @@ void volcache_free (VolCacheEntry *e); void volcache_invalidate (u_int32_t id, int32_t cell); -void volcache_status (FILE *f); +int volume_make_uptodate (VolCacheEntry *e, CredCacheEntry *ce); + +void volcache_status (void); int volcache_store_state (void); #endif /* _VOLCACHE_ */ + diff --git a/usr.sbin/afs/src/include/bits.c b/usr.sbin/afs/src/include/bits.c index 6aa08cf85df..e8a09031871 100644 --- a/usr.sbin/afs/src/include/bits.c +++ b/usr.sbin/afs/src/include/bits.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bits.c,v 1.1.1.1 1998/09/14 21:52:59 art Exp $ */ +/* $OpenBSD: bits.c,v 1.2 1999/04/30 01:59:10 art Exp $ */ /* * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: bits.c,v 1.4 1998/03/28 09:24:30 lha Exp $"); +RCSID("$KTH: bits.c,v 1.6 1998/12/20 15:55:29 assar Exp $"); #endif #include <stdio.h> #include <string.h> @@ -50,10 +50,10 @@ RCSID("$KTH: bits.c,v 1.4 1998/03/28 09:24:30 lha Exp $"); static void strupr(char *s) { - char *p = s; + unsigned char *p = (unsigned char *)s; while(*p){ - if(islower((int)*p)) - *p = toupper((int)*p); + if(islower(*p)) + *p = toupper(*p); p++; } } @@ -77,7 +77,11 @@ strupr(char *s) } \ } -static void +#ifndef HAVE___ATTRIBUTE__ +#define __attribute__(x) +#endif + +static void __attribute__ ((unused)) try_signed(FILE *f, int len) { BITSIZE(signed char); @@ -90,7 +94,7 @@ try_signed(FILE *f, int len) fprintf(f, "/* There is no %d bit type */\n", len); } -static void +static void __attribute__ ((unused)) try_unsigned(FILE *f, int len) { BITSIZE(unsigned char); @@ -103,7 +107,7 @@ try_unsigned(FILE *f, int len) fprintf(f, "/* There is no %d bit type */\n", len); } -static int +static int __attribute__ ((unused)) print_bt(FILE *f, int flag) { if(flag == 0){ @@ -138,7 +142,7 @@ int main(int argc, char **argv) } fprintf(f, "/* %s -- this file was generated for %s by\n", fn, HOST); fprintf(f, " %*s %s */\n\n", strlen(fn), "", - "$KTH: bits.c,v 1.4 1998/03/28 09:24:30 lha Exp $"); + "$KTH: bits.c,v 1.6 1998/12/20 15:55:29 assar Exp $"); fprintf(f, "#ifndef %s\n", hb); fprintf(f, "#define %s\n", hb); fprintf(f, "\n"); diff --git a/usr.sbin/afs/src/include/config.h b/usr.sbin/afs/src/include/config.h index 4ac6990c716..aa8a53346de 100644 --- a/usr.sbin/afs/src/include/config.h +++ b/usr.sbin/afs/src/include/config.h @@ -1,10 +1,12 @@ -/* $OpenBSD: config.h,v 1.1.1.1 1998/09/14 21:52:59 art Exp $ */ /* include/config.h. Generated automatically by configure. */ /* include/config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if you have a working `mmap' system call. */ #define HAVE_MMAP 1 +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void @@ -14,6 +16,9 @@ /* Define if you can safely include both <sys/time.h> and <time.h>. */ #define TIME_WITH_SYS_TIME 1 +/* Define if the X Window System is missing or not being used. */ +/* #undef X_DISPLAY_MISSING */ + /* Define this if we can include both sys/dir.h and dirent.h */ #define USE_SYS_DIR_H 1 @@ -23,6 +28,12 @@ /* Define this if struct winsize is declared in sys/termios.h */ #define HAVE_STRUCT_WINSIZE 1 +/* Define this if struct msghdr is declared in sys/socket.h */ +#define HAVE_STRUCT_MSGHDR 1 + +/* Define this if struct iovec is declared in sys/uio.h */ +#define HAVE_STRUCT_IOVEC 1 + /* Define this if struct winsize have ws_xpixel */ #define HAVE_WS_XPIXEL 1 @@ -33,7 +44,7 @@ #define SOCKADDR_HAS_SA_LEN 1 /* define if the system is missing a prototype for strtok_r() */ -#define NEED_STRTOK_R_PROTO 1 +/* #undef NEED_STRTOK_R_PROTO */ /* define if you have h_errno */ #define HAVE_H_ERRNO 1 @@ -71,6 +82,12 @@ /* Define if you have the FOUR_ARGUMENT_VFS_BUSY function. */ #define HAVE_FOUR_ARGUMENT_VFS_BUSY 1 +/* Define if you have the FOUR_ARGUMENT_VFS_OBJECT_CREATE function. */ +/* #undef HAVE_FOUR_ARGUMENT_VFS_OBJECT_CREATE */ + +/* Define if you have the ONE_ARGUMENT_VOP_LOCK function. */ +/* #undef HAVE_ONE_ARGUMENT_VOP_LOCK */ + /* Define if you have the THREE_ARGUMENT_VFS_BUSY function. */ /* #undef HAVE_THREE_ARGUMENT_VFS_BUSY */ @@ -272,6 +289,9 @@ /* Define if you have the tgetent function. */ #define HAVE_TGETENT 1 +/* Define if you have the thr_yield function. */ +/* #undef HAVE_THR_YIELD */ + /* Define if you have the unsetenv function. */ #define HAVE_UNSETENV 1 @@ -320,11 +340,17 @@ /* Define if you have the <arpa/nameser.h> header file. */ #define HAVE_ARPA_NAMESER_H 1 +/* Define if you have the <asm/smp_lock.h> header file. */ +/* #undef HAVE_ASM_SMP_LOCK_H */ + +/* Define if you have the <asm/smplock.h> header file. */ +/* #undef HAVE_ASM_SMPLOCK_H */ + /* Define if you have the <crypt.h> header file. */ /* #undef HAVE_CRYPT_H */ /* Define if you have the <dbm.h> header file. */ -/* #undef HAVE_DBM_H */ +#define HAVE_DBM_H 1 /* Define if you have the <dirent.h> header file. */ #define HAVE_DIRENT_H 1 @@ -350,9 +376,24 @@ /* Define if you have the <libelf/nlist.h> header file. */ /* #undef HAVE_LIBELF_NLIST_H */ +/* Define if you have the <linux/devfs_fs.h> header file. */ +/* #undef HAVE_LINUX_DEVFS_FS_H */ + +/* Define if you have the <linux/modversions.h> header file. */ +/* #undef HAVE_LINUX_MODVERSIONS_H */ + /* Define if you have the <linux/types.h> header file. */ /* #undef HAVE_LINUX_TYPES_H */ +/* Define if you have the <machine/alpha/asm.h> header file. */ +/* #undef HAVE_MACHINE_ALPHA_ASM_H */ + +/* Define if you have the <machine/asm.h> header file. */ +#define HAVE_MACHINE_ASM_H 1 + +/* Define if you have the <machine/regdef.h> header file. */ +/* #undef HAVE_MACHINE_REGDEF_H */ + /* Define if you have the <miscfs/genfs/genfs.h> header file. */ /* #undef HAVE_MISCFS_GENFS_GENFS_H */ @@ -383,6 +424,9 @@ /* Define if you have the <pwd.h> header file. */ #define HAVE_PWD_H 1 +/* Define if you have the <regdef.h> header file. */ +/* #undef HAVE_REGDEF_H */ + /* Define if you have the <resolv.h> header file. */ #define HAVE_RESOLV_H 1 @@ -398,9 +442,6 @@ /* Define if you have the <sys/cdefs.h> header file. */ #define HAVE_SYS_CDEFS_H 1 -/* Define if you have the <sys/dirent.h> header file. */ -#define HAVE_SYS_DIRENT_H 1 - /* Define if you have the <sys/filedesc.h> header file. */ #define HAVE_SYS_FILEDESC_H 1 @@ -416,6 +457,9 @@ /* Define if you have the <sys/mman.h> header file. */ #define HAVE_SYS_MMAN_H 1 +/* Define if you have the <sys/module.h> header file. */ +/* #undef HAVE_SYS_MODULE_H */ + /* Define if you have the <sys/mount.h> header file. */ #define HAVE_SYS_MOUNT_H 1 @@ -446,6 +490,9 @@ /* Define if you have the <sys/stat.h> header file. */ #define HAVE_SYS_STAT_H 1 +/* Define if you have the <sys/syscallargs.h> header file. */ +#define HAVE_SYS_SYSCALLARGS_H 1 + /* Define if you have the <sys/sysconfig.h> header file. */ /* #undef HAVE_SYS_SYSCONFIG_H */ @@ -470,6 +517,12 @@ /* Define if you have the <sys/uio.h> header file. */ #define HAVE_SYS_UIO_H 1 +/* Define if you have the <sys/user.h> header file. */ +#define HAVE_SYS_USER_H 1 + +/* Define if you have the <sys/utsname.h> header file. */ +#define HAVE_SYS_UTSNAME_H 1 + /* Define if you have the <sys/vfs.h> header file. */ /* #undef HAVE_SYS_VFS_H */ @@ -482,6 +535,24 @@ /* Define if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 +/* Define if you have the <vm/vm.h> header file. */ +#define HAVE_VM_VM_H 1 + +/* Define if you have the <vm/vm_extern.h> header file. */ +#define HAVE_VM_VM_EXTERN_H 1 + +/* Define if you have the <vm/vm_object.h> header file. */ +#define HAVE_VM_VM_OBJECT_H 1 + +/* Define if you have the <vm/vm_pager.h> header file. */ +#define HAVE_VM_VM_PAGER_H 1 + +/* Define if you have the <vm/vm_zone.h> header file. */ +/* #undef HAVE_VM_VM_ZONE_H */ + +/* Define if you have the <vm/vnode_pager.h> header file. */ +#define HAVE_VM_VNODE_PAGER_H 1 + /* Define if you have the curses library (-lcurses). */ /* #undef HAVE_LIBCURSES */ @@ -531,6 +602,7 @@ #define HAVE_REGISTER_T 1 /* #undef HAVE_INT32 */ /* #undef HAVE_U_INT32 */ +/* #undef HAVE_INTPTR_T */ #define EFF_NTOHL ntohl @@ -538,7 +610,7 @@ #define RCSID(msg) \ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } -#define VERSION "0.9" +#define VERSION "0.24pre" #define PACKAGE "arla" /* Check for posix signals */ @@ -558,6 +630,10 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* We have krb_principal from kth-krb ? */ #define HAVE_KRB_PRINCIPAL 1 +/* Define if you have a krb_get_err_text (otherwise, you should really + get more modern kerberos code) */ +#define HAVE_KRB_GET_ERR_TEXT 1 + /* If we have _res */ /* #undef HAVE__RES */ @@ -573,6 +649,15 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your kernel has a vop_noislocked */ /* #undef HAVE_KERNEL_VOP_NOISLOCKED */ +/* Define if your kernel has a vop_stdnolock */ +/* #undef HAVE_KERNEL_VOP_STDLOCK */ + +/* Define if your kernel has a vop_stdnounlock */ +/* #undef HAVE_KERNEL_VOP_STDUNLOCK */ + +/* Define if your kernel has a vop_stdnoislocked */ +/* #undef HAVE_KERNEL_VOP_STDISLOCKED */ + /* Define if your kernel has a vop_revoke */ /* #undef HAVE_KERNEL_VOP_REVOKE */ @@ -588,17 +673,50 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your kernel has a genfs_revoke */ /* #undef HAVE_KERNEL_GENFS_REVOKE */ +/* Define if your kernel has a vfs_opv_init */ +#define HAVE_KERNEL_VFS_OPV_INIT 1 + /* Define if your kernel has a vfs_opv_init_default */ #define HAVE_KERNEL_VFS_OPV_INIT_DEFAULT 1 +/* Define if your kernel has a vfs_opv_init_explicit */ +#define HAVE_KERNEL_VFS_OPV_INIT_EXPLICIT 1 + +/* Define if your kernel has a vfs_add_vnodeops */ +/* #undef HAVE_KERNEL_VFS_ADD_VNODEOPS */ + /* Define if your kernel has a vfs_attach */ /* #undef HAVE_KERNEL_VFS_ATTACH */ +/* Define if your kernel has a vfs_register */ +#define HAVE_KERNEL_VFS_REGISTER 1 + /* Define if your kernel has a vfs_getnewfsid */ #define HAVE_KERNEL_VFS_GETNEWFSID 1 -/* Define if your kernel has a vfs_opv_init_explicit */ -#define HAVE_KERNEL_VFS_OPV_INIT_EXPLICIT 1 +/* Define if your kernel has a vfs_getvfs */ +#define HAVE_KERNEL_VFS_GETVFS 1 + +/* Define if your kernel has a vfs_object_create */ +/* #undef HAVE_KERNEL_VFS_OBJECT_CREATE */ + +/* Define if your kernel has a zfreei */ +/* #undef HAVE_KERNEL_ZFREEI */ + +/* Define if your kernel has a vfs_cache_lookup */ +/* #undef HAVE_KERNEL_VFS_CACHE_LOOKUP */ + +/* Define if your kernel has a vnode_pager_generic_putpages */ +/* #undef HAVE_KERNEL_VNODE_PAGER_GENERIC_PUTPAGES */ + +/* Define if your kernel has a vnode_pager_generic_getpages */ +/* #undef HAVE_KERNEL_VNODE_PAGER_GENERIC_GETPAGES */ + +/* Define if your kernel has a vnode_pager_setsize */ +#define HAVE_KERNEL_VNODE_PAGER_SETSIZE 1 + +/* Define if your kernel has a doforce */ +#define HAVE_KERNEL_DOFORCE 1 /* Define if your struct dirent has a field d_type */ #define HAVE_STRUCT_DIRENT_D_TYPE 1 @@ -606,8 +724,11 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your struct vfsconf has a field vfc_refcount */ #define HAVE_STRUCT_VFSCONF_VFC_REFCOUNT 1 +/* Define if your struct vfsconf has a field vfc_mountroot */ +/* #undef HAVE_STRUCT_VFSCONF_VFC_MOUNTROOT */ + /* Define if your struct uio has a field uio_procp */ -/* #undef HAVE_STRUCT_UIO_UIO_PROCP */ +#define HAVE_STRUCT_UIO_UIO_PROCP 1 /* Define if your struct vfsops has a field vfs_opv_descs */ /* #undef HAVE_STRUCT_VFSOPS_VFS_OPV_DESCS */ @@ -615,6 +736,15 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your struct vfsops has a field vfs_name */ /* #undef HAVE_STRUCT_VFSOPS_VFS_NAME */ +/* Define if your struct vfsops has a field vfs_oid */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_OID */ + +/* Define if your struct vfsops has a field vfs_checkexp */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_CHECKEXP */ + +/* Define if your struct vfsops has a field vfs_uninit */ +/* #undef HAVE_STRUCT_VFSOPS_VFS_UNINIT */ + /* Define if you want to use mmap:ed time */ /* #undef USE_MMAPTIME */ @@ -624,6 +754,9 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* Define if your hstrerror need proto */ /* #undef NEED_HSTRERROR_PROTO */ +/* define if the system is missing a prototype for inet_aton() */ +/* #undef NEED_INET_ATON_PROTO */ + /* Define if you have gnu libc */ /* #undef HAVE_GLIBC */ @@ -646,12 +779,68 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } /* #undef HAVE_LINUX_KERNEL_U_INT32_T */ /* #undef HAVE_LINUX_KERNEL_U_INT64_T */ +/* Define this if you have a struct new_stat */ +/* #undef HAVE_STRUCT_NEW_STAT */ + /* Define this if you have a type vop_t */ /* #undef HAVE_VOP_T */ /* Define this is you have a vfssw */ /* #undef HAVE_VFSSW */ +/* Define this if struct mount have mnt_syncer */ +#define HAVE_STRUCT_MOUNT_MNT_SYNCER 1 + /* Define this if struct proc have p_sigmask */ #define HAVE_STRUCT_PROC_P_SIGMASK 1 +/* Define this if you have struct a_flags instead of a_waitfor in vop_fseek*/ +/* #undef HAVE_STRUCT_VOP_FSYNC_ARGS_A_FLAGS */ + +/* Define this if struct proc have p_retval */ +/* #undef HAVE_STRUCT_PROC_P_RETVAL */ + +/* Define this if struct file_operations has flush */ +/* #undef HAVE_STRUCT_FILE_OPERATIONS_FLUSH */ + +/* Define this if the read_super superoperation takes the dir_d argument */ +/* #undef HAVE_READ_SUPER_FOUR_ARGS */ + +/* Define this if the follow_link inode-operation takes the follow argument */ +/* #undef HAVE_FOLLOW_LINK_THREE_ARGS */ + +/* Define this if your full_name_hash works with 8bit characters */ +/* #undef HAVE_FULL_NAME_HASH_8BIT */ + +/* Define if your getvfsbyname takes two arguments */ +/* #undef HAVE_GETVFSBYNAME_TWO_ARGS */ + +/* Define if you have DIRSIZ in <dirent.h> */ +/* #undef DIRSIZ_IN_DIRENT_H */ + +/* Define if you have DIRSIZ in <sys/dir.h> */ +#define DIRSIZ_IN_SYS_DIR_H 1 + +/* Define if you have GENERIC_DIRENT in <sys/dirent.h> */ +/* #undef GENERIC_DIRSIZ_IN_SYS_DIRENT_H */ + +/* Define if running on Irix 6.4 or later */ +/* #undef IRIX_64 */ + +/* + * Defintions that are ugly but needed to get all the symbols used + */ + +/* + * Defining this enables lots of useful (and used) extensions on + * glibc-based systems such as Linux + */ + +#define _GNU_SOURCE + +/* + * Defining this enables us to get the definition of `sigset_t' and + * other importatnt definitions on Solaris. + */ + +#define __EXTENSIONS__ diff --git a/usr.sbin/afs/src/include/version.h b/usr.sbin/afs/src/include/version.h new file mode 100644 index 00000000000..bce23be694a --- /dev/null +++ b/usr.sbin/afs/src/include/version.h @@ -0,0 +1,2 @@ +char *arla_long_version = "@(#)$Version: arla-0.24pre by art on kurrent.stacken.kth.se (sparc-unknown-openbsd2.5) Wed Apr 28 18:54:29 MEST 1999 $"; +char *arla_version = "arla-0.24pre"; diff --git a/usr.sbin/afs/src/lib/ko/gensysname.c b/usr.sbin/afs/src/lib/ko/gensysname.c index 05fe0d08614..eeaaeaa6879 100644 --- a/usr.sbin/afs/src/lib/ko/gensysname.c +++ b/usr.sbin/afs/src/lib/ko/gensysname.c @@ -1,6 +1,6 @@ -/* $OpenBSD: gensysname.c,v 1.1.1.1 1998/09/14 21:53:00 art Exp $ */ +/* $OpenBSD: gensysname.c,v 1.2 1999/04/30 01:59:11 art Exp $ */ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,9 +39,11 @@ #include "ko_locl.h" -RCSID("$KTH: gensysname.c,v 1.13 1998/08/23 22:50:24 assar Exp $"); +RCSID("$KTH: gensysname.c,v 1.24 1999/01/04 23:21:29 lha Exp $"); typedef int (*test_sysname)(void); +typedef void (*gen_sysname)(char*, size_t, const char*, + const char*, const char*); struct sysname { const char *sysname; @@ -49,9 +51,10 @@ struct sysname { const char *vendor; const char *os; test_sysname atest; + gen_sysname gen; }; -enum { O_C, O_TEXT, O_MACHINE } output = O_TEXT; +enum { OUTPUT_C, OUTPUT_TEXT, OUTPUT_MACHINE } output = OUTPUT_TEXT; /* * HELP: @@ -76,17 +79,48 @@ linux_glibc_test(void) return ret == 0; } +#ifdef HAVE_SYS_UTSNAME_H +static void +bsd_gen_sysname(char *buf, + size_t len, + const char *cpu, + const char *vendor, + const char *os) +{ + struct utsname uts; + int major, minor; + const char *name; + if(uname(&uts) < 0) { + warn("uname"); + strcpy(buf, "bsdhost"); + return; + } + if(strcmp(uts.sysname, "FreeBSD") == 0) + name = "fbsd"; + else if(strcmp(uts.sysname, "NetBSD") == 0) + name = "nbsd"; + else if(strcmp(uts.sysname, "OpenBSD") == 0) + name = "obsd"; + else if(strcmp(uts.sysname, "BSD/OS") == 0) + name = "bsdi"; + else + name = "bsd"; + /* this is perhaps a bit oversimplified */ + if(sscanf(uts.release, "%d.%d", &major, &minor) == 2) + snprintf(buf, len, "%s_%s%d%d", uts.machine, name, major, minor); + else + snprintf(buf, len, "%s_%s", uts.machine, name); +} +#endif + struct sysname sysnames[] = { - { "sparc_nbsd13", "sparc", "*", "netbsd1.3*", NULL }, - { "sparc_obsd23", "sparc", "*", "openbsd2.3*", NULL }, { "sparc_linux6", "sparc", "*", "linux-gnu*", &linux_glibc_test }, { "sparc_linux5", "sparc", "*", "linux-gnu*", NULL }, - { "i386_obsd23", "i*86*", "*", "openbsd2.3*", NULL }, - { "i386_fbsd30", "i*86*", "*", "freebsd3.0*", NULL }, { "i386_linux6", "i*86*", "*pc*", "linux-gnu*", &linux_glibc_test }, { "i386_linux5", "i*86*", "*pc*", "linux-gnu*", NULL }, { "alpha_linux6", "alpha", "*", "linux-gnu*", &linux_glibc_test }, { "alpha_linux5", "alpha", "*", "linux-gnu*", NULL }, + { "alpha_dux40", "alpha", "*", "osf4.0*", NULL }, { "sun4x_54", "sparc", "*", "solaris2.4*", NULL }, { "sun4x_551", "sparc", "*", "solaris2.5.1*", NULL }, { "sun4x_55", "sparc", "*", "solaris2.5*", NULL }, @@ -97,6 +131,11 @@ struct sysname sysnames[] = { { "sunx86_55", "i386", "*", "solaris2.5*", NULL }, { "sunx86_56", "i386", "*", "solaris2.6*", NULL }, { "sunx86_57", "i386", "*", "solaris2.7*", NULL }, + { "i386_nt35", "i*86*", "*", "cygwin*", NULL }, +#ifdef HAVE_SYS_UTSNAME_H + /* catch-all bsd entry */ + { "", "*", "*", "*bsd*", NULL, &bsd_gen_sysname }, +#endif {NULL} }; @@ -104,14 +143,14 @@ static void printsysname(const char *sysname) { switch (output) { - case O_TEXT: + case OUTPUT_TEXT: printf("%s\n", sysname); break; - case O_MACHINE: + case OUTPUT_MACHINE: printf("%s\n", sysname); break; - case O_C: - printf("/* Generated from $KTH: gensysname.c,v 1.13 1998/08/23 22:50:24 assar Exp $ */\n"); + case OUTPUT_C: + printf("/* Generated from $KTH: gensysname.c,v 1.24 1999/01/04 23:21:29 lha Exp $ */\n"); printf("const char *arla_getsysname(void) { return \"%s\" ; }\n", sysname); break; @@ -143,7 +182,7 @@ struct getargs args[] = { static void usage(void) { - arg_printusage(args, NULL, "[sysname]"); + arg_printusage(args, NULL, "[sysname]", 0); exit(1); } @@ -190,14 +229,14 @@ main(int argc, char **argv) usage(); if (versionflag) - errx(0, "Version: $KTH: gensysname.c,v 1.13 1998/08/23 22:50:24 assar Exp $"); + errx(0, "Version: $KTH: gensysname.c,v 1.24 1999/01/04 23:21:29 lha Exp $"); if (ccodeflag) - output = O_C; + output = OUTPUT_C; if (humanflag) - output = O_TEXT; + output = OUTPUT_TEXT; if (machineflag) - output = O_MACHINE; + output = OUTPUT_MACHINE; if (sysnameflag) { printf ("%s-%s-%s\n", cpu, vendor, os); @@ -221,13 +260,20 @@ main(int argc, char **argv) try_parsing (&argc, &argv, &os); while (sysname->sysname && !found) { + char sn[64]; if (!strmatch(sysname->cpu, cpu) && !strmatch(sysname->vendor, vendor) && !strmatch(sysname->os, os) && (sysname->atest == NULL || ((*(sysname->atest))()))) { found = 1; - printsysname(sysname->sysname); + if(sysname->gen != NULL) + (*sysname->gen)(sn, sizeof(sn), cpu, vendor, os); + else { + strncpy(sn, sysname->sysname, sizeof(sn)); + sn[sizeof(sn) - 1] = '\0'; + } + printsysname(sn); } sysname++; } diff --git a/usr.sbin/afs/src/lib/ko/ko.h b/usr.sbin/afs/src/lib/ko/ko.h index 58d59359eed..47bf9b4c14f 100644 --- a/usr.sbin/afs/src/lib/ko/ko.h +++ b/usr.sbin/afs/src/lib/ko/ko.h @@ -1,6 +1,6 @@ -/* $OpenBSD: ko.h,v 1.1.1.1 1998/09/14 21:53:00 art Exp $ */ +/* $OpenBSD: ko.h,v 1.2 1999/04/30 01:59:11 art Exp $ */ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,12 +37,13 @@ * SUCH DAMAGE. */ -/* $KTH: ko.h,v 1.10 1998/07/25 15:18:48 map Exp $ */ +/* $KTH: ko.h,v 1.16 1999/03/03 15:39:51 assar Exp $ */ #ifndef __KO_H #define __KO_H 1 #include <atypes.h> +#include <bool.h> typedef int32_t koerr_t; @@ -60,26 +61,48 @@ const char *arla_getsysname(void); /* - * Cell manglening + * Cell managing */ +typedef struct { + const char *name; + struct in_addr addr; +} cell_db_entry; + +typedef struct { + int32_t id; /* Cell-ID */ + const char *name; /* Domain-style name */ + const char *expl; /* Longer name */ + unsigned ndbservers; /* # of database servers */ + cell_db_entry *dbservers; /* Database servers */ + enum { NOSUID_CELL, SUID_CELL } suid_cell ; /* if this is a suid cell */ +} cell_entry; + void cell_init (int cellcachesize); -struct in_addr cell_finddbserver (int32_t cell); -u_long cell_listdbserver (int32_t cell, int index); +const cell_db_entry *cell_dbservers (int32_t cell, int *); + const char *cell_findnamedbbyname (const char *cell); const char *cell_getthiscell (void); const char *cell_getcellbyhost(const char *host); int32_t cell_name2num (const char *cell); const char *cell_num2name (int32_t cell); +cell_entry *cell_get_by_name (const char *cellname); +cell_entry *cell_get_by_id (int32_t cell); +cell_entry *cell_new (const char *name); +Bool cell_issuid (cell_entry *c); +Bool cell_issuid_by_num (int32_t cell); +Bool cell_issuid_by_name (const char *cell); +Bool cell_setsuid_by_num (int32_t cell); -/* NIY -int cell_serverdown (struct in_addr addr); -int cell_cellup_p (int32_t cell); -int cell_probe(int32_t cell); -int cell_probeserver(struct in_addr addr); -*/ +/* + * misc vl + */ -#endif +#include <vldb.h> +#include <volumeserver.h> +void vldb2vldbN (const vldbentry *old, nvldbentry *new); +void volintInfo2xvolintInfo (const volintInfo *old, xvolintInfo *new); +#endif /* __KO_H */ diff --git a/usr.sbin/afs/src/lib/ko/ko_locl.h b/usr.sbin/afs/src/lib/ko/ko_locl.h index b998d9a68ce..fff5c4b402a 100644 --- a/usr.sbin/afs/src/lib/ko/ko_locl.h +++ b/usr.sbin/afs/src/lib/ko/ko_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ko_locl.h,v 1.1.1.1 1998/09/14 21:52:59 art Exp $ */ +/* $OpenBSD: ko_locl.h,v 1.2 1999/04/30 01:59:11 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,7 +39,7 @@ /* * Include file for whole arlad - * $KTH: ko_locl.h,v 1.2 1998/07/16 01:14:26 lha Exp $ + * $KTH: ko_locl.h,v 1.4 1999/01/03 08:27:07 lha Exp $ */ #ifdef HAVE_CONFIG_H @@ -61,6 +61,9 @@ #include <sys/uio.h> #include <sys/mman.h> #include <sys/stat.h> +#ifdef HAVE_SYS_UTSNAME_H +#include <sys/utsname.h> +#endif #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> @@ -73,6 +76,8 @@ #include <hash.h> #include <ip.h> +#include <bool.h> + #include "ko.h" #include "kodebug.h" diff --git a/usr.sbin/afs/src/lib/ko/kocell.c b/usr.sbin/afs/src/lib/ko/kocell.c index 47c44b01c33..f7e195e9156 100644 --- a/usr.sbin/afs/src/lib/ko/kocell.c +++ b/usr.sbin/afs/src/lib/ko/kocell.c @@ -1,6 +1,6 @@ -/* $OpenBSD: kocell.c,v 1.1.1.1 1998/09/14 21:53:00 art Exp $ */ +/* $OpenBSD: kocell.c,v 1.2 1999/04/30 01:59:11 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -41,16 +41,8 @@ * Cell information */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#ifdef HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif +#include "ko_locl.h" + #ifdef HAVE_ARPA_NAMESER_H #include <arpa/nameser.h> #endif @@ -59,33 +51,19 @@ #endif #ifdef KERBEROS -#include <kerberosIV/krb.h> +#include <krb.h> #endif -#include "ko_locl.h" #include "resolve.h" -RCSID("$KTH: kocell.c,v 1.13 1998/07/28 14:54:08 assar Exp $"); +RCSID("$KTH: kocell.c,v 1.19 1999/01/04 23:11:00 assar Exp $"); #define TRANSARCSYSCONFDIR "/usr/vice/etc" #define CELLFILENAME "CellServDB" #define THISCELLFILENAME "ThisCell" - +#define SUIDCELLSFILENAME "SuidCells" #define DEFCELLCACHESIZE 499 -typedef struct { - const char *name; - struct in_addr addr; -} DbServerEntry; - -typedef struct { - int32_t id; /* Cell-ID */ - const char *name; /* Domain-style name */ - const char *expl; /* Longer name */ - unsigned ndbservs; /* # of database servers */ - DbServerEntry *dbservs; /* Database servers */ -} CellEntry; - /* * hash tables by name and by number */ @@ -105,8 +83,8 @@ static char *thiscell = NULL; static int cellnamecmp (void *a, void *b) { - CellEntry *c1 = (CellEntry *)a; - CellEntry *c2 = (CellEntry *)b; + cell_entry *c1 = (cell_entry *)a; + cell_entry *c2 = (cell_entry *)b; return strcmp (c1->name, c2->name); } @@ -114,7 +92,7 @@ cellnamecmp (void *a, void *b) static unsigned cellnamehash (void *a) { - CellEntry *c = (CellEntry *)a; + cell_entry *c = (cell_entry *)a; return hashadd (c->name); } @@ -122,8 +100,8 @@ cellnamehash (void *a) static int cellnumcmp (void *a, void *b) { - CellEntry *c1 = (CellEntry *)a; - CellEntry *c2 = (CellEntry *)b; + cell_entry *c1 = (cell_entry *)a; + cell_entry *c2 = (cell_entry *)b; return c1->id != c2->id; } @@ -131,77 +109,191 @@ cellnumcmp (void *a, void *b) static unsigned cellnumhash (void *a) { - CellEntry *c = (CellEntry *)a; + cell_entry *c = (cell_entry *)a; return c->id; } /* - * Record this cell in the hashtable - */ - -static void -recordcell (CellEntry *c, int dbnum, DbServerEntry *dbservs) -{ - if(dbnum == 0) - KODEB (KODEBMISC, ("No db-servers for cell %s\n", c->name)); - - c->ndbservs = dbnum; - c->dbservs = (DbServerEntry*)malloc (dbnum * sizeof(DbServerEntry)); - if (c->dbservs == NULL) - err (1, "malloc %u", dbnum * sizeof(DbServerEntry)); - memcpy (c->dbservs, dbservs, dbnum * sizeof (DbServerEntry)); - - hashtabadd (cellnamehtab, c); - hashtabadd (cellnumhtab, c); -} - -/* * New cell from cellserver-database file */ -static CellEntry * -newcell (const char *line, int *dbnum) +static cell_entry * +newcell (char *line) { - static long cellno = 0; char *hash; - CellEntry *c; + cell_entry *c; int len; - char *tmp; - c = (CellEntry *)malloc (sizeof (*c)); - if (c == NULL) - err (1, "malloc %u", sizeof(*c)); len = strcspn (line, " \t#"); - tmp = malloc (len + 1); - if (tmp == NULL) - err (1, "strdup"); - strncpy (tmp, line, len); - tmp[len] = '\0'; - c->name = tmp; - if (strcmp (c->name, cell_getthiscell ()) == 0) - c->id = 0; - else - c->id = ++cellno; + line[len] = '\0'; + c = cell_new (line); + if (c == NULL) + err (1, "malloc failed"); + line += len + 1; hash = strchr (line, '#'); if (hash != NULL) { c->expl = strdup (hash+1); if (c->expl == NULL) err (1, "strdup"); - } else - c->expl = NULL; - *dbnum = 0; + } return c; } /* + * Record this cell in the hashtable + */ + +static void +recordcell (cell_entry *c, int dbnum, cell_db_entry *dbservers) +{ + if(dbnum == 0) + KODEB (KODEBMISC, ("No db-servers for cell %s\n", c->name)); + + c->ndbservers = dbnum; + c->dbservers = (cell_db_entry *)malloc (dbnum * sizeof(cell_db_entry)); + if (c->dbservers == NULL) + err (1, "malloc %u", dbnum * sizeof(cell_db_entry)); + memcpy (c->dbservers, dbservers, dbnum * sizeof (cell_db_entry)); +} + +/* + * try to lookup `cell' in DNS + */ + +static void +try_to_find_cell(const char *cell) +{ + struct dns_reply *r; + struct resource_record *rr; + cell_entry *c = NULL; + int dbnum = 0; + cell_db_entry dbservers[256]; + + r = dns_lookup(cell, "AFSDB"); + if (r == NULL) + return; + for(rr = r->head; rr;rr=rr->next){ + switch(rr->type){ + case T_AFSDB: { + struct mx_record *mx = (struct mx_record*)rr->u.data; + + if (mx->preference != 1) { + KODEB (KODEBMISC, + ("Ignoring host with cell type %d in cell %s", + mx->preference, c->name)); + break; + } + if (c == NULL) + c = cell_new (cell); + if (dbnum >= sizeof (dbservers) / sizeof(*dbservers)) { + KODEB (KODEBMISC, ("Too many database servers for " + "cell %s. Ignoring\n", c->name)); + break; + } + dbservers[dbnum].name = strdup (mx->domain); + if (dbservers[dbnum].name == NULL) + err (1, "strdup"); + dbservers[dbnum].addr.s_addr = inet_addr ("0.0.0.0"); + ++dbnum; + break; + } + } + } + for(rr = r->head; rr;rr=rr->next){ + int i; + + switch(rr->type){ + case T_A: { + for (i = 0; i < dbnum; i++) { + if (strcmp(dbservers[i].name,rr->domain) == 0) { + dbservers[i].addr = *(rr->u.a); + break; + } + } + } + } + } + if (c) + recordcell (c, dbnum, dbservers); + dns_free_data(r); +} + +/* + * + */ + +cell_entry * +cell_get_by_name (const char *cellname) +{ + cell_entry key, *data; + + key.name = cellname; + data = (cell_entry *)hashtabsearch (cellnamehtab, &key); + if (data == NULL) { + try_to_find_cell (cellname); + data = (cell_entry *)hashtabsearch (cellnamehtab, &key); + } + return data; +} + +/* + * + */ + +cell_entry * +cell_get_by_id (int32_t cell) +{ + cell_entry key; + + key.id = cell; + return (cell_entry *)hashtabsearch (cellnumhtab, &key); +} + +/* + * cells are assigned monotonically increasing numbers + */ + +static long cellno = 0; + +/* + * + */ + +cell_entry * +cell_new (const char *name) +{ + cell_entry *c; + + c = (cell_entry *)malloc (sizeof (*c)); + if (c == NULL) + return NULL; + c->name = strdup (name); + if (c->name == NULL) { + free (c); + return NULL; + } + if (strcmp (c->name, cell_getthiscell ()) == 0) + c->id = 0; + else + c->id = ++cellno; + c->expl = NULL; + c->ndbservers = 0; + c->dbservers = NULL; + c->suid_cell = NOSUID_CELL; + hashtabadd (cellnamehtab, c); + hashtabadd (cellnumhtab, c); + return c; +} + +/* * Read one line of database information. */ static int -readdb (char *line, CellEntry* c, int *dbnum, int maxdbs, - DbServerEntry *dbservs, int lineno) +readdb (char *line, cell_entry* c, int *dbnum, int maxdbs, + cell_db_entry *dbservs, int lineno) { struct in_addr numaddr; char *hostname; @@ -236,10 +328,10 @@ readcellservdb (const char *filename) { FILE *f; char line[256]; - CellEntry *c = NULL; + cell_entry *c = NULL; int lineno = 0; int dbnum; - DbServerEntry dbservs[256]; + cell_db_entry dbservs[256]; f = fopen (filename, "r"); if (f == NULL) { @@ -260,7 +352,8 @@ readcellservdb (const char *filename) if (*line == '>') { if (c != NULL) recordcell (c, dbnum, dbservs); - c = newcell (line + 1, &dbnum); + c = newcell (line + 1); + dbnum = 0; } else { if (readdb(line, c, &dbnum, sizeof (dbservs) / sizeof(*dbservs), @@ -295,6 +388,7 @@ readthiscell (const char *filename) filename); return 1; } + cell[sizeof(cell)-1] = '\0'; if (cell[strlen(cell) - 1] == '\n') cell[strlen(cell) - 1] = '\0'; thiscell = strdup (cell); @@ -305,6 +399,42 @@ readthiscell (const char *filename) } /* + * Read suidcells file and set suidcell flag + */ + +static int +readsuidcell (const char *filename) +{ + FILE *f; + char cell[256]; + + f = fopen (filename, "r"); + if (f == NULL) { + fprintf(stderr, "Can't open file %s.\n", filename); + return 1; + } + + while (fgets (cell, sizeof(cell), f) != NULL) { + int i; + cell_entry *e; + + cell[sizeof(cell)-1] = '\0'; + i = strlen (cell); + if (cell[i - 1] == '\n') + cell[i - 1] = '\0'; + + e = cell_get_by_name (cell); + if (e == NULL) { + fprintf (stderr, "cell %s doesn't exist in the db\n", cell); + } else { + e->suid_cell = SUID_CELL; + } + } + fclose (f); + return 0; +} + +/* * Initialize the cache of cell information. */ @@ -348,62 +478,31 @@ cell_init (int cellcachesize) "will use DNS AFSDB entries\n"); } } + if (readsuidcell (SYSCONFDIR "/" SUIDCELLSFILENAME)) { + fprintf (stderr, "Falling back on: " TRANSARCSYSCONFDIR "\n"); + if (readsuidcell (TRANSARCSYSCONFDIR "/" SUIDCELLSFILENAME)) + fprintf (stderr, "Cant read suid cells, ignoring\n"); + } } /* - * Find a DB server to talk to for a given cell. + * Return all db servers for `cell' with the count in `num'. + * NULL on error. */ -struct in_addr -cell_finddbserver (int32_t cell) +const cell_db_entry * +cell_dbservers (int32_t cell, int *num) { - CellEntry key; - CellEntry *data; - struct in_addr addr; - - key.id = cell; - data = hashtabsearch (cellnumhtab, &key); - if (data == NULL) { - KODEB (KODEBMISC, ("Cannot find cell %d\n", cell)); - return addr; - } - if (data->ndbservs == 0) { - KODEB (KODEBMISC, ("No DB servers for cell %d\n", cell)); - return addr; - } - if (ipgetaddr (data->dbservs[0].name, &addr)) - return addr; - else - return data->dbservs[0].addr; -} - -/* - * Return DB server number "index" for a given cell. - */ + cell_entry *data = cell_get_by_id (cell); -u_long -cell_listdbserver (int32_t cell, int index) -{ - CellEntry key; - CellEntry *data; - struct in_addr addr; - - key.id = cell; - data = hashtabsearch (cellnumhtab, &key); if (data == NULL) { KODEB (KODEBMISC, ("Cannot find cell %d\n", cell)); - return 0; - } - if (data->ndbservs <= index) { - return 0; + return NULL; } - if (ipgetaddr (data->dbservs[index].name, &addr)) - return addr.s_addr; - else - return data->dbservs[index].addr.s_addr; + *num = data->ndbservers; + return data->dbservers; } - /* * Find the name of DB server to talk to for a given cell. * @@ -414,81 +513,19 @@ cell_listdbserver (int32_t cell, int index) const char * cell_findnamedbbyname (const char *cell) { - CellEntry key; - CellEntry *data; + cell_entry *data = cell_get_by_name (cell); - key.name = cell; - data = hashtabsearch (cellnamehtab, &key); if (data == NULL) { KODEB (KODEBMISC, ("Cannot find cell %d\n", cell)); return NULL; } - if (data->ndbservs == 0) { + if (data->ndbservers == 0) { KODEB (KODEBMISC, ("No DB servers for cell %d\n", cell)); return NULL; } - return data->dbservs[0].name ; -} - -static void -try_to_find_cell(const char *cell) -{ - struct dns_reply *r; - struct resource_record *rr; - CellEntry *c = NULL; - int dbnum; - DbServerEntry dbservs[256]; - - r = dns_lookup(cell, "AFSDB"); - if (r == NULL) - return; - for(rr = r->head; rr;rr=rr->next){ - switch(rr->type){ - case T_AFSDB: { - struct mx_record *mx = (struct mx_record*)rr->u.data; - - if (mx->preference != 1) { - KODEB (KODEBMISC, - ("Ignoring host with cell type %d in cell %s", - mx->preference, c->name)); - break; - } - if (c == NULL) - c = newcell (cell, &dbnum); - if (dbnum >= sizeof (dbservs) / sizeof(*dbservs)) { - KODEB (KODEBMISC, ("Too many database servers for " - "cell %s. Ignoring\n", c->name)); - break; - } - dbservs[dbnum].name = strdup (mx->domain); - if (dbservs[dbnum].name == NULL) - err (1, "strdup"); - dbservs[dbnum].addr.s_addr = inet_addr ("0.0.0.0"); - ++dbnum; - break; - } - } - } - for(rr = r->head; rr;rr=rr->next){ - int i; - - switch(rr->type){ - case T_A: { - for (i = 0; i < dbnum; i++) { - if (strcmp(dbservs[i].name,rr->domain) == 0) { - dbservs[i].addr = *(rr->u.a); - break; - } - } - } - } - } - if (c) - recordcell (c, dbnum, dbservs); - dns_free_data(r); + return data->dbservers[0].name ; } - /* * Get the cell of the host */ @@ -522,20 +559,12 @@ cell_getcellbyhost(const char *host) int32_t cell_name2num (const char *cell) { - CellEntry key, *data; - - key.name = cell; - data = hashtabsearch (cellnamehtab, (void *)&key); - if (data) - return data->id; - else { - try_to_find_cell(cell); - data = hashtabsearch (cellnamehtab, (void *)&key); - if (data) - return data->id; - else - return -1; - } + cell_entry *data = cell_get_by_name (cell); + + if (data != NULL) + return data->id; + else + return -1; } /* @@ -545,11 +574,9 @@ cell_name2num (const char *cell) const char * cell_num2name (int32_t cell) { - CellEntry key, *data; + cell_entry *data = cell_get_by_id (cell); - key.id = cell; - data = hashtabsearch (cellnumhtab, (void *)&key); - if (data) + if (data != NULL) return data->name; else return NULL; @@ -564,3 +591,47 @@ cell_getthiscell (void) { return thiscell; } + +/* + * Return if this is a suid cell + */ + +Bool +cell_issuid (cell_entry *c) +{ + assert (c); + + return c->suid_cell == SUID_CELL; +} + +Bool +cell_issuid_by_num (int32_t cell) +{ + cell_entry *c = cell_get_by_id (cell); + if (c == NULL) + return FALSE; + + return cell_issuid (c); +} + +Bool +cell_issuid_by_name (const char *cell) +{ + cell_entry *c = cell_get_by_name (cell); + if (c == NULL) + return FALSE; + + return cell_issuid (c); +} + +Bool +cell_setsuid_by_num (int32_t cell) +{ + cell_entry *c = cell_get_by_id (cell); + if (c == NULL) + return FALSE; + + c->suid_cell = SUID_CELL; + + return 0; +} diff --git a/usr.sbin/afs/src/lib/ko/koerror.c b/usr.sbin/afs/src/lib/ko/koerror.c index 984ad841248..e7543c70b07 100644 --- a/usr.sbin/afs/src/lib/ko/koerror.c +++ b/usr.sbin/afs/src/lib/ko/koerror.c @@ -1,4 +1,4 @@ -/* $OpenBSD: koerror.c,v 1.1.1.1 1998/09/14 21:53:00 art Exp $ */ +/* $OpenBSD: koerror.c,v 1.2 1999/04/30 01:59:11 art Exp $ */ /* * Copyright (c) 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: koerror.c,v 1.7 1998/04/03 03:36:32 assar Exp $"); +RCSID("$KTH: koerror.c,v 1.11 1999/03/19 08:21:45 lha Exp $"); #endif #include <stdio.h> @@ -49,13 +49,16 @@ RCSID("$KTH: koerror.c,v 1.7 1998/04/03 03:36:32 assar Exp $"); #include <vldb.h> #include <volumeserver.h> +#include <pts.h> #ifdef KERBEROS -#include <kerberosIV/krb.h> +#include <krb.h> #include <des.h> +#include <rx/rx.h> +#include <rx/rxgencon.h> #include <rxkad.h> #endif #include <ko.h> - +#include <fs_errors.h> struct koerr { koerr_t code; @@ -116,6 +119,32 @@ static struct koerr koerrmsg[] = { {VOLSERMULTIRWVOL, "More then one read/write volume."}, {VOLSERFAILEDOP, "Failed volume server operation."}, + {PREXIST, "Entry exist."}, + {PRIDEXIST, "Id exist."}, + {PRNOIDS, "No Ids."}, + {PRDBFAIL, "Protection-database failed."}, + {PRNOENT, "No entry."}, + {PRPERM, "Permission denied."}, + {PRNOTGROUP, "Not a group."}, + {PRNOTUSER, "Not a user."}, + {PRBADNAM, "Bad name."}, + {PRBADARG, "Bad argument."}, + {PRNOMORE, "No more (?)."}, + {PRDBBAD, "Protection-database went bad."}, + {PRGROUPEMPTY, "Empty group."}, + {PRINCONSISTENT, "Database inconsistency."}, + {PRBADDR, "Bad address."}, + {PRTOOMANY, "Too many."}, + + {RXGEN_CC_MARSHAL, "rxgen - cc_marshal"}, + {RXGEN_CC_UNMARSHAL, "rxgen - cc_unmarshal"}, + {RXGEN_SS_MARSHAL, "rxgen - ss_marshal"}, + {RXGEN_SS_UNMARSHAL, "rxgen - ss_unmarshal"}, + {RXGEN_DECODE, "rxgen - decode"}, + {RXGEN_OPCODE, "rxgen - opcode"}, + {RXGEN_SS_XDRFREE, "rxgen - ss_xdrfree"}, + {RXGEN_CC_XDRFREE, "rxgen - cc_xdrfree"}, + #ifdef KERBEROS /* rxkad - XXX more sane messages */ @@ -135,6 +164,20 @@ static struct koerr koerrmsg[] = { #endif + {ARLA_VSALVAGE, "arla-fs-error - salvaging"}, + {ARLA_VNOVNODE, "arla-fs-error - no such vnode"}, + {ARLA_VNOVOL, "arla-fs-error - no such volume"}, + {ARLA_VVOLEXISTS, "arla-fs-error - volume already exists"}, + {ARLA_VNOSERVICE, "arla-fs-error - no service"}, + {ARLA_VOFFLINE, "arla-fs-error - volume offline"}, + {ARLA_VONLINE, "arla-fs-error - volume online"}, + {ARLA_VDISKFULL, "arla-fs-error - disk full"}, + {ARLA_VOVERQUOTA, "arla-fs-error - quoua full"}, + {ARLA_VBUSY, "arla-fs-error - busy volume"}, + {ARLA_VMOVED, "arla-fs-error - moved volume"}, + {ARLA_VIO, "arla-fs-error - I/O error"}, + {ARLA_VRESTARTING, "arla-fs-error - restarting"}, + /* Not a known error */ { 0L, "Unknown error"} diff --git a/usr.sbin/afs/src/lib/ko/ports.c b/usr.sbin/afs/src/lib/ko/ports.c index c1398dcb8b8..4de761cdc85 100644 --- a/usr.sbin/afs/src/lib/ko/ports.c +++ b/usr.sbin/afs/src/lib/ko/ports.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ports.c,v 1.1.1.1 1998/09/14 21:53:00 art Exp $ */ +/* $OpenBSD: ports.c,v 1.2 1999/04/30 01:59:11 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -53,7 +53,7 @@ #include <netinet/in.h> #endif -RCSID("$KTH: ports.c,v 1.5 1998/06/07 05:44:38 map Exp $") ; +RCSID("$KTH: ports.c,v 1.6 1998/12/06 07:40:56 assar Exp $") ; typedef struct { const char *name; /* Name of the service */ @@ -84,7 +84,7 @@ Port ports[] = { */ void -initports (void) +ports_init (void) { int i; @@ -102,3 +102,20 @@ initports (void) *(ports[i].port) = ntohs (service->s_port); } } + +/* + * port -> name + */ + +const char * +ports_num2name (int port) +{ + int i; + + for (i = 0; i < sizeof (ports) / sizeof (*ports); ++i) { + + if (*(ports[i].port) == port) + return ports[i].name; + } + return NULL; +} diff --git a/usr.sbin/afs/src/lib/ko/ports.h b/usr.sbin/afs/src/lib/ko/ports.h index 5d9767ffb35..9539677b9f1 100644 --- a/usr.sbin/afs/src/lib/ko/ports.h +++ b/usr.sbin/afs/src/lib/ko/ports.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ports.h,v 1.1.1.1 1998/09/14 21:53:00 art Exp $ */ +/* $OpenBSD: ports.h,v 1.2 1999/04/30 01:59:11 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,7 +37,7 @@ * SUCH DAMAGE. */ -/* $KTH: ports.h,v 1.1 1998/04/02 19:34:12 lha Exp $ */ +/* $KTH: ports.h,v 1.2 1998/12/06 07:42:15 assar Exp $ */ /* * Port numbers. @@ -48,8 +48,9 @@ extern int afsport, afscallbackport, afsprport, afsvldbport, afskaport, afsvolport, afserrorsport, afsbosport, - afsupdateport, afsrmtsys ; + afsupdateport, afsrmtsys; -void initports (void); +void ports_init (void); +const char *ports_num2name(int); #endif /* _PORTS_H_ */ diff --git a/usr.sbin/afs/src/lib/ko/vlmisc.c b/usr.sbin/afs/src/lib/ko/vlmisc.c new file mode 100644 index 00000000000..4db702f96b3 --- /dev/null +++ b/usr.sbin/afs/src/lib/ko/vlmisc.c @@ -0,0 +1,92 @@ +/* $OpenBSD: vlmisc.c,v 1.1 1999/04/30 01:59:11 art Exp $ */ +/* + * Copyright (c) 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ko_locl.h" + +RCSID("$KTH: vlmisc.c,v 1.1 1999/03/03 15:33:21 assar Exp $"); + +/* + * Convert old style vldbentry `old` to newer vldbNentry style `new' + */ + +void +vldb2vldbN (const vldbentry *old, nvldbentry *new) +{ + int i; + + strncpy (new->name, old->name, VLDB_MAXNAMELEN); + new->name[VLDB_MAXNAMELEN-1] = '\0'; + if (old->nServers > MAXNSERVERS) + new->nServers = MAXNSERVERS; + else + new->nServers = old->nServers; + + for (i = 0; i < new->nServers ; i++) { + new->serverNumber[i] = old->serverNumber[i]; + new->serverPartition[i] = old->serverPartition[i]; + new->serverFlags[i] = old->serverFlags[i]; + } + for (i = 0; i < MAXTYPES ; i++) + new->volumeId[i] = old->volumeId[i]; + new->cloneId = old->cloneId; + new->flags = old->flags; +} + +void +volintInfo2xvolintInfo (const volintInfo *old, xvolintInfo *new) +{ + memset (new, 0, sizeof(*new)); + strcpy (new->name, old->name); + new->volid = old->volid; + new->type = old->type; + new->backupID = old->backupID; + new->parentID = old->parentID; + new->cloneID = old->cloneID; + new->status = old->status; + new->copyDate = old->copyDate; + new->inUse = old->inUse; + new->creationDate = old->creationDate; + new->accessDate = old->accessDate; + new->updateDate = old->updateDate; + new->backupDate = old->backupDate; + new->dayUse = old->dayUse; + new->filecount = old->filecount; + new->maxquota = old->maxquota; + new->size = old->size; +} diff --git a/usr.sbin/afs/src/lib/roken/ChangeLog b/usr.sbin/afs/src/lib/roken/ChangeLog index e3d47a877dd..8a2cd1314ae 100644 --- a/usr.sbin/afs/src/lib/roken/ChangeLog +++ b/usr.sbin/afs/src/lib/roken/ChangeLog @@ -1,3 +1,8 @@ +1999-01-03 Love <lha@s3.kth.se> + + * getarg.c (arg_match_long): Unbreak ARG_TRANSLONG and FLAGS (by + passing up optarg) + Sun Nov 9 04:48:46 1997 Johan Danielsson <joda@emma.pdc.kth.se> * fnmatch.c: Add fnmatch from NetBSD diff --git a/usr.sbin/afs/src/util/timeprio.h b/usr.sbin/afs/src/lib/roken/emalloc.c index 86a8dd7ab16..a985a5e46ea 100644 --- a/usr.sbin/afs/src/util/timeprio.h +++ b/usr.sbin/afs/src/lib/roken/emalloc.c @@ -1,6 +1,6 @@ -/* $OpenBSD: timeprio.h,v 1.1.1.1 1998/09/14 21:53:26 art Exp $ */ +/* $OpenBSD: emalloc.c,v 1.1 1999/04/30 01:59:11 art Exp $ */ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,34 +37,26 @@ * SUCH DAMAGE. */ -#ifndef _TIMEPRIO_H -#define _TIMEPRIO_H 1 - -#include <time.h> -#include "prio.h" -#include "bool.h" - -typedef struct tpel { - time_t time; - void *data; -} Tpel; - -typedef Prio Timeprio; - -Timeprio *timeprionew(unsigned size); - -void timepriofree(Timeprio *prio); - -int timeprioinsert(Timeprio *prio, time_t time, void *data); - -void *timepriohead(Timeprio *prio); - -void timeprioremove(Timeprio *prio); +#ifdef HAVE_CONFIG_H +#include <config.h> +RCSID("$KTH: emalloc.c,v 1.2 1999/02/13 05:10:55 assar Exp $"); +#endif -Bool timeprioemptyp(Timeprio *prio); +#include <stdlib.h> +#include <err.h> -time_t timepriotimehead(Timeprio *prio); +#include <roken.h> -#endif +/* + * Like malloc but never fails. + */ +void * +emalloc (size_t sz) +{ + void *tmp = malloc (sz); + if (tmp == NULL && sz != 0) + err (1, "malloc %u", sz); + return tmp; +} diff --git a/usr.sbin/afs/src/util/prio.h b/usr.sbin/afs/src/lib/roken/erealloc.c index 90709b88c56..4aa5096efdb 100644 --- a/usr.sbin/afs/src/util/prio.h +++ b/usr.sbin/afs/src/lib/roken/erealloc.c @@ -1,6 +1,6 @@ -/* $OpenBSD: prio.h,v 1.1.1.1 1998/09/14 21:53:26 art Exp $ */ +/* $OpenBSD: erealloc.c,v 1.1 1999/04/30 01:59:12 art Exp $ */ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,33 +37,26 @@ * SUCH DAMAGE. */ -#ifndef _PRIO_H -#define _PRIO_H 1 - -#include <time.h> -#include <bool.h> - -typedef int (*prio_cmp)(void *, void *); - -typedef struct prio { - unsigned sz; /* current size */ - unsigned size; /* max size */ - prio_cmp cmp; - void **heap; -} Prio; - -Prio *prionew(unsigned size, prio_cmp cmp); - -void priofree(Prio *prio); - -int prioinsert(Prio *prio, void *data); - -void *priohead(Prio *prio); +#ifdef HAVE_CONFIG_H +#include <config.h> +RCSID("$KTH: erealloc.c,v 1.2 1999/02/13 05:10:56 assar Exp $"); +#endif -void prioremove(Prio *prio); +#include <stdlib.h> +#include <err.h> -Bool prioemptyp(Prio *prio); +#include <roken.h> -#endif +/* + * Like realloc but never fails. + */ +void * +erealloc (void *ptr, size_t sz) +{ + void *tmp = realloc (ptr, sz); + if (tmp == NULL && sz != 0) + err (1, "realloc %u", sz); + return tmp; +} diff --git a/usr.sbin/afs/src/util/mem.h b/usr.sbin/afs/src/lib/roken/estrdup.c index b9b2e5e7589..75aed15ce1f 100644 --- a/usr.sbin/afs/src/util/mem.h +++ b/usr.sbin/afs/src/lib/roken/estrdup.c @@ -1,6 +1,6 @@ -/* $OpenBSD: mem.h,v 1.1.1.1 1998/09/14 21:53:24 art Exp $ */ +/* $OpenBSD: estrdup.c,v 1.1 1999/04/30 01:59:12 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,14 +37,26 @@ * SUCH DAMAGE. */ -/* $KTH: mem.h,v 1.2 1997/11/09 23:48:55 assar Exp $ */ - -#ifndef _MEM_ -#define _MEM_ +#ifdef HAVE_CONFIG_H +#include <config.h> +RCSID("$KTH: estrdup.c,v 1.1 1999/02/13 05:15:55 assar Exp $"); +#endif #include <stdlib.h> +#include <err.h> + +#include <roken.h> + +/* + * Like strdup but never fails. + */ -void *emalloc(size_t sz); -void *erealloc(void *ptr, size_t sz); +char * +estrdup (const char *str) +{ + char *tmp = strdup (str); -#endif /* _MEM_ */ + if (tmp == NULL) + err (1, "strdup"); + return tmp; +} diff --git a/usr.sbin/afs/src/lib/roken/getarg.c b/usr.sbin/afs/src/lib/roken/getarg.c index eb1bd324a47..ef87e31cdd6 100644 --- a/usr.sbin/afs/src/lib/roken/getarg.c +++ b/usr.sbin/afs/src/lib/roken/getarg.c @@ -1,6 +1,6 @@ -/* $OpenBSD: getarg.c,v 1.1.1.1 1998/09/14 21:53:02 art Exp $ */ +/* $OpenBSD: getarg.c,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* - * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: getarg.c,v 1.9 1998/08/23 22:47:54 assar Exp $"); +RCSID("$KTH: getarg.c,v 1.14 1999/03/03 15:45:50 assar Exp $"); #endif #include <stdio.h> @@ -49,7 +49,8 @@ RCSID("$KTH: getarg.c,v 1.9 1998/08/23 22:47:54 assar Exp $"); #define ISFLAG(X) ((X)->type == arg_flag || (X)->type == arg_negative_flag) static size_t -print_arg (FILE *stream, int mdoc, int longp, struct getargs *arg) +print_arg (FILE *stream, int mdoc, int longp, struct getargs *arg, + int style) { const char *s = NULL; @@ -61,7 +62,7 @@ print_arg (FILE *stream, int mdoc, int longp, struct getargs *arg) fprintf(stream, "= Ns"); fprintf(stream, " Ar "); }else - if (longp) + if (longp && !(style & ARG_TRANSLONG)) putc ('=', stream); else putc (' ', stream); @@ -73,17 +74,20 @@ print_arg (FILE *stream, int mdoc, int longp, struct getargs *arg) else if (arg->type == arg_string) s = "string"; else - s = "<undefined>"; + s = "undefined"; - fprintf (stream, "%s", s); + if (style & ARG_TRANSLONG) + fprintf (stream, "<%s>", s); + else + fprintf (stream, "%s", s); return 1 + strlen(s); } static void mandoc_template(struct getargs *args, - const char *extra_string) + const char *extra_string, + int style) { - int i; struct getargs *arg; char timestr[64], cmd[64]; const char *p; @@ -114,12 +118,12 @@ mandoc_template(struct getargs *args, for(arg = args; arg->type; arg++) { if(arg->short_name){ printf(".Op Fl %c", arg->short_name); - print_arg(stdout, 1, 0, args + i); + print_arg(stdout, 1, 0, args, style); printf("\n"); } if(arg->long_name){ - printf(".Op Fl -%s", arg->long_name); - print_arg(stdout, 1, 1, args + i); + printf(".Op Fl %s%s", style & ARG_TRANSLONG ? "" : "-", arg->long_name); + print_arg(stdout, 1, 1, args, style); printf("\n"); } /* @@ -135,12 +139,12 @@ mandoc_template(struct getargs *args, for(arg = args; arg->type; arg++) { if(arg->short_name){ printf(".It Fl %c", arg->short_name); - print_arg(stdout, 1, 0, args + i); + print_arg(stdout, 1, 0, args, style); printf("\n"); } if(arg->long_name){ - printf(".It Fl -%s", arg->long_name); - print_arg(stdout, 1, 1, args + i); + printf(".It Fl %s%s", style & ARG_TRANSLONG ? "" : "-", arg->long_name); + print_arg(stdout, 1, 1, args, style); printf("\n"); } if(arg->help) @@ -165,36 +169,48 @@ mandoc_template(struct getargs *args, void arg_printusage (struct getargs *args, const char *progname, - const char *extra_string) + const char *extra_string, + int style) { struct getargs *arg; size_t max_len = 0; + if (progname == NULL) + progname = __progname; + if(getenv("GETARGMANDOC")){ - mandoc_template(args, extra_string); + mandoc_template(args, extra_string, style); return; } - fprintf (stderr, "Usage: %s", __progname); + fprintf (stderr, "Usage: %s", progname); for (arg = args; arg->type; arg++) { size_t len = 0; if (arg->long_name) { - fprintf (stderr, " [--"); + if (style & ARG_TRANSLONG) { + if (arg->mandatoryp) + fprintf (stderr, " -"); + else + fprintf (stderr, " [-"); + } else + fprintf (stderr, " [--"); + if (arg->type == arg_negative_flag) { fprintf (stderr, "no-"); len += 3; } fprintf (stderr, "%s", arg->long_name); len += 2 + strlen(arg->long_name); - len += print_arg (stderr, 0, 1, arg); - putc (']', stderr); + len += print_arg (stderr, 0, 1, arg, style); + if(!(style & ARG_TRANSLONG) || !arg->mandatoryp) + putc (']', stderr); if(arg->type == arg_strings) fprintf (stderr, "..."); } if (arg->short_name) { len += 2; fprintf (stderr, " [-%c", arg->short_name); - len += print_arg (stderr, 0, 0, arg); + len += print_arg (stderr, 0, 0, arg, style); putc (']', stderr); if(arg->type == arg_strings) fprintf (stderr, "..."); @@ -214,21 +230,21 @@ arg_printusage (struct getargs *args, if (arg->short_name) { fprintf (stderr, "-%c", arg->short_name); count += 2; - count += print_arg (stderr, 0, 0, arg); + count += print_arg (stderr, 0, 0, arg, style); } if (arg->short_name && arg->long_name) { fprintf (stderr, " or "); count += 4; } if (arg->long_name) { - fprintf (stderr, "--"); + fprintf (stderr, "-%s", style & ARG_TRANSLONG ? "" : "-"); if (arg->type == arg_negative_flag) { fprintf (stderr, "no-"); count += 3; } fprintf (stderr, "%s", arg->long_name); count += 2 + strlen(arg->long_name); - count += print_arg (stderr, 0, 1, arg); + count += print_arg (stderr, 0, 1, arg, style); } while(count++ <= max_len) putc (' ', stderr); @@ -292,7 +308,7 @@ parse_option(struct getargs *arg, char *optarg, int negate) static int arg_match_long(struct getargs *args, - char **argv, int style) + char **argv, int style, int *next) { char *optarg = NULL; int negate = 0; @@ -303,12 +319,16 @@ arg_match_long(struct getargs *args, int argv_len; char *p, *q; - if (style & ARG_LONGARG) + if (style & ARG_LONGARG) { q = *argv + 2; - else if (style & ARG_TRANSLONG) + *next = 0; + } else if (style & ARG_TRANSLONG) { q = *argv + 1; - else + *next = 0; + } else { + *next = 0; q = *argv; + } argv_len = strlen(q); p = strchr (q, '='); @@ -325,9 +345,16 @@ arg_match_long(struct getargs *args, for (;;) { if (strncmp (arg->long_name, p, len) == 0) { current = arg; - if (style & ARG_TRANSLONG && *(argv +1)) - optarg = *(argv + 1); - else if(p[len] == '\0') + if (style & ARG_TRANSLONG) { + if (ISFLAG(arg)) { + optarg = ""; + *next = 0; + } else if (*(argv +1)) { + optarg = *(argv + 1); + *next = 1; + } else + optarg = ""; + } else if(p[len] == '\0') optarg = p + len; else optarg = p + len + 1; @@ -336,7 +363,17 @@ arg_match_long(struct getargs *args, p_len) == 0) { ++partial_match; partial = arg; - optarg = p + p_len +1 ; + if (style & ARG_TRANSLONG) { + if (ISFLAG(arg)) { + optarg = ""; + *next = 0; + } else if (*(argv + 1)) { + optarg = *(argv + 1); + *next = 1; + } else + optarg = ""; + } else + optarg = p + p_len +1 ; } else if (ISFLAG(arg) && strncmp (p, "no-", 3) == 0) { negate = !negate; p += 3; @@ -388,11 +425,10 @@ getarg(struct getargs *args, break; } swcount = -1; - ret = arg_match_long (args, &argv[i], style); + ret = arg_match_long (args, &argv[i], style, &j); if(ret) return ret; - if (style & ARG_TRANSLONG && argv[i+1]) - ++i; + i += j; }else if (style & ARG_SHORTARG) { for(j = 1; argv[i][j]; j++) { for(arg = args; arg->type; arg++) { diff --git a/usr.sbin/afs/src/lib/roken/getarg.h b/usr.sbin/afs/src/lib/roken/getarg.h index bb35ec6cf98..cd53c7813a8 100644 --- a/usr.sbin/afs/src/lib/roken/getarg.h +++ b/usr.sbin/afs/src/lib/roken/getarg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: getarg.h,v 1.1.1.1 1998/09/14 21:53:01 art Exp $ */ +/* $OpenBSD: getarg.h,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,7 +37,7 @@ * SUCH DAMAGE. */ -/* $KTH: getarg.h,v 1.5 1998/08/23 22:47:26 assar Exp $ */ +/* $KTH: getarg.h,v 1.6 1998/12/08 04:00:08 lha Exp $ */ #ifndef __GETARG_H__ #define __GETARG_H__ @@ -82,6 +82,7 @@ int getarg(struct getargs *args, void arg_printusage (struct getargs *args, const char *progname, - const char *extra_string); + const char *extra_string, + int style); #endif /* __GETARG_H__ */ diff --git a/usr.sbin/afs/src/lib/roken/getusershell.c b/usr.sbin/afs/src/lib/roken/getusershell.c index 04827cfe0b6..0fe1380e71b 100644 --- a/usr.sbin/afs/src/lib/roken/getusershell.c +++ b/usr.sbin/afs/src/lib/roken/getusershell.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getusershell.c,v 1.1.1.1 1998/09/14 21:53:03 art Exp $ */ +/* $OpenBSD: getusershell.c,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. @@ -36,12 +36,13 @@ #include <config.h> #endif -RCSID("$KTH: getusershell.c,v 1.2 1998/02/12 01:01:58 assar Exp $"); +RCSID("$KTH: getusershell.c,v 1.3 1999/01/03 01:42:03 assar Exp $"); #ifndef HAVE_GETUSERSHELL #include <stdio.h> #include <stdlib.h> +#include <ctype.h> #ifdef HAVE_PATHS_H #include <paths.h> #endif diff --git a/usr.sbin/afs/src/lib/roken/parse_units.c b/usr.sbin/afs/src/lib/roken/parse_units.c index 3e9a36dfe7a..19cf103fed2 100644 --- a/usr.sbin/afs/src/lib/roken/parse_units.c +++ b/usr.sbin/afs/src/lib/roken/parse_units.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parse_units.c,v 1.1.1.1 1998/09/14 21:53:06 art Exp $ */ +/* $OpenBSD: parse_units.c,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: parse_units.c,v 1.3 1998/03/21 14:51:05 assar Exp $"); +RCSID("$KTH: parse_units.c,v 1.5 1998/12/20 15:52:37 assar Exp $"); #endif #include <stdio.h> @@ -85,18 +85,16 @@ parse_something (const char *s, const struct units *units, size_t u_len; unsigned partial; - while(isspace(*p) || *p == ',') + while(isspace((unsigned char)*p) || *p == ',') ++p; val = strtod (p, &next); /* strtol(p, &next, 0); */ if (val == 0 && p == next) { - if(accept_no_val_p) - val = 1; - else + if(!accept_no_val_p) return -1; } p = next; - while (isspace(*p)) + while (isspace((unsigned char)*p)) ++p; if (*p == '\0') { res = (*func)(res, val, def_mult); @@ -105,6 +103,7 @@ parse_something (const char *s, const struct units *units, break; } else if (*p == '+') { ++p; + val = 1; } else if (*p == '-') { ++p; val = -1; @@ -151,6 +150,9 @@ parse_something (const char *s, const struct units *units, static int acc_units(int res, int val, unsigned mult) { + if (val == 0) + val = 1; + return res + val * mult; } @@ -174,6 +176,8 @@ acc_flags(int res, int val, unsigned mult) return res | mult; else if(val == -1) return res & ~mult; + else if (val == 0) + return mult; else return -1; } diff --git a/usr.sbin/afs/src/lib/roken/recvmsg.c b/usr.sbin/afs/src/lib/roken/recvmsg.c index 6e08c3c7dac..c0eae49160d 100644 --- a/usr.sbin/afs/src/lib/roken/recvmsg.c +++ b/usr.sbin/afs/src/lib/roken/recvmsg.c @@ -1,6 +1,6 @@ -/* $OpenBSD: recvmsg.c,v 1.1.1.1 1998/09/14 21:53:06 art Exp $ */ +/* $OpenBSD: recvmsg.c,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: recvmsg.c,v 1.1 1998/03/29 01:24:44 assar Exp $"); +RCSID("$KTH: recvmsg.c,v 1.2 1998/09/08 03:17:51 assar Exp $"); #endif #include "roken.h" @@ -68,6 +68,7 @@ recvmsg(int s, struct msghdr *msg, int flags) memcpy (iov->iov_base, p, cnt); p += cnt; nb -= cnt; + ++iov; } free(buf); return ret; diff --git a/usr.sbin/afs/src/lib/roken/resolve.h b/usr.sbin/afs/src/lib/roken/resolve.h index a6ffdaddb38..26aa61acc16 100644 --- a/usr.sbin/afs/src/lib/roken/resolve.h +++ b/usr.sbin/afs/src/lib/roken/resolve.h @@ -1,4 +1,4 @@ -/* $OpenBSD: resolve.h,v 1.1.1.1 1998/09/14 21:53:06 art Exp $ */ +/* $OpenBSD: resolve.h,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,17 +37,13 @@ * SUCH DAMAGE. */ -/* $KTH: resolve.h,v 1.2 1998/05/23 05:59:01 assar Exp $ */ +/* $KTH: resolve.h,v 1.3 1999/01/03 01:44:53 assar Exp $ */ #ifndef __RESOLVE_H__ #define __RESOLVE_H__ /* We use these, but they are not always present in <arpa/nameser.h> */ -#ifndef T_A -#define T_A 1 -#endif - #ifndef T_TXT #define T_TXT 16 #endif @@ -97,6 +93,10 @@ struct resource_record{ typedef int HEADER; /* will never be used */ #endif +#ifndef T_A +#define T_A 1 +#endif + struct dns_reply{ HEADER h; struct dns_query q; diff --git a/usr.sbin/afs/src/lib/roken/roken.h b/usr.sbin/afs/src/lib/roken/roken.h index 2851b1e06de..22062405c2f 100644 --- a/usr.sbin/afs/src/lib/roken/roken.h +++ b/usr.sbin/afs/src/lib/roken/roken.h @@ -1,6 +1,6 @@ -/* $OpenBSD: roken.h,v 1.1.1.1 1998/09/14 21:53:07 art Exp $ */ +/* $OpenBSD: roken.h,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ * SUCH DAMAGE. */ -/* $KTH: roken.h,v 1.9 1998/06/07 05:19:20 map Exp $ */ +/* $KTH: roken.h,v 1.14 1999/02/13 05:16:59 assar Exp $ */ #ifndef __ROKEN_H__ #define __ROKEN_H__ @@ -65,6 +65,9 @@ #ifdef HAVE_SYS_STAT_H #include <sys/stat.h> #endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif @@ -203,8 +206,7 @@ char *hstrerror(int herr); extern int h_errno; #endif -#ifndef HAVE_INET_ATON -/* Minimal implementation of inet_aton. Doesn't handle hex numbers. */ +#if !defined(HAVE_INET_ATON) || defined(NEED_INET_ATON_PROTO) int inet_aton(const char *cp, struct in_addr *adr); #endif @@ -251,6 +253,13 @@ int rcmd(char **ahost, unsigned short inport, const char *locuser, const char *remuser, const char *cmd, int *fd2p); #endif +#ifndef HAVE_STRUCT_IOVEC +struct iovec { + void *iov_base; + size_t iov_len; +}; +#endif + #ifndef HAVE_WRITEV ssize_t writev(int d, const struct iovec *iov, int iovcnt); @@ -261,6 +270,28 @@ ssize_t readv(int d, const struct iovec *iov, int iovcnt); #endif +#ifndef HAVE_STRUCT_MSGHDR +struct msghdr { + void *msg_name; + size_t msg_namelen; + struct iovec *msg_iov; + int msg_iovlen; + void *msg_control; + size_t msg_controllen; + int msg_flags; +}; +#endif + +#ifndef HAVE_RECVMSG +ssize_t +recvmsg(int s, struct msghdr *msg, int flags); +#endif + +#ifndef HAVE_SENDMSG +ssize_t +sendmsg(int s, const struct msghdr *msg, int flags); +#endif + #ifndef HAVE_FLOCK #ifndef LOCK_SH #define LOCK_SH 1 /* Shared lock */ @@ -455,4 +486,12 @@ typedef int ssize_t; /* XXX real hot stuff */ #define ntohs(x) __be16_to_cpu(x) #endif +#if !defined(NSIG) && defined(_NSIG) +#define NSIG _NSIG +#endif + +void *emalloc (size_t sz); +void *erealloc (void *ptr, size_t sz); +char *estrdup (const char *); + #endif /* __ROKEN_H__ */ diff --git a/usr.sbin/afs/src/lib/roken/snprintf.c b/usr.sbin/afs/src/lib/roken/snprintf.c index 94c68504103..3e4b773d396 100644 --- a/usr.sbin/afs/src/lib/roken/snprintf.c +++ b/usr.sbin/afs/src/lib/roken/snprintf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: snprintf.c,v 1.1.1.1 1998/09/14 21:53:08 art Exp $ */ +/* $OpenBSD: snprintf.c,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: snprintf.c,v 1.7 1998/03/18 19:31:44 art Exp $"); +RCSID("$KTH: snprintf.c,v 1.8 1998/12/20 15:52:38 assar Exp $"); #endif #include <stdio.h> #include <stdarg.h> @@ -61,12 +61,12 @@ enum format_flags { */ struct state { - char *str; - char *s; - char *theend; + unsigned char *str; + unsigned char *s; + unsigned char *theend; size_t sz; size_t max_sz; - int (*append_char)(struct state *, char); + int (*append_char)(struct state *, unsigned char); int (*reserve)(struct state *, size_t); /* XXX - methods */ }; @@ -80,7 +80,7 @@ sn_reserve (struct state *state, size_t n) static int -sn_append_char (struct state *state, char c) +sn_append_char (struct state *state, unsigned char c) { if (sn_reserve (state, 1)) { return 1; @@ -96,7 +96,7 @@ as_reserve (struct state *state, size_t n) { if (state->s + n > state->theend) { int off = state->s - state->str; - char *tmp; + unsigned char *tmp; if (state->max_sz && state->sz >= state->max_sz) return 1; @@ -115,7 +115,7 @@ as_reserve (struct state *state, size_t n) } static int -as_append_char (struct state *state, char c) +as_append_char (struct state *state, unsigned char c) { if(as_reserve (state, 1)) return 1; @@ -127,7 +127,7 @@ as_append_char (struct state *state, char c) static int append_number(struct state *state, - unsigned long num, unsigned base, char *rep, + unsigned long num, unsigned base, unsigned char *rep, int width, int prec, int flags, int minusp) { int len = 0; @@ -216,7 +216,7 @@ append_number(struct state *state, static int append_string (struct state *state, - char *arg, + unsigned char *arg, int width, int prec, int flags) @@ -247,7 +247,7 @@ append_string (struct state *state, static int append_char(struct state *state, - char arg, + unsigned char arg, int width, int flags) { @@ -281,9 +281,10 @@ else \ */ static int -xyzprintf (struct state *state, const char *format, va_list ap) +xyzprintf (struct state *state, const char *char_format, va_list ap) { - char c; + const unsigned char *format = (const unsigned char *)char_format; + unsigned char c; while((c = *format++)) { if (c == '%') { @@ -358,7 +359,7 @@ xyzprintf (struct state *state, const char *format, va_list ap) break; case 's' : if (append_string(state, - va_arg(ap, char*), + va_arg(ap, unsigned char*), width, prec, flags)) diff --git a/usr.sbin/afs/src/lib/roken/verr.c b/usr.sbin/afs/src/lib/roken/verr.c index 127422c0aaa..045ab5c7884 100644 --- a/usr.sbin/afs/src/lib/roken/verr.c +++ b/usr.sbin/afs/src/lib/roken/verr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: verr.c,v 1.1.1.1 1998/09/14 21:53:07 art Exp $ */ +/* $OpenBSD: verr.c,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: verr.c,v 1.1 1998/01/13 16:25:46 lha Exp $"); +RCSID("$KTH: verr.c,v 1.2 1998/12/20 15:52:38 assar Exp $"); #endif #include "err.h" @@ -48,4 +48,5 @@ void verr(int eval, const char *fmt, va_list ap) { warnerr(1, eval, 1, fmt, ap); + exit(eval); } diff --git a/usr.sbin/afs/src/lib/roken/verrx.c b/usr.sbin/afs/src/lib/roken/verrx.c index eb88bc1b1c3..13c96a6da38 100644 --- a/usr.sbin/afs/src/lib/roken/verrx.c +++ b/usr.sbin/afs/src/lib/roken/verrx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: verrx.c,v 1.1.1.1 1998/09/14 21:53:08 art Exp $ */ +/* $OpenBSD: verrx.c,v 1.2 1999/04/30 01:59:12 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: verrx.c,v 1.1 1998/01/13 16:25:46 lha Exp $"); +RCSID("$KTH: verrx.c,v 1.2 1998/12/20 15:52:38 assar Exp $"); #endif #include "err.h" @@ -48,4 +48,5 @@ void verrx(int eval, const char *fmt, va_list ap) { warnerr(1, eval, 0, fmt, ap); + exit(eval); } diff --git a/usr.sbin/afs/src/lib/sl/ChangeLog b/usr.sbin/afs/src/lib/sl/ChangeLog index 03b31d9b56f..0c11f65bc3f 100644 --- a/usr.sbin/afs/src/lib/sl/ChangeLog +++ b/usr.sbin/afs/src/lib/sl/ChangeLog @@ -1,3 +1,9 @@ +1999-03-06 Love <lha@s3.kth.se> + + * sl.h: Added prototype + + * sl.c (sl_apropos): New function + Tue Mar 3 00:03:17 1998 Assar Westerlund <assar@sics.se> * Makefile.in (install): removed '-m 444' diff --git a/usr.sbin/afs/src/lib/sl/sl.c b/usr.sbin/afs/src/lib/sl/sl.c index 1fe6c6356f2..99c48d4bbbd 100644 --- a/usr.sbin/afs/src/lib/sl/sl.c +++ b/usr.sbin/afs/src/lib/sl/sl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sl.c,v 1.1.1.1 1998/09/14 21:53:10 art Exp $ */ +/* $OpenBSD: sl.c,v 1.2 1999/04/30 01:59:13 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -39,11 +39,27 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: sl.c,v 1.3 1998/06/21 21:35:58 lha Exp $"); +RCSID("$KTH: sl.c,v 1.6 1999/03/06 17:57:07 lha Exp $"); #endif #include "sl_locl.h" +static size_t __attribute__ ((unused)) +print_sl (FILE *stream, int mdoc, int longp, SL_cmd *c) +{ + if(mdoc){ + if(longp) + fprintf(stream, "= Ns"); + fprintf(stream, " Ar "); + }else + if (longp) + putc ('=', stream); + else + putc (' ', stream); + + return 1; +} + static void mandoc_template(SL_cmd *cmds, const char *extra_string) @@ -283,3 +299,11 @@ sl_loop (SL_cmd *cmds, char *prompt) free (ptr); return 0; } + +void +sl_apropos (SL_cmd *cmd, char *topic) +{ + for (; cmd->name != NULL; ++cmd) + if (cmd->usage != NULL && strstr(cmd->usage, topic) != NULL) + printf ("%-20s%s\n", cmd->name, cmd->usage); +} diff --git a/usr.sbin/afs/src/lib/sl/sl.h b/usr.sbin/afs/src/lib/sl/sl.h index 222ef8575a8..c03b82f7d3a 100644 --- a/usr.sbin/afs/src/lib/sl/sl.h +++ b/usr.sbin/afs/src/lib/sl/sl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sl.h,v 1.1.1.1 1998/09/14 21:53:11 art Exp $ */ +/* $OpenBSD: sl.h,v 1.2 1999/04/30 01:59:13 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,7 +37,7 @@ * SUCH DAMAGE. */ -/* $KTH: sl.h,v 1.2 1998/06/21 21:35:59 lha Exp $ */ +/* $KTH: sl.h,v 1.3 1999/03/06 14:44:37 lha Exp $ */ #ifndef _SL_H #define _SL_H @@ -58,6 +58,7 @@ typedef struct sl_cmd SL_cmd; void sl_help (SL_cmd *, int argc, char **argv); int sl_loop (SL_cmd *, char *prompt); int sl_command (SL_cmd *cmds, int argc, char **argv); +void sl_apropos (SL_cmd *cmd, char *topic); #endif /* _SL_H */ diff --git a/usr.sbin/afs/src/lwp/iomgr.c b/usr.sbin/afs/src/lwp/iomgr.c index 9c3d943938f..54aabee2d90 100644 --- a/usr.sbin/afs/src/lwp/iomgr.c +++ b/usr.sbin/afs/src/lwp/iomgr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iomgr.c,v 1.1.1.1 1998/09/14 21:53:11 art Exp $ */ +/* $OpenBSD: iomgr.c,v 1.2 1999/04/30 01:59:13 art Exp $ */ /* **************************************************************************** * Copyright IBM Corporation 1988, 1989 - All Rights Reserved * @@ -36,7 +36,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: iomgr.c,v 1.18 1998/07/09 19:56:27 art Exp $"); +RCSID("$KTH: iomgr.c,v 1.21 1998/10/01 16:53:39 assar Exp $"); #endif #include <stdio.h> @@ -322,7 +322,7 @@ IOMGR(char *dummy) if (wfds) FD_OR(wfds, req->wfds); else { - wfds = &readfds; + wfds = &writefds; FD_COPY(req->wfds, wfds); } } @@ -331,7 +331,7 @@ IOMGR(char *dummy) if (efds) FD_OR(efds, req->efds); else { - efds = &readfds; + efds = &exceptfds; FD_COPY(req->efds, efds); } } @@ -349,7 +349,9 @@ IOMGR(char *dummy) if (timeout.tv_sec == -1 && timeout.tv_usec == -1) puts("INFINITE)]"); else - printf("<%d, %d>)]\n", timeout.tv_sec, timeout.tv_usec); + printf("<%ld, %lu>)]\n", + (long)timeout.tv_sec, + (unsigned long)timeout.tv_usec); } #endif /* DEBUG */ iomgr_timeout = timeout; @@ -651,7 +653,7 @@ IOMGR_Poll(void) if (wfds) FD_OR(wfds, req->wfds); else { - wfds = &readfds; + wfds = &writefds; FD_COPY(req->wfds, wfds); } } @@ -660,7 +662,7 @@ IOMGR_Poll(void) if (efds) FD_OR(efds, req->efds); else { - efds = &readfds; + efds = &exceptfds; FD_COPY(req->efds, efds); } } @@ -669,7 +671,7 @@ IOMGR_Poll(void) tv.tv_sec = 0; tv.tv_usec = 0; - code = select(nfds, &readfds, &writefds, &exceptfds, &tv); + code = select(nfds, rfds, wfds, efds, &tv); if (code > 0) { SignalIO(code, rfds, wfds, efds); diff --git a/usr.sbin/afs/src/lwp/lwp.c b/usr.sbin/afs/src/lwp/lwp.c index f9163252362..dd2d6f356cd 100644 --- a/usr.sbin/afs/src/lwp/lwp.c +++ b/usr.sbin/afs/src/lwp/lwp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lwp.c,v 1.1.1.1 1998/09/14 21:53:12 art Exp $ */ +/* $OpenBSD: lwp.c,v 1.2 1999/04/30 01:59:13 art Exp $ */ /* **************************************************************************** * Copyright IBM Corporation 1988, 1989 - All Rights Reserved * @@ -38,7 +38,7 @@ #include "lwp.h" -RCSID("$KTH: lwp.c,v 1.10 1998/02/22 20:02:25 joda Exp $"); +RCSID("$KTH: lwp.c,v 1.14 1999/01/12 04:13:44 assar Exp $"); #ifdef AFS_AIX32_ENV #include <ulimit.h> @@ -68,7 +68,7 @@ extern char PRE_Block; /* from preempt.c */ * now I don't get any unalinged memory access on my alpha /lha */ -#ifdef __alpha +#if defined(__alpha) || defined(__uxpv__) || defined(__sparcv9) #define REGSIZE 8 #else #define REGSIZE 4 diff --git a/usr.sbin/afs/src/lwp/lwp.h b/usr.sbin/afs/src/lwp/lwp.h index 8c0492021a0..7da526e62ab 100644 --- a/usr.sbin/afs/src/lwp/lwp.h +++ b/usr.sbin/afs/src/lwp/lwp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: lwp.h,v 1.1.1.1 1998/09/14 21:53:12 art Exp $ */ +/* $OpenBSD: lwp.h,v 1.2 1999/04/30 01:59:13 art Exp $ */ /* **************************************************************************** @@ -29,7 +29,7 @@ * * \*******************************************************************/ -/* $KTH: lwp.h,v 1.8 1998/07/20 02:52:24 assar Exp $ */ +/* $KTH: lwp.h,v 1.12 1999/01/12 04:11:44 assar Exp $ */ #ifndef __LWP_INCLUDE_ #define __LWP_INCLUDE_ 1 @@ -84,7 +84,13 @@ struct lwp_context { /* saved context for dispatcher */ char *topstack; /* ptr to top of process stack */ #ifdef sparc #ifdef save_allregs - long globals[7+1+32+2+32+2]; /* g1-g7, y reg, f0-f31, fsr, fq, c0-c31, csr, cq. */ +#ifdef __sparcv9 +#define nregs (7+1+62+2) +#else +#define nregs (7+1+32+2+32+2) /* g1-g7, y reg, f0-f31, fsr, fq, c0-c31, csr, cq. */ +#endif + long globals[nregs]; +#undef nregs #else long globals[8]; /* g1-g7 and y registers. */ #endif @@ -173,9 +179,9 @@ extern * overflow problems. */ #if defined(AFS_HPUX_ENV) || defined(AFS_NEXT_ENV) /*|| defined(AFS_SUN5_ENV)*/ -#define AFS_LWP_MINSTACKSIZE (24 * 1024) +#define AFS_LWP_MINSTACKSIZE (100 * 1024) #else -#define AFS_LWP_MINSTACKSIZE (16 * 1024) +#define AFS_LWP_MINSTACKSIZE (100 * 1024) #endif /* defined(AFS_HPUX_ENV) */ /* Action to take on stack overflow. */ diff --git a/usr.sbin/afs/src/lwp/make-process.o.sh.in b/usr.sbin/afs/src/lwp/make-process.o.sh.in index a7dc4780fc6..0a64a143e7c 100644 --- a/usr.sbin/afs/src/lwp/make-process.o.sh.in +++ b/usr.sbin/afs/src/lwp/make-process.o.sh.in @@ -3,7 +3,7 @@ # make-process.o.sh # Try to make process.o various ways. # -# $Id: make-process.o.sh.in,v 1.1.1.1 1998/09/14 21:53:12 art Exp $ +# $Id: make-process.o.sh.in,v 1.2 1999/04/30 01:59:13 art Exp $ # srcdir=@srcdir@ @@ -11,7 +11,7 @@ srcdir=@srcdir@ CC="@CC@" GCC="@GCC@" CPP="@CPP@" -AS=as +AS="as" RM=rm HOST_CPU="@host_cpu@" HOST_OS="@host_os@" @@ -52,6 +52,7 @@ case "$HOST_CPU" in hppa*) CPUDEF="" ;; powerpc) CPUDEF="-D__powerpc__" ;; rs6000) CPUDEF="-DRIOS" ;; + f301) ;; *) echo "Unknown host_cpu, good luck" ;; esac @@ -60,15 +61,20 @@ esac # case "$HOST_OS" in - *bsd*) OSDEF="-DAFS_NETBSD_ENV" ;; + *bsd*) OSDEF="-DHAVE_PIC -DAFS_BSD_ENV" ;; *linux*) OSDEF="-DAFS_LINUX_ENV" ;; - *irix*) OSDEF="-Dsgi" ;; *dux* | *osf*) OSDEF="-DAFS_OSF_ENV" ;; *solaris*) OSDEF="-DAFS_SUN5_ENV -D_ASM" USE_AS="yes" ;; - *irix*) OSDEF="-Dsgi" ;; + *irix*) OSDEF="-Dsgi -n32 -DHAVE_PIC"; ASDEF="-n32" ;; *hpux*) OSDEF="-DAFS_HPUX_ENV" PROCESS_S="process.s.hpux" ;; - rhapsody*) OSDEF="-DAFS_NETBSD_ENV" ;; + rhapsody*) OSDEF="-DAFS_BSD_ENV" ;; aix*) CPUDEF="-DRIOS"; OSDEF="" ;; + uxpv*) + $CPP -P ${srcdir}/process-vpp.s > foo.s + $AS -o process.o foo.s && $RM -f foo.s && exit 0 + $RM -f foo.s + exit 1 + ;; *) ;; esac @@ -81,8 +87,8 @@ esac # Can we use $CC to do the asm for us ? (GCC) # -if test "$GCC" = "yes" -a "$USE_AS" = "no"; then - ${CC} $MYDEF $CPUDEF $OSDEF -c ${srcdir}/${PROCESS_S} ; +if test "X$GCC" = "Xyes" -a "X$USE_AS" = "Xno"; then + ${CC} -I../include $MYDEF $CPUDEF $OSDEF -c ${srcdir}/${PROCESS_S} ; # process.o there ? $CC -o testprocess testprocess.o process.o preempt.o lwp.o && exit 0 @@ -93,7 +99,7 @@ fi # Try to use $AS -P for assably # -$AS -P $MYDEF $CPUDEF $OSDEF ${srcdir}/${PROCESS_S} -o process.o +$AS -P -I../include $MYDEF $CPUDEF $OSDEF ${srcdir}/${PROCESS_S} -o process.o # process.o there ? $CC -o testprocess testprocess.o process.o preempt.o lwp.o && exit 0 @@ -106,7 +112,7 @@ $RM -f process.o # if test -s process.i ; then - $AS process.i -o process.o + $AS $ASDEF process.i -o process.o $RM -f process.i # process.o there ? @@ -118,7 +124,7 @@ fi # Try to use $AS (without -P) for assably # -$AS $MYDEF $CPUDEF $OSDEF ${srcdir}/${PROCESS_S} -o process.o +$AS -I../include $MYDEF $CPUDEF $OSDEF ${srcdir}/${PROCESS_S} -o process.o # process.o there ? $CC -o testprocess testprocess.o process.o preempt.o lwp.o && exit 0 @@ -144,7 +150,8 @@ fi # $RM -f foo.c && $LN_S ${srcdir}/${PROCESS_S} foo.c -$CPP $MYDEF $CPUDEF $OSDEF foo.c > process.ss +$CPP -I../include $MYDEF $CPUDEF $OSDEF foo.c > process.ss +$RM -f foo.c $AS process.ss -o process.o $RM -f process.ss @@ -154,8 +161,3 @@ $RM -f process.o echo "WE HAVE NO process.o !" exit 1 - - - - - diff --git a/usr.sbin/afs/src/lwp/plwp.c b/usr.sbin/afs/src/lwp/plwp.c new file mode 100644 index 00000000000..62509a78b1e --- /dev/null +++ b/usr.sbin/afs/src/lwp/plwp.c @@ -0,0 +1,939 @@ +/* $OpenBSD: plwp.c,v 1.1 1999/04/30 01:59:13 art Exp $ */ +/* This version of the code is derived from the Coda version of the LWP + * library, which can be compiled as a wrapper around Mach cthreads + */ +/* +**************************************************************************** +* Copyright IBM Corporation 1988, 1989 - All Rights Reserved * +* * +* Permission to use, copy, modify, and distribute this software and its * +* documentation for any purpose and without fee is hereby granted, * +* provided that the above copyright notice appear in all copies and * +* that both that copyright notice and this permission notice appear in * +* supporting documentation, and that the name of IBM not be used in * +* advertising or publicity pertaining to distribution of the software * +* without specific, written prior permission. * +* * +* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM * +* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * +* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * +* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * +* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * +**************************************************************************** +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* allocate externs here */ +#define LWP_KERNEL + +#include <lwp.h> + +RCSID("$KTH: plwp.c,v 1.2 1999/02/02 00:47:16 assar Exp $"); + +#ifdef AFS_AIX32_ENV +#include <ulimit.h> +#include <sys/errno.h> +#include <sys/user.h> +#include <sys/pseg.h> +#include <sys/core.h> +#pragma alloca +#endif + +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +extern char PRE_Block; /* from preempt.c */ + +#define ON 1 +#define OFF 0 +#define TRUE 1 +#define FALSE 0 +#define READY 2 +#define WAITING 3 +#define DESTROYED 4 +#define QWAITING 5 +#define MAXINT (~(1<<((sizeof(int)*8)-1))) +#define MINSTACK 44 + + +/* Debugging macro */ +#ifdef DEBUG +#define Debug(level, msg)\ + if (lwp_debug && lwp_debug >= level) {\ + printf("***LWP (%p): ", lwp_cpptr);\ + printf msg;\ + putchar('\n');\ + } + +#else +#define Debug(level, msg) +#endif + +/* Prototypes */ +static void Abort_LWP(char *msg) ; +static void Dispatcher(void); +static void Create_Process_Part2(PROCESS temp); +static void purge_dead_pcbs(void) ; +static void Dispose_of_Dead_PCB (PROCESS cur) ; +static void Free_PCB(PROCESS pid) ; +static void Exit_LWP(); +static void Initialize_PCB(PROCESS temp, int priority, char *stack, + int stacksize, void (*ep)() , char *parm, + char *name) ; +static int Internal_Signal(register char *event) ; +char (*RC_to_ASCII()); + +#define MAX_PRIORITIES (LWP_MAX_PRIORITY+1) + +struct QUEUE { + PROCESS head; + int count; +} runnable[MAX_PRIORITIES], blocked; +/* + * Invariant for runnable queues: The head of each queue points to the + * currently running process if it is in that queue, or it points to the + * next process in that queue that should run. + */ + +/* special user-tweakable option for AIX */ +int lwp_MaxStackSize = 32768; +int lwp_MaxStackSeen = 0; + +int lwp_nextindex = 0; + +/* Iterator macro */ +#define for_all_elts(var, q, body)\ + {\ + register PROCESS var, _NEXT_;\ + register int _I_;\ + for (_I_=q.count, var = q.head; _I_>0; _I_--, var=_NEXT_) {\ + _NEXT_ = var -> next;\ + body\ + }\ + } + +static struct lwp_ctl *lwp_init = 0; + +static void Dump_One_Process(PROCESS pid); +static void Dump_Processes(); +static void Delete_PCB(register PROCESS pid); +static void Free_PCB(PROCESS pid); +static void Cal_Highest_runnable_priority(); +static int InitializeProcessSupport(int, PROCESS *); + +PROCESS lwp_cpptr; + +/* The global Highest_runnable_priority is only needed in NEW lwp. + But it gets set within a for_all_elts() instance in + InternalSignal(). */ +int Highest_runnable_priority; /* global variable for max priority */ + +int Proc_Running; /* indicates forked proc got control */ + +pthread_mutex_t run_sem, ct_mutex; + +static void +lwpremove(register PROCESS p, register struct QUEUE *q) +{ + /* Special test for only element on queue */ + if (q->count == 1) + q -> head = NULL; + else { + /* Not only element, do normal remove */ + p -> next -> prev = p -> prev; + p -> prev -> next = p -> next; + } + /* See if head pointing to this element */ + if (q->head == p) q -> head = p -> next; + q->count--; + Debug(0, ("removing, count now %d", q->count)); + p -> next = p -> prev = NULL; +} + +static void +lwpinsert(register PROCESS p, register struct QUEUE *q) +{ + if (q->head == NULL) { /* Queue is empty */ + q -> head = p; + p -> next = p -> prev = p; + } else { /* Regular insert */ + p -> prev = q -> head -> prev; + q -> head -> prev -> next = p; + q -> head -> prev = p; + p -> next = q -> head; + } + q->count++; + Debug(0, ("inserting, count now %d", q->count)); +} + +static void +lwpmove(PROCESS p, struct QUEUE *from, struct QUEUE *to) +{ + lwpremove(p, from); + lwpinsert(p, to); +} + +int +LWP_TerminateProcessSupport() /* terminate all LWP support */ +{ + register int i; + + Debug(0, ("Entered Terminate_Process_Support")); + if (lwp_init == NULL) return LWP_EINIT; + /* free all space allocated */ + for (i=0; i<MAX_PRIORITIES; i++) + for_all_elts(cur, runnable[i], { Free_PCB(cur);}) + for_all_elts(cur, blocked, { Free_PCB(cur);}) + free((char *)lwp_init); + lwp_init = NULL; + return LWP_SUCCESS; +} + +int +LWP_GetRock(int Tag, char **Value) +{ + /* Obtains the pointer Value associated with the rock Tag of this LWP. + Returns: + LWP_SUCCESS if specified rock exists and Value has been filled + LWP_EBADROCK rock specified does not exist + */ + register int i; + register struct rock *ra; + + ra = lwp_cpptr->rlist; + + for (i = 0; i < lwp_cpptr->rused; i++) + if (ra[i].tag == Tag) { +#ifdef PTHREAD_GETSPECIFIC_TWOARG + pthread_getspecific(ra[i].val, Value); +#else + *Value = pthread_getspecific(ra[i].val); +#endif + /**Value = ra[i].value;*/ + return(LWP_SUCCESS); + } + return(LWP_EBADROCK); +} + + +int +LWP_NewRock(int Tag, char *Value) +{ + /* Finds a free rock and sets its value to Value. + Return codes: + LWP_SUCCESS Rock did not exist and a new one was used + LWP_EBADROCK Rock already exists. + LWP_ENOROCKS All rocks are in use. + + From the above semantics, you can only set a rock value once. + This is specifically to prevent multiple users of the LWP + package from accidentally using the same Tag value and + clobbering others. You can always use one level of + indirection to obtain a rock whose contents can change. */ + + register int i; + register struct rock *ra; /* rock array */ + + ra = lwp_cpptr->rlist; + + /* check if rock has been used before */ + for (i = 0; i < lwp_cpptr->rused; i++) + if (ra[i].tag == Tag) return(LWP_EBADROCK); + + /* insert new rock in rock list and increment count of rocks */ + if (lwp_cpptr->rused < MAXROCKS) { + ra[lwp_cpptr->rused].tag = Tag; +#ifdef HAVE_PTHREAD_KEYCREATE + if (pthread_keycreate(&ra[lwp_cpptr->rused].val, NULL)) +#else + if (pthread_key_create(&ra[lwp_cpptr->rused].val, NULL)) +#endif + return(LWP_EBADROCK); + if (pthread_setspecific(ra[lwp_cpptr->rused].val, Value)) + return(LWP_EBADROCK); + /* ra[lwp_cpptr->rused].value = Value; */ + lwp_cpptr->rused++; + return(LWP_SUCCESS); + } + else return(LWP_ENOROCKS); +} + +static void +Dispose_of_Dead_PCB(PROCESS cur) +{ + + Debug(0, ("Entered Dispose_of_Dead_PCB")); + Delete_PCB(cur); + Free_PCB(cur); +} + +int +LWP_CurrentProcess(PROCESS *pid) +{ + Debug(0, ("Entered Current_Process")); + if (lwp_init) { + *pid = lwp_cpptr; + return LWP_SUCCESS; + } else + return LWP_EINIT; +} + + +int +LWP_GetProcessPriority(PROCESS pid, int *priority) +{ + Debug(0, ("Entered Get_Process_Priority")); + if (lwp_init) { + *priority = pid -> priority; + return 0; + } else + return LWP_EINIT; +} + +int +LWP_WaitProcess(char *event) +{ + char *tempev[2]; + + Debug(0, ("Entered Wait_Process")); + if (event == NULL) return LWP_EBADEVENT; + tempev[0] = event; + tempev[1] = NULL; + return LWP_MwaitProcess(1, tempev); +} + +static void +Delete_PCB(register PROCESS pid) +{ + Debug(0, ("Entered Delete_PCB")); + lwpremove(pid, (pid->blockflag || pid->status==WAITING || + pid->status==DESTROYED ? &blocked + : &runnable[pid->priority])); +} + +static void +purge_dead_pcbs() +{ + for_all_elts(cur, blocked, { if (cur->status == DESTROYED) + Dispose_of_Dead_PCB(cur); }) +} + +static void +Exit_LWP() +{ + exit (-1); +} + +static void +Dump_Processes() +{ + if (lwp_init) { + register int i; + for (i=0; i<MAX_PRIORITIES; i++) + for_all_elts(x, runnable[i], { + printf("[Priority %d]\n", i); + Dump_One_Process(x); + }) + for_all_elts(x, blocked, { Dump_One_Process(x); }) + } else + printf("***LWP: LWP support not initialized\n"); +} + +char * +LWP_Name() +{ + return(lwp_cpptr->name); +} + +int +LWP_Index() +{ + return(lwp_cpptr->index); +} + +int +LWP_HighestIndex() +{ + return(lwp_nextindex-1); +} + +/* A process calls this routine to wait until somebody signals it. + * LWP_QWait removes the calling process from the runnable queue + * and makes the process sleep until some other process signals via LWP_QSignal + */ +int +LWP_QWait() +{ + PROCESS old_cpptr; + + Debug(0, ("LWP_QWait: %s is going to QWait\n", lwp_cpptr->name)); + lwp_cpptr->status = QWAITING; + if (runnable[lwp_cpptr->priority].count == 0) + Cal_Highest_runnable_priority(); + + old_cpptr = lwp_cpptr; + + /* wake up next lwp */ + lwp_cpptr = runnable[Highest_runnable_priority].head; + lwpremove(lwp_cpptr, &runnable[Highest_runnable_priority]); + timerclear(&lwp_cpptr->lastReady); + pthread_mutex_lock(&ct_mutex); + Debug(0, ("LWP_QWait:%s going to wake up %s \n", old_cpptr->name, + lwp_cpptr->name)); + pthread_cond_signal(&lwp_cpptr->c); + + /* sleep on your own condition */ + Debug(0, ("LWP_QWait:%s going to wait on own condition \n", + old_cpptr->name)); + pthread_cond_wait(&old_cpptr->c, &ct_mutex); + pthread_mutex_unlock(&ct_mutex); + + lwp_cpptr = old_cpptr; + + /* return only if calling process' priority is the highest */ + if (lwp_cpptr->priority < Highest_runnable_priority) + Dispatcher(); + return LWP_SUCCESS; +} + + +/* signal the PROCESS pid - by adding it to the runnable queue */ +int +LWP_QSignal(PROCESS pid) +{ + if (pid->status == QWAITING) { + Debug(0, ("LWP_Qsignal: %s is going to QSignal %s\n", lwp_cpptr->name, + pid->name)); + pid->status = READY; + lwpinsert(pid, &runnable[pid->priority]); + Debug(0, ("LWP_QSignal: Just inserted %s into runnable queue\n", + pid->name)); + gettimeofday(&pid->lastReady, 0); + Highest_runnable_priority = + MAX(Highest_runnable_priority, pid->priority); + Debug(0, ("%s priority= %d; HRP = %d; Signalled process pri = %d", + lwp_cpptr->name, lwp_cpptr->priority, + Highest_runnable_priority, pid->priority)); + return LWP_SUCCESS; + } + else return LWP_ENOWAIT; +} + + +int +LWP_CreateProcess(void (*ep)(), int stacksize, int priority, + char *parm, char *name, PROCESS *pid) +{ + PROCESS temp; + pthread_t ct; + pthread_attr_t cta; + PROCESS old_cpptr; + int retval; + + Debug(0, ("Entered LWP_CreateProcess to create %s at priority %d\n", + name, priority)); + old_cpptr = lwp_cpptr; + /* Throw away all dead process control blocks */ + purge_dead_pcbs(); + + if (lwp_init) { + /* allocate the memory for the pcb - check for malloc errors */ + temp = (PROCESS)malloc (sizeof (struct lwp_pcb)); + if (temp == NULL) { + Dispatcher(); + return LWP_ENOMEM; + } + + /* check priorities */ + if (priority < 0 || priority >= MAX_PRIORITIES) { + Dispatcher(); + return LWP_EBADPRI; + } + + Initialize_PCB(temp, priority, NULL, 0, ep, parm, name); + + /* make the process runnable by placing it in the runnable q */ + lwpinsert(temp, &runnable[priority]); + gettimeofday(&temp->lastReady, 0); + + if (PRE_Block != 0) Abort_LWP("PRE_Block not 0"); + + PRE_Block = 1; + Proc_Running = FALSE; /* sem set true by forked process */ + + pthread_attr_init(&cta); +#ifdef _POSIX_THREAD_ATTR_STACKSIZE + pthread_attr_setstacksize(&cta, stacksize); +#endif + retval = pthread_create(&ct, &cta, (void *)Create_Process_Part2, temp); + if (!retval) { + temp->a = cta; + pthread_detach(ct); + + /* check if max priority has changed */ + Highest_runnable_priority = MAX(Highest_runnable_priority, priority); + + pthread_mutex_lock(&run_sem); + Debug(0, ("Before creating process yields Proc_Running = %d\n", + Proc_Running)); + while( !Proc_Running ){ + pthread_mutex_unlock(&run_sem); +#if defined(HAVE_THR_YIELD) + thr_yield(); +#elif defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + sched_yield(); +#else + pthread_yield(); +#endif + pthread_mutex_lock(&run_sem); + Debug(0,("After creating proc yields and gets back control Proc_Running = %d\n", + Proc_Running)); + } + pthread_mutex_unlock(&run_sem); + + lwp_cpptr = old_cpptr; + + Dispatcher(); + *pid = temp; + return LWP_SUCCESS; + } + } else { + pthread_attr_destroy(&cta); + } + return LWP_EINIT; +} + +int +LWP_DestroyProcess(PROCESS pid) +{ + void *t; + + Debug(0, ("Entered Destroy_Process")); + if (lwp_init) { + pthread_attr_destroy(&pid->a); + if (lwp_cpptr == pid){ + /* kill myself */ + pid->status = DESTROYED; + Free_PCB(pid); + Cal_Highest_runnable_priority(); + + /* Calculate next runnable lwp and signal it */ + lwp_cpptr = runnable[Highest_runnable_priority].head; + lwpremove(lwp_cpptr, &runnable[Highest_runnable_priority]); + + pthread_mutex_lock(&ct_mutex); + pthread_cond_signal(&lwp_cpptr->c); + pthread_mutex_unlock(&ct_mutex); + pthread_exit(t); + } else { + /* kill some other process - mark status destroyed - + if process is blocked, it will be purged on next create proc; + if it is runnable the dispatcher will kill it */ + pid->status = DESTROYED ; + Dispatcher(); + } + return LWP_SUCCESS ; + } else + return LWP_EINIT; +} + +int +LWP_DispatchProcess() /* explicit voluntary preemption */ +{ + Debug(0, ("Entered Dispatch_Process")) + if (lwp_init) { + Dispatcher(); + return LWP_SUCCESS; + } else + return LWP_EINIT; +} + +int +LWP_Init(int version, int priority, PROCESS *pid) +{ + if (version != LWP_VERSION) + { + fprintf(stderr, "**** FATAL ERROR: LWP VERSION MISMATCH ****\n"); + exit(-1); + } + else return(InitializeProcessSupport(priority, pid)); +} + +int +LWP_InitializeProcessSupport(int priority, PROCESS *pid) +{ + return(InitializeProcessSupport(priority, pid)); +} + +static int +InitializeProcessSupport(int priority, PROCESS *pid) +{ + PROCESS temp; + register int i; + + Debug(0, ("Entered InitializeProcessSupport")); + if (lwp_init != NULL) return LWP_SUCCESS; + + /* check priorities and set up running and blocked queues */ + if (priority >= MAX_PRIORITIES) return LWP_EBADPRI; + for (i=0; i<MAX_PRIORITIES; i++) { + runnable[i].head = NULL; + runnable[i].count = 0; + } + blocked.head = NULL; + blocked.count = 0; + lwp_init = (struct lwp_ctl *) malloc(sizeof(struct lwp_ctl)); + temp = (PROCESS) malloc(sizeof(struct lwp_pcb)); + if (lwp_init == NULL || temp == NULL) + Abort_LWP("Insufficient Storage to Initialize LWP Support"); + + /* check parameters */ + Initialize_PCB(temp, priority, NULL, 0, NULL, NULL,"Main Process"); + gettimeofday(&temp->lastReady, 0); + + Highest_runnable_priority = priority; + + /* initialize mutex and semaphore */ + Proc_Running = TRUE; + pthread_mutex_init(&run_sem, NULL); + pthread_mutex_init(&ct_mutex, NULL); + + lwp_cpptr = temp; + Dispatcher(); + *pid = temp; + return LWP_SUCCESS; +} + +int +LWP_INTERNALSIGNAL(void *event, int yield) +{ + Debug(0, ("Entered LWP_SignalProcess, yield=%d", yield)); + if (lwp_init) { + int rc; + rc = Internal_Signal(event); + if (yield) { + Cal_Highest_runnable_priority(); + Debug(0, ("hipri=%d", Highest_runnable_priority)); + Dispatcher(); + } + return rc; + } else + return LWP_EINIT; +} + +int +LWP_MwaitProcess(int wcount, char *evlist[]) /* wait on m of n events */ +{ + register int ecount, i; + PROCESS old_cpptr; + + Debug(0, ("Entered Mwait_Process [waitcnt = %d]", wcount)); + if (evlist == NULL) { + Dispatcher(); + return LWP_EBADCOUNT; + } + + /* count # of events in eventlist */ + for (ecount = 0; evlist[ecount] != NULL; ecount++) ; + if (ecount == 0) { + Dispatcher(); + return LWP_EBADCOUNT; + } + + if (lwp_init) { + /* check for illegal counts */ + if (wcount>ecount || wcount<0) { + Dispatcher(); + return LWP_EBADCOUNT; + } + + /* reallocate eventlist if new list has more elements than before */ + if (ecount > lwp_cpptr->eventlistsize) { + lwp_cpptr->eventlist = + (char **)realloc((char *)lwp_cpptr->eventlist, + ecount*sizeof(char *)); + lwp_cpptr->eventlistsize = ecount; + } + + /* place events in eventlist of the pcb */ + for (i=0; i<ecount; i++) lwp_cpptr -> eventlist[i] = evlist[i]; + + /* if there are any events to wait on then set status to + WAITING and place the pcb in blocked queue */ + if (wcount > 0) { + lwp_cpptr -> status = WAITING; + lwpinsert(lwp_cpptr, &blocked); + } + lwp_cpptr -> wakevent = 0; /* index of eventid causing wakeup */ + lwp_cpptr -> waitcnt = wcount; + lwp_cpptr -> eventcnt = ecount; + if (runnable[lwp_cpptr->priority].count == 0) + Cal_Highest_runnable_priority(); + old_cpptr = lwp_cpptr; + + /* wake up next lwp */ + lwp_cpptr = runnable[Highest_runnable_priority].head; + lwpremove(lwp_cpptr, &runnable[Highest_runnable_priority]); + timerclear(&lwp_cpptr->lastReady); + Debug(0, ("WaitProcess: %s Going to signal %s \n", + old_cpptr->name, lwp_cpptr->name)) + pthread_mutex_lock(&ct_mutex); + pthread_cond_signal(&lwp_cpptr->c); + + /* sleep on your own condition */ + Debug(0, ("WaitProcess:%s going to wait \n", old_cpptr->name)) + pthread_cond_wait(&old_cpptr->c, &ct_mutex); + pthread_mutex_unlock(&ct_mutex); + + /* update the global pointer */ + lwp_cpptr = old_cpptr; + if (lwp_cpptr->priority < Highest_runnable_priority) + Dispatcher(); + return LWP_SUCCESS ; + } + return LWP_EINIT ; + +} + +int +LWP_StackUsed(PROCESS pid, int *max, int *used) +{ + /* just here for compatibility */ + *max = -1; + *used = -1; + return LWP_SUCCESS; +} + +static void +Abort_LWP(char *msg) +{ + Debug(0, ("Entered Abort_LWP")) + printf("***LWP Abort: %s\n", msg); + Dump_Processes(); + Exit_LWP(); +} + +static void +Create_Process_Part2(PROCESS temp) +{ + /* set the global Proc_Running to signal the parent */ + pthread_mutex_lock(&run_sem); + Proc_Running = TRUE; + pthread_cond_wait(&temp->c, &run_sem); + pthread_mutex_unlock(&run_sem); + lwp_cpptr = temp; + +#ifdef _POSIX_THREAD_ATTR_STACKSIZE + pthread_attr_setstacksize(&temp->a, temp->stacksize); +#endif + + (*temp->ep)(temp->parm); + LWP_DestroyProcess(temp); +} + +static void +Dump_One_Process(PROCESS pid) +{ + int i; + + printf("***LWP: Process Control Block at 0x%x\n", (int)pid); + printf("***LWP: Name: %s\n", pid->name); + if (pid->ep != NULL) + printf("***LWP: Initial entry point: 0x%x\n", (int)pid->ep); + if (pid->blockflag) printf("BLOCKED and "); + switch (pid->status) { + case READY: printf("READY"); break; + case WAITING: printf("WAITING"); break; + case DESTROYED: printf("DESTROYED"); break; + default: printf("unknown"); + } + putchar('\n'); + printf("***LWP: Priority: %d \tInitial parameter: 0x%x\n", + pid->priority, (int)pid->parm); + + if (pid->eventcnt > 0) { + printf("***LWP: Number of events outstanding: %d\n", pid->waitcnt); + printf("***LWP: Event id list:"); + for (i=0;i<pid->eventcnt;i++) + printf(" 0x%x", (int)pid->eventlist[i]); + putchar('\n'); + } + if (pid->wakevent>0) + printf("***LWP: Number of last wakeup event: %d\n", pid->wakevent); +} + +static void +Dispatcher() /* Lightweight process dispatcher */ +{ + void *t; + int my_priority; + PROCESS old_cpptr; +#if 1 + int i = Highest_runnable_priority; + + Cal_Highest_runnable_priority(); + if (Highest_runnable_priority != i) + printf("hipri was %d actually %d\n", i, Highest_runnable_priority); + Highest_runnable_priority = i; +#endif + my_priority = lwp_cpptr->priority; + Debug(0, ("Dispatcher: %d runnable at pri %d hi %d blk %d", + runnable[my_priority].count, my_priority, + Highest_runnable_priority, PRE_Block)); + PRE_Block = 1; + if ((my_priority < Highest_runnable_priority) || + (runnable[my_priority].count > 0)) + { + Debug(0, ("Dispatcher: %s is now yielding", lwp_cpptr->name)); + /* I have to quit */ + old_cpptr = lwp_cpptr; + lwpinsert(old_cpptr, &runnable[my_priority]); + gettimeofday(&old_cpptr->lastReady, 0); + lwp_cpptr = runnable[Highest_runnable_priority].head; + + /* remove next process from runnable queue and signal it */ + lwpremove(lwp_cpptr, &runnable[Highest_runnable_priority]); + pthread_mutex_lock(&ct_mutex); + Debug(0, ("Dispatcher: %s going to signal %s condition\n", + old_cpptr->name, lwp_cpptr->name)) + + pthread_cond_signal(&lwp_cpptr->c); + + /* now sleep until somebody wakes me */ + Debug(0, ("Dispatcher: %s going to wait on own condition\n", + old_cpptr->name)) + pthread_cond_wait(&old_cpptr->c, &ct_mutex); + pthread_mutex_unlock(&ct_mutex); + + /* update global pointer */ + lwp_cpptr = old_cpptr; + } else { + Debug(0, ("Dispatcher: %s still running", lwp_cpptr->name)) + } + /* make sure HRP is set correct */ + Highest_runnable_priority = lwp_cpptr->priority; + if (lwp_cpptr->status == DESTROYED){ + /* the process was runnable but got destroyed by somebody */ + Free_PCB(lwp_cpptr); + Cal_Highest_runnable_priority(); + lwp_cpptr = runnable[Highest_runnable_priority].head; + lwpremove(lwp_cpptr, &runnable[Highest_runnable_priority]); + + pthread_mutex_lock(&ct_mutex); + pthread_cond_signal(&lwp_cpptr->c); + pthread_mutex_unlock(&ct_mutex); + pthread_exit(t); + } +#if 0 + if (PRE_Block != 1) Abort_LWP("PRE_Block not 1"); +#endif + PRE_Block = 0; +} + + +static void +Free_PCB(PROCESS pid) +{ + Debug(0, ("Entered Free_PCB")) + + if (pid->eventlist != NULL) free((char *)pid->eventlist); + free((char *)pid); +} + +static void +Initialize_PCB(PROCESS temp, int priority, char *stack, int stacksize, + void (*ep)(), char *parm, char *name) +{ + register int i = 0; + + Debug(0, ("Entered Initialize_PCB")) + if (name != NULL) + while (((temp -> name[i] = name[i]) != '\0') && (i < 31)) i++; + temp -> name[31] = '\0'; + temp -> status = READY; + temp -> eventlist = (char **)malloc(EVINITSIZE*sizeof(char *)); + temp -> eventlistsize = EVINITSIZE; + temp -> eventcnt = 0; + temp -> wakevent = 0; + temp -> waitcnt = 0; + temp -> blockflag = 0; + temp -> iomgrRequest = 0; + temp -> priority = priority; + temp -> index = lwp_nextindex++; + temp -> ep = ep; + temp -> parm = parm; + temp -> misc = NULL; /* currently unused */ + temp -> next = NULL; + temp -> prev = NULL; + temp -> rused = 0; + temp -> level = 1; /* non-preemptable */ + timerclear(&temp->lastReady); + + /* initialize the mutex and condition */ + pthread_mutex_init(&temp->m, NULL); + pthread_cond_init(&temp->c, NULL); + + Debug(0, ("Leaving Initialize_PCB\n")) +} + +static int +Internal_Signal(register char *event) +{ + int rc = LWP_ENOWAIT; + register int i; + + Debug(0, ("Entered Internal_Signal [event id 0x%x]", (int)event)); + if (!lwp_init) return LWP_EINIT; + if (event == NULL) return LWP_EBADEVENT; + + for_all_elts(temp, blocked, { /* for all pcb's on the blocked q */ + if (temp->status == WAITING) + for (i=0; i < temp->eventcnt; i++) { /* check each event in list */ + if (temp -> eventlist[i] == event) { + temp -> eventlist[i] = NULL; + rc = LWP_SUCCESS; + Debug(0, ("decrementing %s to %d", temp->name, (temp->waitcnt-1))); + /* reduce waitcnt by 1 for the signal */ + /* if wcount reaches 0 then make the process runnable */ + if (--temp->waitcnt == 0) { + temp -> status = READY; + temp -> wakevent = i+1; + lwpmove(temp, &blocked, &runnable[temp->priority]); + gettimeofday(&temp->lastReady, 0); + Highest_runnable_priority = + MAX(Highest_runnable_priority, temp->priority); + Debug(0, ("marked runnable. hi_pri %d, %d at %d", Highest_runnable_priority, runnable[temp->priority].count, temp->priority)); + break; + } + } + } + }) + return rc; +} + +/* places the maximum of runnable task priorities in the global variable - + * Highest_runnable_priority. No runnable process is an error */ +static void +Cal_Highest_runnable_priority() +{ + int i; + for (i = LWP_MAX_PRIORITY; runnable[i].count == 0 && i >=0; i--); +#if 0 + if (i < 0) + Abort_LWP("No ready processes"); + else + Highest_runnable_priority = i; +#else + if (i >= 0) + Highest_runnable_priority = i; +#endif +} diff --git a/usr.sbin/afs/src/lwp/plwp.h b/usr.sbin/afs/src/lwp/plwp.h new file mode 100644 index 00000000000..4857eef176d --- /dev/null +++ b/usr.sbin/afs/src/lwp/plwp.h @@ -0,0 +1,191 @@ +/* $OpenBSD: plwp.h,v 1.1 1999/04/30 01:59:13 art Exp $ */ +#ifndef LWP_INCLUDED +#define LWP_INCLUDED + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_POSIX_SIGNALS +#define AFS_POSIX_SIGNALS 1 +#endif +#define AFS_LWP_MINSTACKSIZE (100 * 1024) +#include <sys/time.h> +#include <signal.h> + +#ifndef LWP_KERNEL +extern +#endif +char lwp_debug; /* ON = show LWP debugging trace */ + +extern int lwp_stackUseEnabled; +extern int lwp_MaxStackSeen; +#define LWP_ActiveProcess (lwp_cpptr+0) + +#define LWP_VERSION 210888001 + +#define LWP_SUCCESS 0 +#define LWP_EBADPID -1 +#define LWP_EBLOCKED -2 +#define LWP_EINIT -3 +#define LWP_EMAXPROC -4 +#define LWP_ENOBLOCK -5 +#define LWP_ENOMEM -6 +#define LWP_ENOPROCESS -7 +#define LWP_ENOWAIT -8 +#define LWP_EBADCOUNT -9 +#define LWP_EBADEVENT -10 +#define LWP_EBADPRI -11 +#define LWP_NO_STACK -12 +/* These two are for the signal mechanism. */ +#define LWP_EBADSIG -13 /* bad signal number */ +#define LWP_ESYSTEM -14 /* system call failed */ +/* These are for the rock mechanism */ +#define LWP_ENOROCKS -15 /* all rocks are in use */ +#define LWP_EBADROCK -16 /* the specified rock does not exist */ + + +/* Maximum priority permissible (minimum is always 0) */ +#define LWP_MAX_PRIORITY 4 + +/* Usual priority used by user LWPs */ +#define LWP_NORMAL_PRIORITY (LWP_MAX_PRIORITY-1) + +#define LWP_SignalProcess(event) LWP_INTERNALSIGNAL(event, 1) +#define LWP_NoYieldSignal(event) LWP_INTERNALSIGNAL(event, 0) + +/* Users aren't really supposed to know what a pcb is, but .....*/ +typedef struct lwp_pcb *PROCESS; + +/* Action to take on stack overflow. */ +#define LWP_SOQUIET 1 /* do nothing */ +#define LWP_SOABORT 2 /* abort the program */ +#define LWP_SOMESSAGE 3 /* print a message and be quiet */ +extern int lwp_overflowAction; + +/* Tells if stack size counting is enabled. */ +extern int lwp_stackUseEnabled; + +int LWP_QWait(void); +int LWP_QSignal(PROCESS); +int LWP_Init(int, int, PROCESS *); +int LWP_InitializeProcessSupport(int, PROCESS *); +int LWP_TerminateProcessSupport(); +int LWP_CreateProcess(void (*)(), int, int, char *, char *, PROCESS *); +int LWP_CurrentProcess(PROCESS *); +int LWP_DestroyProcess(PROCESS); +int LWP_DispatchProcess(); +int LWP_GetProcessPriority(PROCESS, int *); +int LWP_INTERNALSIGNAL(void *, int); +int LWP_WaitProcess(char *); +int LWP_MwaitProcess(int, char **); +int LWP_StackUsed(PROCESS, int *, int *); +int LWP_NewRock(int, char *); +int LWP_GetRock(int, char **); +char *LWP_Name(); +int LWP_Index(); +int LWP_HighestIndex(); + +int IOMGR_SoftSig(void (*)(), char *); +int IOMGR_Initialize(void); +int IOMGR_Finalize(void); +long IOMGR_Poll(void); +int IOMGR_Select(int, fd_set *, fd_set *, fd_set *, struct timeval *); +int IOMGR_Cancel(register PROCESS); +int IOMGR_Signal(int, char *); +int IOMGR_CancelSignal(int); +void IOMGR_Sleep(unsigned int); + +int FT_Init(int, int); +#if __GNUC__ >= 2 +struct timezone; +#endif +int FT_GetTimeOfDay(register struct timeval *, register struct timezone *); +int TM_GetTimeOfDay(struct timeval *, struct timezone *); +int FT_AGetTimeOfDay(struct timeval *, struct timezone *); +unsigned int FT_ApproxTime(void); + +#include <pthread.h> + +/* Initial size of eventlist in a PCB; grows dynamically */ +#define EVINITSIZE 5 + +struct rock + {/* to hide things associated with this LWP under */ + int tag; /* unique identifier for this rock */ + pthread_key_t val; + /*char *value;*/ /* pointer to some arbitrary data structure */ + }; + +#define MAXROCKS 4 /* max no. of rocks per LWP */ + +struct lwp_pcb { /* process control block */ + char name[32]; + int rc; + char status; + char **eventlist; + char eventlistsize; + int eventcnt; + int wakevent; + int waitcnt; + char blockflag; + int priority; + PROCESS misc; + char *stack; + int stacksize; + long stackcheck; + void (*ep)(char *); + char *parm; + int rused; + struct rock rlist[MAXROCKS]; + PROCESS next, prev; + int level; + struct IoRequest *iomgrRequest; + int index; + struct timeval lastReady; + pthread_mutex_t m; + pthread_cond_t c; + pthread_attr_t a; +}; + +extern int lwp_nextindex; /* Next lwp index to assign */ + +extern PROCESS lwp_cpptr; /* pointer to current process pcb */ +struct lwp_ctl { /* LWP control structure */ + int processcnt; /* number of lightweight processes */ + char *outersp; /* outermost stack pointer */ + PROCESS outerpid; /* process carved by Initialize */ + PROCESS first, last; /* ptrs to first and last pcbs */ + char dsptchstack[800]; /* stack for dispatcher use only */ +}; + +extern char PRE_Block; /* used in preemption control (in preempt.c) */ + +/* Debugging macro */ +#ifdef LWPDEBUG +#define lwpdebug(level, msg)\ + if (lwp_debug > level) {\ + printf("***LWP (0x%x): ", lwp_cpptr);\ + printf msg;\ + putchar('\n');\ + fflush(stdout);\ + } +#else /* LWPDEBUG */ +#define lwpdebug(level, msg) +#endif /* LWPDEBUG */ + +#define MAXTHREADS 100 + +#endif /* LWP_INCLUDED */ + + + diff --git a/usr.sbin/afs/src/lwp/preempt.c b/usr.sbin/afs/src/lwp/preempt.c index ba1d8cefb58..8bf6c182046 100644 --- a/usr.sbin/afs/src/lwp/preempt.c +++ b/usr.sbin/afs/src/lwp/preempt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: preempt.c,v 1.1.1.1 1998/09/14 21:53:12 art Exp $ */ +/* $OpenBSD: preempt.c,v 1.2 1999/04/30 01:59:13 art Exp $ */ /* **************************************************************************** * Copyright IBM Corporation 1988, 1989 - All Rights Reserved * @@ -30,10 +30,10 @@ #include <sys/time.h> #include <signal.h> -#include "lwp.h" +#include <lwp.h> #include "preempt.h" -RCSID("$KTH: preempt.c,v 1.5 1998/02/06 03:18:30 art Exp $"); +RCSID("$KTH: preempt.c,v 1.6 1999/02/01 04:56:13 assar Exp $"); char PRE_Block = 0; /* used in lwp.c and process.s */ diff --git a/usr.sbin/afs/src/lwp/preempt.h b/usr.sbin/afs/src/lwp/preempt.h index 6640747586c..ad26cdc2113 100644 --- a/usr.sbin/afs/src/lwp/preempt.h +++ b/usr.sbin/afs/src/lwp/preempt.h @@ -1,9 +1,9 @@ -/* $OpenBSD: preempt.h,v 1.1.1.1 1998/09/14 21:53:12 art Exp $ */ -/* $Header: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/preempt.h,v 1.1.1.1 1998/09/14 21:53:12 art Exp $ */ +/* $OpenBSD: preempt.h,v 1.2 1999/04/30 01:59:13 art Exp $ */ +/* $Header: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/preempt.h,v 1.2 1999/04/30 01:59:13 art Exp $ */ /* $Source: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/preempt.h,v $ */ #if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS) -static char *rcsidpreempt = "$Header: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/preempt.h,v 1.1.1.1 1998/09/14 21:53:12 art Exp $"; +static char *rcsidpreempt = "$Header: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/preempt.h,v 1.2 1999/04/30 01:59:13 art Exp $"; #endif /* @@ -41,3 +41,7 @@ static char *rcsidpreempt = "$Header: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/p #define PRE_EndCritical() lwp_cpptr->level-- #define DEFAULTSLICE 10 + +int PRE_InitPreempt(struct timeval *); +int PRE_EndPreempt(void); + diff --git a/usr.sbin/afs/src/lwp/process-vpp.s b/usr.sbin/afs/src/lwp/process-vpp.s new file mode 100644 index 00000000000..707f7c855b5 --- /dev/null +++ b/usr.sbin/afs/src/lwp/process-vpp.s @@ -0,0 +1,171 @@ +/* -*- text -*- */ +/* + * Copyright (c) 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id: process-vpp.s,v 1.1 1999/04/30 01:59:14 art Exp $ */ + +/* LWP context switch for Fujitsu UXP/V */ + +#define registers 8 /* leave room for fp, and ra */ +#define floats (registers + 12 * 4) +#ifdef SAVE_FLOATS +#define FRAMESIZE (floats + 15 * 8) +#else +#define FRAMESIZE floats +#endif + +/* +void savecontext(int (*)(void), struct savearea*, void*); +*/ + + .section .text + .global savecontext + .align 8 +savecontext: + /* make space */ + or %gr1, %gr0, %gr2 & st %gr2, %gr1, 4 + addi23 %gr1, -FRAMESIZE, %gr1 & st %gr3, %gr2, %gr0 + + /* save registers */ + /* XXX save more registers? */ + st %gr4, %gr1, registers + 0 + st %gr5, %gr1, registers + 4 + st %gr6, %gr1, registers + 8 + st %gr7, %gr1, registers + 12 + st %gr8, %gr1, registers + 16 + st %gr9, %gr1, registers + 20 + st %gr10, %gr1, registers + 24 + st %gr11, %gr1, registers + 28 + st %gr12, %gr1, registers + 32 + st %gr13, %gr1, registers + 36 + st %gr14, %gr1, registers + 40 + st %gr15, %gr1, registers + 44 + +#ifdef SAVE_FLOATS + /* save floting point registers */ + st.d %fr1, %gr1, floats + 0 + st.d %fr2, %gr1, floats + 8 + st.d %fr3, %gr1, floats + 16 + st.d %fr4, %gr1, floats + 24 + st.d %fr5, %gr1, floats + 32 + st.d %fr6, %gr1, floats + 40 + st.d %fr7, %gr1, floats + 48 + st.d %fr8, %gr1, floats + 56 + st.d %fr9, %gr1, floats + 64 + st.d %fr10, %gr1, floats + 72 + st.d %fr11, %gr1, floats + 80 + st.d %fr12, %gr1, floats + 88 + st.d %fr13, %gr1, floats + 96 + st.d %fr14, %gr1, floats + 104 + st.d %fr15, %gr1, floats + 112 +#endif + + /* block */ + addi5 %gr0, 1, %gr20 + seti PRE_Block, %gr21 + st.c %gr20, %gr21, 0 + + /* save sp */ + st %gr1, %gr17, 0 + /* new sp */ + subi5 %gr18, 0, %gr0 + brc %iccp.z, samestack + + /* switch to new stack */ + or %gr18, %gr0, %gr1 + /* load fp */ + ld %gr1, 0, %gr2 + +samestack: + /* is this necessary? */ + or %gr16, %gr0, %gr3 + jmp %gr3 + + .type savecontext,@function + .size savecontext,.-savecontext + +/* +void returnto(struct savearea*); +*/ + .global returnto + .align 8 +returnto: + seti PRE_Block, %gr17 + st.c %gr0, %gr17, 0 + /* restore sp */ + ld %gr16, 0, %gr1 + /* restore registers */ + ld %gr1, registers + 0, %gr4 + ld %gr1, registers + 4, %gr5 + ld %gr1, registers + 8, %gr6 + ld %gr1, registers + 12, %gr7 + ld %gr1, registers + 16, %gr8 + ld %gr1, registers + 20, %gr9 + ld %gr1, registers + 24, %gr10 + ld %gr1, registers + 28, %gr11 + ld %gr1, registers + 32, %gr12 + ld %gr1, registers + 36, %gr13 + ld %gr1, registers + 40, %gr14 + ld %gr1, registers + 44, %gr15 + +#ifdef SAVE_FLOATS + /* restore floting point registers */ + ld.d %gr1, floats + 0, %fr1 + ld.d %gr1, floats + 8, %fr2 + ld.d %gr1, floats + 16, %fr3 + ld.d %gr1, floats + 24, %fr4 + ld.d %gr1, floats + 32, %fr5 + ld.d %gr1, floats + 40, %fr6 + ld.d %gr1, floats + 48, %fr7 + ld.d %gr1, floats + 56, %fr8 + ld.d %gr1, floats + 64, %fr9 + ld.d %gr1, floats + 72, %fr10 + ld.d %gr1, floats + 80, %fr11 + ld.d %gr1, floats + 88, %fr12 + ld.d %gr1, floats + 96, %fr13 + ld.d %gr1, floats + 104, %fr14 + ld.d %gr1, floats + 112, %fr15 +#endif + addi23 %gr1, FRAMESIZE, %gr1 + ld %gr1, 0, %gr3 + ld %gr1, 4, %gr2 + + jmp %gr3 + + .type returnto,@function + .size returnto,.-returnto diff --git a/usr.sbin/afs/src/lwp/process.S b/usr.sbin/afs/src/lwp/process.S index 5078caad1eb..5808930f058 100644 --- a/usr.sbin/afs/src/lwp/process.S +++ b/usr.sbin/afs/src/lwp/process.S @@ -1,4 +1,4 @@ -/* $Header: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/process.S,v 1.3 1999/02/01 16:23:14 pefo Exp $ */ +/* $Header: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/process.S,v 1.4 1999/04/30 01:59:14 art Exp $ */ /* $Source: /home/cvs/src/usr.sbin/afs/src/lwp/Attic/process.S,v $ */ /* @@ -22,6 +22,8 @@ **************************************************************************** */ +#include <config.h> + #if defined(RIOS) /* lws 92.11.18 I don't know if we have to save the TOC (R2) or not... @@ -266,42 +268,44 @@ _returnto: clrb _PRE_Block rts | Return to previous process #endif /* mc68000 */ -#ifdef sparc -#ifdef AFS_SUN5_ENV -#include <sys/asm_linkage.h> -#include <sys/trap.h> -#else -#ifdef AFS_NETBSD_ENV + +#ifdef sparc +#if defined(AFS_SUN5_ENV) +#include <sys/asm_linkage.h> +#include <sys/trap.h> +#ifndef STACK_BIAS +#define STACK_BIAS 0 +#endif +#elif defined(AFS_BSD_ENV) #include <machine/trap.h> #define ST_FLUSH_WINDOWS ST_FLUSHWIN #define MINFRAME 92 #define SA(x) (((x)+7)&~7) #define STACK_ALIGN 8 -#else -#ifdef AFS_LINUX_ENV +#define STACK_BIAS 0 +#elif defined(AFS_LINUX_ENV) #define AFS_SUN5_ENV 1 /* Make believe this is Solaris */ #define ST_FLUSH_WINDOWS 0x03 /* XXX: from asm/traps.h */ #define MINFRAME 92 #define SA(x) (((x)+7)&~7) #define STACK_ALIGN 8 -#else /* SunOS 4: */ -#include <sun4/asm_linkage.h> -#include <sun4/trap.h> -#endif -#endif +#define STACK_BIAS 0 +#else /* SunOS4 */ +#include <sun4/asm_linkage.h> +#include <sun4/trap.h> #endif + .data #ifdef AFS_SUN5_ENV .globl PRE_Block #else .globl _PRE_Block #endif -topstack = 0 -globals = 4 /* # savecontext(f, area1, newsp) # int (*f)(); struct savearea *area1; char *newsp; */ + .text #ifdef AFS_SUN5_ENV .globl savecontext @@ -315,13 +319,117 @@ _savecontext: /* The following 3 lines do the equivalent of: _PRE_Block = 1 */ #ifdef AFS_SUN5_ENV - set PRE_Block, %l0 -#else + +#ifdef __sparcv9 + sethi %hh(PRE_Block),%l0 + or %l0,%hm(PRE_Block),%l0 + sethi %lm(PRE_Block),%g1 + or %g1,%lo(PRE_Block),%g1 + sllx %l0,32,%l0 + or %l0,%g1,%l0 +#else + sethi %hi(PRE_Block),%l0 + or %l0,%lo(PRE_Block),%l0 +#endif +#else /* AFS_SUN5_ENV */ set _PRE_Block, %l0 #endif mov 1,%l1 stb %l1, [%l0] +#ifdef __sparcv9 + +topstack = 0 +globals = 8 + + stx %fp,[%i1+topstack] ! area1->topstack = sp + + stx %g1, [%i1 + globals + 0] /* Save all globals just in case */ + stx %g2, [%i1 + globals + 8] + stx %g3, [%i1 + globals + 16] + stx %g4, [%i1 + globals + 24] + stx %g5, [%i1 + globals + 32] + stx %g6, [%i1 + globals + 40] + stx %g7, [%i1 + globals + 48] + mov %y, %g1 + stx %g1, [%i1 + globals + 56] + +#ifdef save_allregs + stx %f0, [%i1 + globals + 64 + 0] + stx %f1, [%i1 + globals + 64 + 8] + stx %f2, [%i1 + globals + 64 + 16] + stx %f3, [%i1 + globals + 64 + 24] + stx %f4, [%i1 + globals + 64 + 32] + stx %f5, [%i1 + globals + 64 + 40] + stx %f6, [%i1 + globals + 64 + 48] + stx %f7, [%i1 + globals + 64 + 56] + stx %f8, [%i1 + globals + 64 + 64] + stx %f9, [%i1 + globals + 64 + 72] + stx %f10, [%i1 + globals + 64 + 80] + stx %f11, [%i1 + globals + 64 + 88] + stx %f12, [%i1 + globals + 64 + 96] + stx %f13, [%i1 + globals + 64 + 104] + stx %f14, [%i1 + globals + 64 + 112] + stx %f15, [%i1 + globals + 64 + 120] + stx %f16, [%i1 + globals + 64 + 128] + stx %f17, [%i1 + globals + 64 + 136] + stx %f18, [%i1 + globals + 64 + 144] + stx %f19, [%i1 + globals + 64 + 152] + stx %f20, [%i1 + globals + 64 + 160] + stx %f21, [%i1 + globals + 64 + 168] + stx %f22, [%i1 + globals + 64 + 176] + stx %f23, [%i1 + globals + 64 + 184] + stx %f24, [%i1 + globals + 64 + 192] + stx %f25, [%i1 + globals + 64 + 200] + stx %f26, [%i1 + globals + 64 + 208] + stx %f27, [%i1 + globals + 64 + 216] + stx %f28, [%i1 + globals + 64 + 224] + stx %f29, [%i1 + globals + 64 + 232] + stx %f30, [%i1 + globals + 64 + 240] + stx %f31, [%i1 + globals + 64 + 248] + stx %f32, [%i1 + globals + 64 + 256] + stx %f33, [%i1 + globals + 64 + 264] + stx %f34, [%i1 + globals + 64 + 272] + stx %f35, [%i1 + globals + 64 + 280] + stx %f36, [%i1 + globals + 64 + 288] + stx %f37, [%i1 + globals + 64 + 296] + stx %f38, [%i1 + globals + 64 + 304] + stx %f39, [%i1 + globals + 64 + 312] + stx %f40, [%i1 + globals + 64 + 320] + stx %f41, [%i1 + globals + 64 + 328] + stx %f42, [%i1 + globals + 64 + 336] + stx %f43, [%i1 + globals + 64 + 344] + stx %f44, [%i1 + globals + 64 + 352] + stx %f45, [%i1 + globals + 64 + 360] + stx %f46, [%i1 + globals + 64 + 368] + stx %f47, [%i1 + globals + 64 + 376] + stx %f48, [%i1 + globals + 64 + 384] + stx %f49, [%i1 + globals + 64 + 392] + stx %f50, [%i1 + globals + 64 + 400] + stx %f51, [%i1 + globals + 64 + 408] + stx %f52, [%i1 + globals + 64 + 416] + stx %f53, [%i1 + globals + 64 + 424] + stx %f54, [%i1 + globals + 64 + 432] + stx %f55, [%i1 + globals + 64 + 440] + stx %f56, [%i1 + globals + 64 + 448] + stx %f57, [%i1 + globals + 64 + 456] + stx %f59, [%i1 + globals + 64 + 464] + stx %f60, [%i1 + globals + 64 + 472] + stx %f61, [%i1 + globals + 64 + 480] +#ifdef notdef + mov %fsr,%g1 + stx %g1, [%i1 + globals + 64 + 488] + mov %fq,%g1 + stx %g1, [%i1 + globals + 64 + 496] +#endif + +#endif + +#else /* !__sparcv9 */ + +topstack = 0 +globals = 4 + st %fp,[%i1+topstack] ! area1->topstack = sp st %g1, [%i1 + globals + 0] /* Save all globals just in case */ @@ -413,6 +521,9 @@ _savecontext: st %g1, [%i1 + globals + 200 + 100] #endif #endif + +#endif /* __sparcv9 */ + cmp %i2, 0 be,a L1 ! if (newsp == 0) no stack switch nop @@ -433,7 +544,7 @@ _savecontext: add %o2, STACK_ALIGN - 1, %o2 and %o2, ~(STACK_ALIGN - 1), %o2 call %o0 - sub %o2, SA(MINFRAME), %sp + sub %o2, SA(MINFRAME) + STACK_BIAS, %sp #endif L1: call %i0 ! call f() @@ -450,10 +561,100 @@ returnto: _returnto: #endif ta ST_FLUSH_WINDOWS ! FLush all other active windows - ld [%o0+topstack],%g1 ! sp = area1->topstack + +#ifdef __sparcv9 + +#ifdef save_allregs + ldx [%i1 + globals + 64 + 0], %f0 + ldx [%i1 + globals + 64 + 8], %f1 + ldx [%i1 + globals + 64 + 16], %f2 + ldx [%i1 + globals + 64 + 24], %f3 + ldx [%i1 + globals + 64 + 32], %f4 + ldx [%i1 + globals + 64 + 40], %f5 + ldx [%i1 + globals + 64 + 48], %f6 + ldx [%i1 + globals + 64 + 56], %f7 + ldx [%i1 + globals + 64 + 64], %f8 + ldx [%i1 + globals + 64 + 72], %f9 + ldx [%i1 + globals + 64 + 80], %f10 + ldx [%i1 + globals + 64 + 88], %f11 + ldx [%i1 + globals + 64 + 96], %f12 + ldx [%i1 + globals + 64 + 104], %f13 + ldx [%i1 + globals + 64 + 112], %f14 + ldx [%i1 + globals + 64 + 120], %f15 + ldx [%i1 + globals + 64 + 128], %f16 + ldx [%i1 + globals + 64 + 136], %f17 + ldx [%i1 + globals + 64 + 144], %f18 + ldx [%i1 + globals + 64 + 152], %f19 + ldx [%i1 + globals + 64 + 160], %f20 + ldx [%i1 + globals + 64 + 168], %f21 + ldx [%i1 + globals + 64 + 176], %f22 + ldx [%i1 + globals + 64 + 184], %f23 + ldx [%i1 + globals + 64 + 192], %f24 + ldx [%i1 + globals + 64 + 200], %f25 + ldx [%i1 + globals + 64 + 208], %f26 + ldx [%i1 + globals + 64 + 216], %f27 + ldx [%i1 + globals + 64 + 224], %f28 + ldx [%i1 + globals + 64 + 232], %f29 + ldx [%i1 + globals + 64 + 240], %f30 + ldx [%i1 + globals + 64 + 248], %f31 + ldx [%i1 + globals + 64 + 256], %f32 + ldx [%i1 + globals + 64 + 264], %f33 + ldx [%i1 + globals + 64 + 272], %f34 + ldx [%i1 + globals + 64 + 280], %f35 + ldx [%i1 + globals + 64 + 288], %f36 + ldx [%i1 + globals + 64 + 296], %f37 + ldx [%i1 + globals + 64 + 304], %f38 + ldx [%i1 + globals + 64 + 312], %f39 + ldx [%i1 + globals + 64 + 320], %f40 + ldx [%i1 + globals + 64 + 328], %f41 + ldx [%i1 + globals + 64 + 336], %f42 + ldx [%i1 + globals + 64 + 344], %f43 + ldx [%i1 + globals + 64 + 352], %f44 + ldx [%i1 + globals + 64 + 360], %f45 + ldx [%i1 + globals + 64 + 368], %f46 + ldx [%i1 + globals + 64 + 376], %f47 + ldx [%i1 + globals + 64 + 384], %f48 + ldx [%i1 + globals + 64 + 392], %f49 + ldx [%i1 + globals + 64 + 400], %f50 + ldx [%i1 + globals + 64 + 408], %f51 + ldx [%i1 + globals + 64 + 416], %f52 + ldx [%i1 + globals + 64 + 424], %f53 + ldx [%i1 + globals + 64 + 432], %f54 + ldx [%i1 + globals + 64 + 440], %f55 + ldx [%i1 + globals + 64 + 448], %f56 + ldx [%i1 + globals + 64 + 456], %f57 + ldx [%i1 + globals + 64 + 464], %f59 + ldx [%i1 + globals + 64 + 472], %f60 + ldx [%i1 + globals + 64 + 480], %f61 +#ifdef notdef + mov %fsr,%g1 + ldx [%i1 + globals + 64 + 488], %g1 + mov %fq,%g1 + ldx [%i1 + globals + 64 + 496], %g1 +#endif + +#endif + + ldx [%o0+topstack],%g1 ! sp = area1->topstack sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place sub %fp, SA(MINFRAME), %sp + + ldx [%o0 + globals + 56], %g1 ! Restore global regs back + mov %g1, %y + ldx [%o0 + globals + 0], %g1 + ldx [%o0 + globals + 8], %g2 + ldx [%o0 + globals + 16], %g3 + ldx [%o0 + globals + 24],%g4 + ldx [%o0 + globals + 32],%g5 + ldx [%o0 + globals + 40],%g6 + ldx [%o0 + globals + 48],%g7 + +#else /* !__sparcv9 */ + ld [%o0+topstack],%g1 ! sp = area1->topstack + sub %g1, SA(MINFRAME), %fp ! Adjust sp to the right place + sub %fp, SA(MINFRAME), %sp + #ifdef save_allregs ld [%o0 + globals + 32 + 0],%f0 ! Restore floating-point registers ld [%o0 + globals + 32 + 4],%f1 @@ -542,11 +743,23 @@ _returnto: ld [%o0 + globals + 16],%g5 ld [%o0 + globals + 20],%g6 ld [%o0 + globals + 24],%g7 + +#endif /* __sparcv9 */ /* The following 3 lines are equivalent to: _PRE_Block = 0 */ #ifdef AFS_SUN5_ENV - set PRE_Block, %l0 +#ifdef __sparcv9 + sethi %hh(PRE_Block),%l0 + or %l0,%hm(PRE_Block),%l0 + sethi %lm(PRE_Block),%g1 + or %g1,%lo(PRE_Block),%g1 + sllx %l0,32,%l0 + or %l0,%g1,%l0 #else + sethi %hi(PRE_Block),%l0 + or %l0,%lo(PRE_Block),%l0 +#endif +#else /* AFS_SUN5_ENV */ set _PRE_Block, %l0 #endif mov 0,%l1 @@ -825,13 +1038,15 @@ _returnto: #endif #ifdef mips -#if defined(sgi) || defined(__OpenBSD__) +#ifdef HAVE_PIC .option pic2 -#if defined(sgi) -#include <regdef.h> /* Allow use of symbolic names for registers. */ -#else -#include <machine/regdef.h> /* Allow use of symbolic names for registers. */ + +#if defined(HAVE_MACHINE_REGDEF_H) +#include <machine/regdef.h> +#elif defined(HAVE_REGDEF_H) +#include <regdef.h> #endif + /* 9 sregs, ra, 6 fp regs, gp, pad to 8 byte boundary */ #define regspace 9 * 4 + 4 + 6 * 8 + 4 + 4 #define floats 0 @@ -920,11 +1135,27 @@ returnto: /* Code for MIPS R2000/R3000 architecture * Written by Zalman Stern April 30th, 1989. */ -#ifndef __OpenBSD__ + +#if defined(HAVE_REGDEF_H) #include <regdef.h> /* Allow use of symbolic names for registers. */ #else -#include <machine/regdef.h> +#define sp $29 +#define ra $31 +#define t0 $8 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define s8 $30 #endif + #define regspace 9 * 4 + 4 + 6 * 8 #define floats 0 #define registers floats + 6 * 8 @@ -992,8 +1223,8 @@ returnto: sb $0, PRE_Block j ra .end returnto -#endif /* sgi */ -#endif +#endif /* HAVE_PIC */ +#endif /* mips */ #ifdef AFS_HPUX_ENV #include "process.s.hpux" @@ -1092,7 +1323,7 @@ ENTRY(returnto) #endif /* AFS_386i_ENV */ -#ifdef __alpha +#ifdef alpha /* Code for DEC Alpha architecture */ #ifdef AFS_OSF_ENV #include <machine/asm.h> @@ -1180,11 +1411,11 @@ x: ; \ #define IMPORT(sym, size) \ .extern sym,size -#elif AFS_NETBSD_ENV +#elif defined(HAVE_MACHINE_ASM_H) /* BSD */ #include <machine/asm.h> -#else /* OSF */ +#elif defined(HAVE_MACH_ALPHA_ASM_H) /* OSF */ #include <mach/alpha/asm.h> -#endif /* OSF */ +#endif #define FRAMESIZE ((8*8)+8+(7*8)) #define floats 0 @@ -1216,7 +1447,7 @@ NESTED(savecontext,3,FRAMESIZE,ra,0x0400f700,0x000003fc) /* Save return address */ stq ra, returnaddr(sp) -#if !defined(AFS_NETBSD_ENV) +#if !defined(AFS_BSD_ENV) .mask (M_S0|M_S1|M_S2|M_S3|M_S4|M_S5|M_S6|M_RA), -FRAMESIZE #endif diff --git a/usr.sbin/afs/src/lwp/rw.c b/usr.sbin/afs/src/lwp/rw.c new file mode 100644 index 00000000000..96e19d15e02 --- /dev/null +++ b/usr.sbin/afs/src/lwp/rw.c @@ -0,0 +1,255 @@ +/* $OpenBSD: rw.c,v 1.1 1999/04/30 01:59:14 art Exp $ */ +/* +**************************************************************************** +* Copyright IBM Corporation 1988, 1989 - All Rights Reserved * +* * +* Permission to use, copy, modify, and distribute this software and its * +* documentation for any purpose and without fee is hereby granted, * +* provided that the above copyright notice appear in all copies and * +* that both that copyright notice and this permission notice appear in * +* supporting documentation, and that the name of IBM not be used in * +* advertising or publicity pertaining to distribution of the software * +* without specific, written prior permission. * +* * +* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM * +* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * +* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * +* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * +* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * +**************************************************************************** +*/ + +/* + (Multiple) readers & writers test of LWP stuff. + +Created: 11/1/83, J. Rosenberg + +*/ + +#include <sys/time.h> +#include <stdio.h> +#include <stdlib.h> + +#include <lwp.h> +#include "lock.h" +#include "preempt.h" + +#define DEFAULT_READERS 5 + +#define STACK_SIZE (16*1024) + +/* The shared queue */ +typedef struct QUEUE { + struct QUEUE *prev, *next; + char *data; + struct Lock lock; +} queue; + +queue *init() +{ + queue *q; + + q = (queue *) malloc(sizeof(queue)); + q -> prev = q -> next = q; + return(q); +} + +char empty(queue *q) +{ + return (q->prev == q && q->next == q); +} + +void insert(queue *q, char *s) +{ + queue *new; + + new = (queue *) malloc(sizeof(queue)); + new -> data = s; + new -> prev = q -> prev; + q -> prev -> next = new; + q -> prev = new; + new -> next = q; +} + +char *Remove(queue *q) +{ + queue *old; + char *s; + + if (empty(q)) { + printf("Remove from empty queue"); + abort(); + } + + old = q -> next; + q -> next = old -> next; + q -> next -> prev = q; + s = old -> data; + free(old); + return(s); +} + +queue *q; + +int asleep; /* Number of processes sleeping -- used for + clean termination */ + +static int read_process(int id) +{ + int foo; + printf("\t[Reader %d]\n", id); + LWP_NewRock(1, id); + LWP_DispatchProcess(); /* Just relinquish control for now */ + + PRE_PreemptMe(); + for (;;) { + register int i; + + /* Wait until there is something in the queue */ + asleep++; + ObtainReadLock(&q->lock); + while (empty(q)) { + ReleaseReadLock(&q->lock); + LWP_WaitProcess((void *)q); + ObtainReadLock(&q->lock); + } + asleep--; + for (i=0; i<10000; i++) ; + PRE_BeginCritical(); + LWP_GetRock(1, &foo); + printf("[%d: %s]\n", foo, Remove(q)); + PRE_EndCritical(); + ReleaseReadLock(&q->lock); + LWP_DispatchProcess(); + } +} + +static void write_process() +{ + static char *messages[] = + { + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + "Mary had a little lamb,", + "Its fleece was white as snow,", + "And everywhere that Mary went,", + "The lamb was sure to go", + 0 + }; + char **mesg; + + printf("\t[Writer]\n"); + PRE_PreemptMe(); + + /* Now loop & write data */ + for (mesg=messages; *mesg!=0; mesg++) { + ObtainWriteLock(&q->lock); + insert(q, *mesg); + ReleaseWriteLock(&q->lock); + LWP_SignalProcess(q); + } + + asleep++; +} + +/* + Arguments: + 0: Unix junk, ignore + 1: Number of readers to create (default is DEFAULT_READERS) + 2: # msecs for interrupt (to satisfy Larry) + 3: Present if lwp_debug to be set +*/ + + +int +main(int argc, char **argv) +{ + int nreaders, i; + long interval; /* To satisfy Brad */ + PROCESS *readers; + PROCESS writer, master; + struct timeval tv; + char rname[9]; + + printf("\n*Readers & Writers*\n\n"); + setbuf(stdout, 0); + + /* Determine # readers */ + if (argc == 1) + nreaders = DEFAULT_READERS; + else + sscanf(*++argv, "%d", &nreaders); + printf("[There will be %d readers]\n", nreaders); + + interval = (argc >= 3 ? atoi(*++argv)*1000 : 50000); + + if (argc == 4) lwp_debug = 1; + LWP_InitializeProcessSupport(0, &master); + printf("[Support initialized]\n"); + tv.tv_sec = 0; + tv.tv_usec = interval; + PRE_InitPreempt(&tv); + + /* Initialize queue */ + q = init(); + + /* Initialize lock */ + Lock_Init(&q->lock); + + asleep = 0; + /* Now create readers */ + printf("[Creating Readers...\n"); + readers = (PROCESS *) calloc(nreaders, sizeof(PROCESS)); + for (i=0; i<nreaders; i++) { + sprintf(rname, "Reader %d", i); + LWP_CreateProcess((void *)(read_process), STACK_SIZE, 0, (char *)i, + rname, &readers[i]); + } + printf("done]\n"); + + printf("\t[Creating Writer...\n"); + LWP_CreateProcess(write_process, STACK_SIZE, 1, 0, "Writer", &writer); + printf("done]\n"); + + /* Now loop until everyone's done */ + while (asleep != nreaders+1) LWP_DispatchProcess(); + /* Destroy the readers */ + for (i=nreaders-1; i>=0; i--) LWP_DestroyProcess(readers[i]); + printf("\n*Exiting*\n"); + return 0; +} diff --git a/usr.sbin/afs/src/lwp/testlwp.c b/usr.sbin/afs/src/lwp/testlwp.c index f967691ea09..3eb1b686ab8 100644 --- a/usr.sbin/afs/src/lwp/testlwp.c +++ b/usr.sbin/afs/src/lwp/testlwp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: testlwp.c,v 1.1.1.1 1998/09/14 21:53:13 art Exp $ */ +/* $OpenBSD: testlwp.c,v 1.2 1999/04/30 01:59:14 art Exp $ */ /* * Copyright (c) 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -40,11 +40,11 @@ /* * testlwp * - * Checks if lwp seams to work, and demostrates how to use lwp. - * Give multiple commands om the argumentline to run several - * tests on the same time. + * Checks if lwp seems to work, and demostrates how to use lwp. Give + * multiple commands on the command line to run several tests at the + * same time. * - * $KTH: testlwp.c,v 1.2 1998/07/15 12:50:58 map Exp $ + * $KTH: testlwp.c,v 1.3 1998/10/25 19:37:33 joda Exp $ * */ @@ -299,7 +299,7 @@ int main(int argc, char **argv) } else if (strcasecmp("cancel", argv[1]) == 0) { yaEndlessLoop(); } else if (strcasecmp("version", argv[1]) == 0) { - printf("Version: $KTH: testlwp.c,v 1.2 1998/07/15 12:50:58 map Exp $\n"); + printf("Version: $KTH: testlwp.c,v 1.3 1998/10/25 19:37:33 joda Exp $\n"); } else { printf("unknown command %s\n", argv[1]); } diff --git a/usr.sbin/afs/src/rx/rx-new.h b/usr.sbin/afs/src/rx/rx-new.h new file mode 100644 index 00000000000..f335e7a0fe4 --- /dev/null +++ b/usr.sbin/afs/src/rx/rx-new.h @@ -0,0 +1,239 @@ +/* $OpenBSD: rx-new.h,v 1.1 1999/04/30 01:59:14 art Exp $ */ +/* + * rx.h,v 1.7 1995/04/11 06:07:07 assar Exp + */ + +#ifndef _RX_ +#define _RX_ + +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <list.h> +#include <pthread.h> +#include <thrpool.h> + +#include <rx_pkt.h> + +/* XXX - This should be moved somewhere else and replaced with XDR */ + +typedef u_long unsigned32; +typedef u_short unsigned16; + +/* Security garbage */ + +typedef struct rx_securityClass { +} rx_securityClass; + +typedef struct rx_connection rx_connection; + +typedef struct rx_call rx_call; + +typedef struct rx_service rx_service; + +#define RX_MAXDATA 1444 /* XXX - ??? */ + + +typedef struct rx_wirepacket { + rx_header header; + char data[RX_MAXDATA]; +} rx_wirepacket; + +/* + * There are two different types of acks. + * soft ack means that the packet has been receieved at the other end, + * but the sender should not throw away the packet yet. The receiver + * can still drop the packet or not give it to the application. + * The point of the soft acks is mainly flow-control. + * + * A hard ack means that the packet has been acknowledged by the + * application. Then the packet can be thrown away. + * + */ + +typedef enum { + RX_PKT_SOFT_ACK = 1 +} rx_packet_flags; + +typedef struct rx_packet { + rx_wirepacket wire; + unsigned datalen; + rx_call *call; + rx_packet_flags flags; +} rx_packet; + + +/* every call - i.e. RPC transaction */ + +struct rx_call { + enum { SENDING, RECEIVING } mode; + u_long callno; /* Call # of this connection */ + u_long seqno; /* Seq # for packets */ + int channelid; /* What channel are we using? */ + rx_connection *conn; + List *recvpackets; /* List of received packets */ +#if 0 + List *ooopackets; /* Packets rec'd out-of-order */ +#endif + rx_packet *thispacket; /* This packet, sending or receiving */ + char *ptr; /* Here we should write data */ + unsigned nleft; /* How much data there is left */ + pthread_mutex_t mutex; /* Synchronisation */ + pthread_cond_t cond; +}; + +/* This represents the on-going communication, i.e. a connection */ + +typedef enum { + RX_CONN_SERVER, /* This is a server */ + RX_CONN_CLIENT /* The other side is a server */ +} rx_connection_type; + +#define RX_WINDOW 15 + +struct rx_connection { + time_t epoch; /* Time when this connection started */ + u_long connid; /* Connection ID. How? */ + struct sockaddr_in peer; /* The one we're talking to */ + u_long serialno; /* Next serial number to use */ + u_long callno[MAXCALLS]; /* Next call number to use */ + rx_call *calls[MAXCALLS]; /* The on-going calls */ + u_char secindex; /* Security index */ + u_short serviceid; /* Service ID */ + rx_connection_type type; /* Type of connection C-S or S-C */ + u_long maxnoacked; /* Max packet sent and soft-acked */ + List *packets; /* Not yet acked sent packets */ + u_long window; /* Size of the window */ + pthread_cond_t condsend; /* Conditional variable for sending */ + pthread_mutex_t mutexsend; /* Mutex for above */ + pthread_cond_t condrecv; + pthread_mutex_t mutexrecv; + rx_service *service; /* Service if server, else NULL */ +}; + +/* + * About packets: + * + * Here we keep the packets that have been sent but not yet + * hard-acked. When a packet has been soft-acked we set a flag in the + * packet_flags and stop the resend-timer. + */ + +struct rx_service { + u_short port; + u_short serviceid; + char *servicename; + int (*serviceproc)(rx_call *); + Thrpool *thrpool; +}; + +/* functions */ + +int rx_Init (int port); + +rx_connection *rx_NewConnection (struct in_addr host, u_short port, + u_short service, + rx_securityClass *sec, + int secindex); + +void rx_DestroyConnection (rx_connection *); + +rx_call *rx_NewCall (rx_connection *); + +int rx_EndCall (rx_call *, int); + +rx_service *rx_NewService(u_short port, u_short serviceid, + char *servicename, rx_securityClass **so, + int nso, int (*serviceproc)(rx_call *)); + +int rx_Write (rx_call *, void *, int); +int rx_Read (rx_call *, void *, int); +int rx_FlushWrite (rx_call *call); + + +#endif /* _RX_ */ + + + + +/* Old garbage */ + +#if 0 + +/* header of a RPC packet */ +/* We should use XDR on this too. */ + +typedef enum { + HT_DATA = 1, + HT_ACK = 2, + HT_BUSY = 3, + HT_ABORT = 4, + HT_ACKALL = 5, + HT_CHAL = 6, + HT_RESP = 7, + HT_DEBUG = 8 +} rx_header_type; + +/* For flags in header */ + +enum { + HF_CLIENT_INITIATED = 1, + HF_REQ_ACK = 2, + HF_LAST = 4, + HF_MORE = 8}; + +#define MAXCALLS 4 + +#define CALL_MASK (MAXCALLS-1) +#define CONNID_MASK (~(MAXCALLS-1)) + +typedef struct rx_header { + unsigned32 epoch; + unsigned32 connid; /* And channel ID */ + unsigned32 callid; + unsigned32 seqno; /* Call-based number */ + unsigned32 serialno; /* Unique number */ + u_char type; + u_char flags; + u_char status; + u_char secindex; + unsigned16 reserved; /* ??? verifier? */ + unsigned16 serviceid; +/* This should be the other way around according to everything but */ +/* tcpdump */ +} rx_header; + +#endif + +#if 0 + +typedef enum { + RX_ACK_REQUESTED = 1, + RX_ACK_DUPLICATE = 2, + RX_ACK_OUT_OF_SEQUENCE = 3, + RX_ACK_EXEEDS_WINDOW = 4, + RX_ACK_NOSPACE = 5, + RX_ACK_PING = 6, + RX_ACK_PING_RESPONSE = 7, + RX_ACK_DELAY = 8 +} rx_ack_reason; + +typedef enum { + RX_ACK_TYPE_NACK = 0, + RX_ACK_TYPE_ACK = 1 +} rx_ack_type; + +#define RXMAXACKS 255 + +typedef struct rx_ack_packet { + unsigned16 bufferspace; + unsigned16 maxskew; + unsigned32 firstpacket; /* First packet in acks below */ + unsigned32 prevpacket; + unsigned32 serial; /* Packet that prompted this one */ + u_char reason; /* rx_ack_reason */ + u_char nacks; /* # of acks */ + u_char acks[RXMAXACKS]; /* acks (rx_ack_type) */ +} rx_ack_packet; + +#endif diff --git a/usr.sbin/afs/src/rx/rx.c b/usr.sbin/afs/src/rx/rx.c index ffc5b62778a..8ff3ebbead6 100644 --- a/usr.sbin/afs/src/rx/rx.c +++ b/usr.sbin/afs/src/rx/rx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rx.c,v 1.1.1.1 1998/09/14 21:53:14 art Exp $ */ +/* $OpenBSD: rx.c,v 1.2 1999/04/30 01:59:14 art Exp $ */ /* **************************************************************************** * Copyright IBM Corporation 1988, 1989 - All Rights Reserved * @@ -24,7 +24,7 @@ #include "rx_locl.h" -RCSID("$KTH: rx.c,v 1.5 1998/02/24 01:36:30 art Exp $"); +RCSID("$KTH: rx.c,v 1.6 1998/09/09 10:17:52 assar Exp $"); /* * quota system: each attached server process must be able to make @@ -65,7 +65,7 @@ long Rx0 = 0, Rx1 = 0; struct rx_serverQueueEntry *rx_waitForPacket = 0; struct rx_packet *rx_allocedP = 0; #if 0 -static char rxrcsid[] = "@(#)$KTH: rx.c,v 1.5 1998/02/24 01:36:30 art Exp $"; +static char rxrcsid[] = "@(#)$KTH: rx.c,v 1.6 1998/09/09 10:17:52 assar Exp $"; #endif /* ------------Exported Interfaces------------- */ diff --git a/usr.sbin/afs/src/rx/rx.h b/usr.sbin/afs/src/rx/rx.h index bb46a439744..621a14a1ae7 100644 --- a/usr.sbin/afs/src/rx/rx.h +++ b/usr.sbin/afs/src/rx/rx.h @@ -1,5 +1,5 @@ -/* $OpenBSD: rx.h,v 1.1.1.1 1998/09/14 21:53:14 art Exp $ */ -/* $KTH: rx.h,v 1.8 1998/03/01 15:26:57 assar Exp $ */ +/* $OpenBSD: rx.h,v 1.2 1999/04/30 01:59:15 art Exp $ */ +/* $KTH: rx.h,v 1.10 1998/10/20 02:49:53 art Exp $ */ /* **************************************************************************** @@ -38,6 +38,7 @@ #endif #include <atypes.h> #include <stdio.h> +#include <sys/param.h> #include "rx_mach.h" #include "rx_user.h" #include "rx_clock.h" diff --git a/usr.sbin/afs/src/rx/rx_clock.c b/usr.sbin/afs/src/rx/rx_clock.c index ecc93700132..729c5dec7ef 100644 --- a/usr.sbin/afs/src/rx/rx_clock.c +++ b/usr.sbin/afs/src/rx/rx_clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rx_clock.c,v 1.1.1.1 1998/09/14 21:53:14 art Exp $ */ +/* $OpenBSD: rx_clock.c,v 1.2 1999/04/30 01:59:15 art Exp $ */ /* **************************************************************************** * Copyright IBM Corporation 1988, 1989 - All Rights Reserved * @@ -25,7 +25,7 @@ #include "rx_locl.h" -RCSID("$KTH: rx_clock.c,v 1.4 1998/03/13 01:10:57 art Exp $"); +RCSID("$KTH: rx_clock.c,v 1.5 1998/10/25 19:38:30 joda Exp $"); #ifndef KERNEL @@ -36,6 +36,8 @@ RCSID("$KTH: rx_clock.c,v 1.4 1998/03/13 01:10:57 art Exp $"); #ifdef AFS_SUN5_ENV #define STARTVALUE 10000000 /* Max number of seconds setitimer * allows, for some reason */ +#elif defined(__uxpv__) +#define STARTVALUE 42949672 #else #define STARTVALUE 100000000 /* Max number of seconds setitimer * allows, for some reason */ diff --git a/usr.sbin/afs/src/rx/rx_pkt.c b/usr.sbin/afs/src/rx/rx_pkt.c index 30df91d56c7..3e2a1d083c2 100644 --- a/usr.sbin/afs/src/rx/rx_pkt.c +++ b/usr.sbin/afs/src/rx/rx_pkt.c @@ -1,12 +1,15 @@ -/* $OpenBSD: rx_pkt.c,v 1.1.1.1 1998/09/14 21:53:16 art Exp $ */ +/* $OpenBSD: rx_pkt.c,v 1.2 1999/04/30 01:59:15 art Exp $ */ #include "rx_locl.h" -RCSID("$KTH: rx_pkt.c,v 1.9 1998/03/14 13:40:22 assar Exp $"); +RCSID("$KTH: rx_pkt.c,v 1.11 1999/03/04 01:44:19 assar Exp $"); struct rx_packet *rx_mallocedP = 0; struct rx_cbuf *rx_mallocedC = 0; -char cml_version_number[4711]; /* XXX - What is this? */ +/* string to send to rxdebug */ +#define CML_VERSION_NUMBER_SIZE 65 +static char cml_version_number[CML_VERSION_NUMBER_SIZE]= PACKAGE "-" VERSION ; + extern int (*rx_almostSent) (); /* @@ -623,6 +626,11 @@ rxi_ReadPacket(int socket, struct rx_packet *p, p->wirevec[--p->niovecs].iov_base = NULL; p->wirevec[p->niovecs].iov_len = 0; + if (nbytes < 0) { + /* ignore error? */ + return 0; + } + p->length = (nbytes - RX_HEADER_SIZE); if ((nbytes > tlen) || (nbytes < (int)RX_HEADER_SIZE)) { /* Bogus packet */ if (nbytes > 0) @@ -674,7 +682,9 @@ osi_NetSend(osi_socket socket, char *addr, struct iovec *dvec, fd_set sfds; rx_stats.sendSelects++; - if (errno != EWOULDBLOCK && errno != ENOBUFS) { + if (errno != EWOULDBLOCK + && errno != ENOBUFS + && errno != ECONNREFUSED) { (osi_Msg "rx failed to send packet: "); perror("rx_send"); /* translates the message to English */ return 3; @@ -1010,7 +1020,7 @@ rxi_ReceiveVersionPacket(struct rx_packet *ap, osi_socket asocket, { long tl; - rx_packetwrite(ap, 0, 65, cml_version_number + 4); + rx_packetwrite(ap, 0, CML_VERSION_NUMBER_SIZE, cml_version_number); tl = ap->length; ap->length = 65; rxi_SendDebugPacket(ap, asocket, ahost, aport); diff --git a/usr.sbin/afs/src/rx/rx_pkt.h b/usr.sbin/afs/src/rx/rx_pkt.h index 8b7d50baef8..988b16ef59a 100644 --- a/usr.sbin/afs/src/rx/rx_pkt.h +++ b/usr.sbin/afs/src/rx/rx_pkt.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rx_pkt.h,v 1.1.1.1 1998/09/14 21:53:16 art Exp $ */ +/* $OpenBSD: rx_pkt.h,v 1.2 1999/04/30 01:59:15 art Exp $ */ #ifndef _RX_PACKET_ #define _RX_PACKET_ #include "sys/uio.h" @@ -20,7 +20,10 @@ * and that the offsets are as well. */ -#include <sys/param.h> + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif #define RX_IPUDP_SIZE 28 @@ -165,6 +168,11 @@ struct rx_header { * Both Firstbuffersize and cbuffersize must be integral multiples of 8, * so the security header and trailer stuff works for rxkad_crypt. yuck. */ + +#define RX_FIRSTBUFFERSIZE (OLD_MAX_PACKET_SIZE - RX_HEADER_SIZE - 4) +#define RX_CBUFFERSIZE 1024 + +#if 0 #if defined(AFS_SUN5_ENV) || defined(AFS_AOS_ENV) #define RX_FIRSTBUFFERSIZE (OLD_MAX_PACKET_SIZE - RX_HEADER_SIZE) #define RX_CBUFFERSIZE 1012 @@ -172,6 +180,8 @@ struct rx_header { #define RX_FIRSTBUFFERSIZE 480 /* MTUXXX should be 1444 */ #define RX_CBUFFERSIZE 504 /* MTUXXX change this to 1024 or 1012 */ #endif /* AFS_SUN5_ENV */ +#endif + struct rx_packet { struct rx_queue queueItemHeader; /* Packets are chained using the * queue.h package */ @@ -229,12 +239,12 @@ struct rx_cbuf { * caller. */ #define rx_GetLong(p,off) (( (off) >= (p)->wirevec[1].iov_len) ? \ rx_SlowGetLong((p), (off)) : \ - *((long *)((char *)(p)->wirevec[1].iov_base + (off)))) + *((u_int32_t *)((char *)(p)->wirevec[1].iov_base + (off)))) #define rx_PutLong(p,off,b) { \ if ((off) >= (p)->wirevec[1].iov_len) \ rx_SlowPutLong((p), (off), (b)); \ - else *((long *)((char *)(p)->wirevec[1].iov_base + (off))) = b; } + else *((u_int32_t *)((char *)(p)->wirevec[1].iov_base + (off))) = b; } #define rx_data(p, o, l) ((l=((struct rx_packet*)(p))->wirevec[(o+1)].iov_len),\ (((struct rx_packet*)(p))->wirevec[(o+1)].iov_base)) diff --git a/usr.sbin/afs/src/rx/rx_trace.c b/usr.sbin/afs/src/rx/rx_trace.c index 9ad2fbff8de..a00b718c84c 100644 --- a/usr.sbin/afs/src/rx/rx_trace.c +++ b/usr.sbin/afs/src/rx/rx_trace.c @@ -1,7 +1,7 @@ -/* $OpenBSD: rx_trace.c,v 1.1.1.1 1998/09/14 21:53:17 art Exp $ */ +/* $OpenBSD: rx_trace.c,v 1.2 1999/04/30 01:59:15 art Exp $ */ #include "rx_locl.h" -RCSID("$KTH: rx_trace.c,v 1.4 1998/02/22 19:55:04 joda Exp $"); +RCSID("$KTH: rx_trace.c,v 1.5 1998/09/09 10:17:53 assar Exp $"); #ifdef RXTRACEON char rxi_tracename[80] = "/tmp/rxcalltrace"; @@ -10,6 +10,9 @@ char rxi_tracename[80] = "/tmp/rxcalltrace"; char rxi_tracename[80] = "\0Change This pathname (and preceding NUL) to initiate tracing"; #endif + +#ifdef RXDEBUG + int rxi_logfd = 0; char rxi_tracebuf[4096]; unsigned long rxi_tracepos = 0; @@ -26,7 +29,6 @@ struct rx_trace { struct rx_trace rxtinfo; -#ifdef RXDEBUG void rxi_flushtrace(void) { @@ -99,7 +101,8 @@ rxi_calltrace(unsigned int event, struct rx_call *call) if (rxi_tracepos >= (4096 - sizeof(struct rx_trace))) rxi_flushtrace(); } -#endif + +#endif /* RXDEBUG */ #ifdef DUMPTRACE diff --git a/usr.sbin/afs/src/rx/rx_user.c b/usr.sbin/afs/src/rx/rx_user.c index b443cbb6c19..d5df290d96c 100644 --- a/usr.sbin/afs/src/rx/rx_user.c +++ b/usr.sbin/afs/src/rx/rx_user.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rx_user.c,v 1.1.1.1 1998/09/14 21:53:17 art Exp $ */ +/* $OpenBSD: rx_user.c,v 1.2 1999/04/30 01:59:15 art Exp $ */ /* **************************************************************************** * Copyright IBM Corporation 1988, 1989 - All Rights Reserved * @@ -27,7 +27,7 @@ #include "rx_locl.h" -RCSID("$KTH: rx_user.c,v 1.10 1998/04/08 05:19:34 lha Exp $"); +RCSID("$KTH: rx_user.c,v 1.14 1999/03/05 04:18:16 assar Exp $"); #ifndef IPPORT_USERRESERVED /* @@ -141,50 +141,37 @@ rxi_StartServerProcs(int nExistingProcs) osi_socket rxi_GetUDPSocket(u_short port) { - int binds, code; - register int socketFd = OSI_NULLSOCKET; + int code; + int socketFd = OSI_NULLSOCKET; struct sockaddr_in taddr; char *name = "rxi_GetUDPSocket: "; -#if 0 /* We dont want to have this error - * message, don't bother us */ - if (port >= IPPORT_RESERVED && port < IPPORT_USERRESERVED) { - (osi_Msg "%s*WARNING* port number %d is not a reserved port number." - "Use port numbers above %d\n", - name, port, IPPORT_USERRESERVED); + socketFd = socket(AF_INET, SOCK_DGRAM, 0); + if (socketFd < 0) { + perror("socket"); + (osi_Msg "%sunable to create UDP socket\n", name); + return OSI_NULLSOCKET; } -#endif /* 0 */ - if (port > 0 && port < IPPORT_RESERVED && geteuid() != 0) { - (osi_Msg "%sport number %d is a reserved port number which may only" - " be used by root. Use port numbers above %d\n", - name, port, IPPORT_USERRESERVED); - goto error; +#ifdef SO_BSDCOMPAT + { + int one = 1; + setsockopt (socketFd, SOL_SOCKET, SO_BSDCOMPAT, &one, sizeof(one)); } - socketFd = socket(AF_INET, SOCK_DGRAM, 0); +#endif - /* IOMGR_Select doesn't deal with arbitrarily large select masks */ - if (socketFd > 31) { - (osi_Msg "%ssocket descriptor > 31\n", name); - goto error; - } FD_SET(socketFd, &rx_selectMask); if (socketFd > rx_maxSocketNumber) rx_maxSocketNumber = socketFd; - taddr.sin_addr.s_addr = 0; + memset (&taddr, 0, sizeof(taddr)); taddr.sin_family = AF_INET; - taddr.sin_port = port; -#define MAX_RX_BINDS 10 - for (binds = 0; binds < MAX_RX_BINDS; binds++) { - code = bind(socketFd, (const struct sockaddr *) & taddr, sizeof(taddr)); - if (!code) - break; - sleep(10); - } - if (code) { + taddr.sin_port = port; + + code = bind(socketFd, (const struct sockaddr *) &taddr, sizeof(taddr)); + if (code < 0) { perror("bind"); - (osi_Msg "%sbind failed\n", name); + (osi_Msg "%sunable to bind UDP socket\n", name); goto error; } @@ -316,12 +303,12 @@ rxi_Listener(void) lastPollWorked = 0; /* default is that it didn't find * anything */ - fds = (*rx_select) (FD_SETSIZE, &rfds, 0, 0, tvp); + fds = (*rx_select) (rx_maxSocketNumber + 1, &rfds, 0, 0, tvp); clock_NewTime(); if (fds > 0) { if (doingPoll) lastPollWorked = 1; - for(socket = 0; socket < FD_SETSIZE; ++socket) { + for(socket = 0; socket < rx_maxSocketNumber + 1; ++socket) { if(p == NULL) break; if(FD_ISSET(socket, &rfds) && diff --git a/usr.sbin/afs/src/rx/rxgencon.h b/usr.sbin/afs/src/rx/rxgencon.h new file mode 100644 index 00000000000..19bed98dc2b --- /dev/null +++ b/usr.sbin/afs/src/rx/rxgencon.h @@ -0,0 +1,39 @@ +/* $OpenBSD: rxgencon.h,v 1.1 1999/04/30 01:59:15 art Exp $ */ +/* +**************************************************************************** +* Copyright IBM Corporation 1988, 1989 - All Rights Reserved * +* * +* Permission to use, copy, modify, and distribute this software and its * +* documentation for any purpose and without fee is hereby granted, * +* provided that the above copyright notice appear in all copies and * +* that both that copyright notice and this permission notice appear in * +* supporting documentation, and that the name of IBM not be used in * +* advertising or publicity pertaining to distribution of the software * +* without specific, written prior permission. * +* * +* IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL IBM * +* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY * +* DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER * +* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * +* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * +**************************************************************************** +*/ + +/* $KTH: rxgencon.h,v 1.1 1999/02/05 06:09:06 lha Exp $ */ + +#ifndef _RXGEN_CONSTS_ +#define _RXGEN_CONSTS_ + +/* These are some rxgen-based (really arbitrary) error codes... */ +#define RXGEN_SUCCESS 0 +#define RXGEN_CC_MARSHAL -450 +#define RXGEN_CC_UNMARSHAL -451 +#define RXGEN_SS_MARSHAL -452 +#define RXGEN_SS_UNMARSHAL -453 +#define RXGEN_DECODE -454 +#define RXGEN_OPCODE -455 +#define RXGEN_SS_XDRFREE -456 +#define RXGEN_CC_XDRFREE -457 + +#endif /* _RXGEN_CONSTS_ */ diff --git a/usr.sbin/afs/src/rxdef/cb.xg b/usr.sbin/afs/src/rxdef/cb.xg index 7613145da44..7c02c996a07 100644 --- a/usr.sbin/afs/src/rxdef/cb.xg +++ b/usr.sbin/afs/src/rxdef/cb.xg @@ -6,9 +6,12 @@ package RXAFSCB_ -%#include <atypes.h> -%#include <rx/rx.h> -%#include <rx/rx_null.h> +%#include <config.h> +%#include <roken.h> +%#include <fs_errors.h> + +error-function conv_to_arla_errno + /*%#include "fs.h"*/ /* diff --git a/usr.sbin/afs/src/rxdef/common.h b/usr.sbin/afs/src/rxdef/common.h index 8e817555a57..45f6309c77e 100644 --- a/usr.sbin/afs/src/rxdef/common.h +++ b/usr.sbin/afs/src/rxdef/common.h @@ -1,9 +1,9 @@ -/* $OpenBSD: common.h,v 1.1.1.1 1998/09/14 21:53:18 art Exp $ */ +/* $OpenBSD: common.h,v 1.2 1999/04/30 01:59:15 art Exp $ */ /* * Common defintions for cb.xg and fs.xg */ -/* $KTH: common.h,v 1.8 1998/09/03 18:47:29 lha Exp $ */ +/* $KTH: common.h,v 1.9 1998/10/31 02:29:18 lha Exp $ */ %#ifndef _COMMON_ %#define _COMMON_ @@ -79,7 +79,7 @@ const SS_MODTIME = 0x01 ; const SS_OWNER = 0x02 ; const SS_GROUP = 0x04 ; const SS_MODEBITS = 0x08 ; -const SS_SEGSIZE = 0x0F ; +const SS_SEGSIZE = 0x10 ; struct AFSStoreStatus { unsigned long Mask; diff --git a/usr.sbin/afs/src/rxdef/fs.xg b/usr.sbin/afs/src/rxdef/fs.xg index ee7136042a3..bdf3abd61fa 100644 --- a/usr.sbin/afs/src/rxdef/fs.xg +++ b/usr.sbin/afs/src/rxdef/fs.xg @@ -6,9 +6,11 @@ package RXAFS_ -%#include <atypes.h> -%#include <rx/rx.h> -%#include <rx/rx_null.h> +%#include <config.h> +%#include <roken.h> +%#include <fs_errors.h> + +error-function conv_to_arla_errno #include "common.h" diff --git a/usr.sbin/afs/src/rxdef/pts.xg b/usr.sbin/afs/src/rxdef/pts.xg index 510294a8aa7..90702c1372c 100644 --- a/usr.sbin/afs/src/rxdef/pts.xg +++ b/usr.sbin/afs/src/rxdef/pts.xg @@ -6,10 +6,11 @@ package PR_ -%#include <atypes.h> -%#include <rx/rx.h> -%#include <rx/rx_null.h> +%#include <config.h> +%#include <roken.h> +%#include <fs_errors.h> +error-function conv_to_arla_errno /* * Interface @@ -237,7 +238,7 @@ NameToID(IN namelist *nlist, IDToName(IN idlist *ilist, OUT namelist *nlist) = 505; -NewEntry(IN char name[PR_MAXNAMELEN], +NewEntry(IN string name<PR_MAXNAMELEN>, IN long flag, IN long oid, OUT long *id) = 509; @@ -253,17 +254,17 @@ DumpEntry(IN long pos, OUT struct prdebugentry *entry) = 502; ChangeEntry(IN long id, - IN char name[PR_MAXNAMELEN], + IN string name<PR_MAXNAMELEN>, IN long oid, IN long newid) = 513; -SetFieldesEntry(IN long id, - IN long mask, - IN long flags, - IN long ngroups, - IN long nusers, - IN long spare1, - IN long spare2) = 516; +SetFieldsEntry(IN long id, + IN long mask, + IN long flags, + IN long ngroups, + IN long nusers, + IN long spare1, + IN long spare2) = 516; Delete(IN long id) = 506; diff --git a/usr.sbin/afs/src/rxdef/rx_pkt.xg b/usr.sbin/afs/src/rxdef/rx_pkt.xg new file mode 100644 index 00000000000..ce5743aa1f2 --- /dev/null +++ b/usr.sbin/afs/src/rxdef/rx_pkt.xg @@ -0,0 +1,77 @@ +/* rx_pkt.xg,v 1.3 1994/12/27 03:37:04 assar Exp */ + +/* header of a RPC packet */ + +enum rx_header_type { + HT_DATA = 1, + HT_ACK = 2, + HT_BUSY = 3, + HT_ABORT = 4, + HT_ACKALL = 5, + HT_CHAL = 6, + HT_RESP = 7, + HT_DEBUG = 8 +}; + +/* For flags in header */ + +enum rx_header_flag { + HF_CLIENT_INITIATED = 1, + HF_REQ_ACK = 2, + HF_LAST = 4, + HF_MORE = 8 +}; + +%#define MAXCALLS 4 + +%#define CALL_MASK (MAXCALLS-1) +%#define CONNID_MASK (~(MAXCALLS-1)) + +const RX_HEADER_SIZE=28; + +struct rx_header { + unsigned epoch; + unsigned connid; /* And channel ID */ + unsigned callid; + unsigned seqno; + unsigned serialno; + u_char type; + u_char flags; + u_char status; + u_char secindex; + u_short reserved; /* ??? verifier? */ + u_short serviceid; +/* This should be the other way around according to everything but */ +/* tcpdump */ +}; + +enum rx_ack_reason { + RX_ACK_REQUESTED = 1, + RX_ACK_DUPLICATE = 2, + RX_ACK_OUT_OF_SEQUENCE = 3, + RX_ACK_EXEEDS_WINDOW = 4, + RX_ACK_NOSPACE = 5, + RX_ACK_PING = 6, + RX_ACK_PING_RESPONSE = 7, + RX_ACK_DELAY = 8 +}; + +enum rx_ack_type { + RX_ACK_TYPE_NACK = 0, + RX_ACK_TYPE_ACK = 1 +}; + +const RXMAXACKS=255; + +struct rx_ack_header { + u_short bufferspace; /* # of packet buffers available */ + u_short maxskew; + u_long firstpacket; /* First packet in acks below */ + u_long prevpacket; + u_long serial; /* Packet that prompted this one */ + u_char reason; /* rx_ack_reason */ +/* u_char nacks;*/ /* # of acks */ + u_char acks<u_char>; +/* u_char acks[RXMAXACKS];*/ /* acks (rx_ack_type) */ +}; + diff --git a/usr.sbin/afs/src/rxdef/ubik.xg b/usr.sbin/afs/src/rxdef/ubik.xg index 78eecc0f6d5..13586730873 100644 --- a/usr.sbin/afs/src/rxdef/ubik.xg +++ b/usr.sbin/afs/src/rxdef/ubik.xg @@ -1,14 +1,16 @@ /* -*- C -*- */ /* - * $Id: ubik.xg,v 1.1.1.1 1998/09/14 21:53:18 art Exp $ + * $Id: ubik.xg,v 1.2 1999/04/30 01:59:15 art Exp $ */ package Ubik_ -%#include <atypes.h> -%#include <rx/rx.h> -%#include <rx/rx_null.h> +%#include <config.h> +%#include <roken.h> +%#include <fs_errors.h> + +error-function conv_to_arla_errno /* * Interface @@ -31,14 +33,14 @@ struct ubik_debug { long lowestTime; long syncHost; long syncTime; - struct net_version syncVersion; - struct net_tid syncTid; + net_version syncVersion; + net_tid syncTid; long amSyncSite; long syncSiteUntil; long nServers; long lockedPages; long writeLockedPages; - struct net_version localVersion; + net_version localVersion; long activeWrite; long tidCounter; long anyReadLocks; @@ -54,7 +56,7 @@ struct ubik_sdebug { long lastVoteTime; long lastBeaconSent; long lastVote; - struct net_version remoteVersion; + net_version remoteVersion; long currentDB; long beaconSinceDown; long up; diff --git a/usr.sbin/afs/src/rxdef/vldb.xg b/usr.sbin/afs/src/rxdef/vldb.xg index 23eb49c9dee..bf6d50428cf 100644 --- a/usr.sbin/afs/src/rxdef/vldb.xg +++ b/usr.sbin/afs/src/rxdef/vldb.xg @@ -6,28 +6,24 @@ package VL_ -%#include <atypes.h> -%#include <rx/rx.h> -%#include <rx/rx_null.h> +%#include <config.h> +%#include <roken.h> +%#include <fs_errors.h> + +error-function conv_to_arla_errno /* * Structures and defines for vldb data */ -const VLDB_MAXNAMELEN=65; - -const MAXNSERVERS=8; -const NMAXNSERVERS=13; - -const MAX_NUMBER_OPCODES=30; - -const MAXTYPES=3; - -const MAXSERVERID=30; - -const HASHSIZE=8191; - -const DEFAULTBULK=10000; +const VLDB_MAXNAMELEN = 65; +const MAXNSERVERS = 8; +const NMAXNSERVERS = 13; +const MAX_NUMBER_OPCODES = 30; +const MAXTYPES = 3; +const MAXSERVERID = 30; +const HASHSIZE = 8191; +const DEFAULTBULK = 10000; typedef opaque bulk<DEFAULTBULK>; @@ -35,6 +31,12 @@ typedef opaque bulk<DEFAULTBULK>; typedef struct single_vldbentry *vldblist; #endif +const VLLIST_SERVER = 0x1; +const VLLIST_PARTITION = 0x2; +const VLLIST_VOLUMETYPE = 0x4; +const VLLIST_VOLUMEID = 0x8; +const VLLIST_FLAG = 0x10; + const RWVOL = 0; const ROVOL = 1; const BACKVOL = 2; @@ -48,6 +50,7 @@ const VLF_RWEXISTS = 0x1000; const VLF_ROEXISTS = 0x2000; const VLF_BOEXISTS = 0x4000; const VLF_BACKEXISTS = 0x4000; +const VLF_DFSFILESET = 0x8000; const VL_IDEXIST = 363520; const VL_IO = 363521; @@ -81,7 +84,7 @@ const VL_NOMEM = 363547; struct vldbentry { char name[VLDB_MAXNAMELEN]; - long volumeType; + long volumeType; /* spares */ long nServers; long serverNumber[MAXNSERVERS]; long serverPartition[MAXNSERVERS]; @@ -92,30 +95,67 @@ struct vldbentry { }; struct nvldbentry { - char name[VLDB_MAXNAMELEN]; - long nServers; - long serverNumber[NMAXNSERVERS]; - long serverPartition[NMAXNSERVERS]; - long serverFlags[NMAXNSERVERS]; - u_long volumeId[MAXTYPES]; - long cloneId; - long flags; - long spares1; - long spares2; - long spares3; - long spares4; - long spares5; - long spares6; - long spares7; - long spares8; - long spares9; + char name[VLDB_MAXNAMELEN]; + long nServers; + long serverNumber[NMAXNSERVERS]; + long serverPartition[NMAXNSERVERS]; + long serverFlags[NMAXNSERVERS]; + u_long volumeId[MAXTYPES]; + long cloneId; + long flags; + long spares1; + long spares2; + long spares3; + long spares4; + long spares5; + long spares6; + long spares7; + long spares8; + long spares9; }; +struct vlentry { + u_long volumeId[MAXTYPES]; + long flags; + long LockAfsId; + long LockTimestamp; + long cloneId; + long AssociatedChain; + long nextIdHash[MAXTYPES]; + long nextNameHash; + long spares1[2]; + char name[VLDB_MAXNAMELEN]; + u_char volumeType; + u_char serverNumber[MAXNSERVERS]; + u_char serverPartition[MAXNSERVERS]; + u_char serverFlags[MAXNSERVERS]; + u_char RefCount; + char spares2[1]; +}; + +struct disk_vlentry { + u_long volumeId[MAXTYPES]; + long flags; + long LockAfsId; + long LockTimestamp; + long cloneId; + long AssociatedChain; + long nextIdHash[MAXTYPES]; + long nextNameHash; + long spares1[2]; + char name[VLDB_MAXNAMELEN]; + u_char volumeType; + long serverNumber[MAXNSERVERS]; + u_char serverPartition[MAXNSERVERS]; + u_char serverFlags[MAXNSERVERS]; + u_char RefCount; + char spares2[1]; +}; struct vital_vlheader { long vldbversion; long headersize; - long feePtr; + long freePtr; long eofPtr; long allocs; long frees; @@ -123,6 +163,19 @@ struct vital_vlheader { long totalEntries[MAXTYPES]; }; +typedef long longarray[MAXTYPES]; + +struct vlheader { + struct vital_vlheader vital_header; + u_long IpMappedAddr[MAXSERVERID]; + long VolnameHash[HASHSIZE]; +/* long VolidHashRW[HASHSIZE]; + long VolidHashRO[HASHSIZE]; + long VolidHashBACK[HASHSIZE];*/ + longarray VolidHash[HASHSIZE]; +}; + + struct VldbUpdateEntry { u_long Mask; char name[VLDB_MAXNAMELEN]; @@ -199,6 +252,29 @@ struct vldstats { }; typedef vldbentry bulkentries<>; +typedef nvldbentry nbulkentries<>; +typedef uvldbentry ubulkentries<>; + +struct ListAddrByAttributes { + int32_t mask; + u_int32_t ipaddr; + int32_t index; + int32_t spare; + afsUUID uuid; +}; + +const VLADDR_IPADDR = 0x1; +const VLADDR_INDEX = 0x2; +const VLADDR_UUID = 0x4; + +typedef int32_t bulkaddrs<>; + +struct VL_Callback { + u_int32_t version; + u_int32_t expiration_time; + u_int32_t time; + u_int32_t handle; +}; /* * Interface @@ -257,9 +333,64 @@ GetStats (OUT vldstats *stats, Probe () = 514; -GetEntryByNameN(IN string volumename<VLDB_MAXNAMELEN>, - OUT nvldbentry *entry) = 519; +GetAddrs(IN int32_t handle, + IN int32_t spare, + OUT VL_Callback *spare3, + IN int32_t *nentries, + OUT bulkaddrs *blkaddr) = 515; +ChangeAddrs(IN int32_t old_ip, + IN int32_t new_ip) = 516; /* obsolete */ + +CreateEntryN(IN nvldbentry *newentry) = 517; + +GetEntryByIDN (IN long Volid, + IN long voltype, + OUT nvldbentry *entry) = 518; + +GetEntryByNameN (IN string volumename<VLDB_MAXNAMELEN>, + OUT nvldbentry *entry) = 519; + +ReplaceEntryN (IN long Volid, + IN long voltype, + IN vldbentry *newentry, + IN long ReleaseType) = 520; + +ListEntryN() = 521; + +ListAttributesN (IN VldbListByAttributes *attributes, + OUT long *nentries, + OUT nbulkentries *blkentries) = 522; + +LinkedListN() = 523; + +UpdateEntryByName (IN string volname<VLDB_MAXNAMELEN>, + IN VldbUpdateEntry *UpdateEntry, + IN long ReleaseType) = 524; + +CreateEntryU(IN uvldbentry *newentry) = 525; + +GetEntryByIDU() = 526; GetEntryByNameU (IN string volumename<VLDB_MAXNAMELEN>, OUT struct uvldbentry *entry) = 527; + +ReplaceEntryU() = 528; + +ListEntryU() = 529; + +ListAttributesU (IN VldbListByAttributes *attributes, + OUT long *nentries, + OUT ubulkentries *blkentries) = 530; + +LinkedListU() = 531; + +RegisterAddrs(IN afsUUID *uid, + IN int32_t spare, + IN bulkaddrs *addrs) = 532; + +GetAddrsU(IN ListAddrByAttributes *inaddr, + OUT afsUUID *uuid, + OUT int32_t *uniq, + OUT int32_t *nentries, + OUT bulkaddrs *addrs) = 533; diff --git a/usr.sbin/afs/src/rxdef/volumeserver.xg b/usr.sbin/afs/src/rxdef/volumeserver.xg index 07313e084c0..523ecd6ff4c 100644 --- a/usr.sbin/afs/src/rxdef/volumeserver.xg +++ b/usr.sbin/afs/src/rxdef/volumeserver.xg @@ -2,72 +2,78 @@ * Interface to Volumeserver, * reference /afs/nada.kth.se/misc/reference/programming/afs/shadow/ * - * $Id: volumeserver.xg,v 1.1.1.1 1998/09/14 21:53:18 art Exp $ + * $Id: volumeserver.xg,v 1.2 1999/04/30 01:59:16 art Exp $ */ package VOLSER_ -%#include <atypes.h> -%#include <rx/rx.h> -%#include <rx/rx_null.h> - -const VLDB_MAXSERVER = 80; -const VOLSERVICE_PORT = 7005; -const VOLSERVICE_ID = 4; -const INVALID_BID = 0; -const VOLSER_MAXVOLNAME = 65; -const VOLSER_OLDMAXVOLNAME = 32; -const VOLSER_MAX_REPSITES = 7; -const VNAMESIZE = 32; - - -const VOLCREATEVOLUME = 100; -const VOLDELETEVOLUME = 101; -const VOLRESTORE = 102; -const VOLFORWARD = 103; -const VOLENDTRANS = 104; -const VOLCLONE = 105; -const VOLSETFLAGS = 106; -const VOLGETFLAGS = 107; -const VOLTRANSCREATE = 108; -const VOLDUMP = 109; -const VOLGETNTHVOLUME = 110; -const VOLSETFORWARDING = 111; -const VOLGETNAME = 112; -const VOLGETSTATUS = 113; -const VOLSIGRESTORE = 114; -const VOLLISTPARTITIONS = 115; -const VOLLISTVOLS = 116; -const VOLSETIDTYPES = 117; -const VOLMONITOR = 118; -const VOLDISKPART = 119; -const VOLRECLOSE = 120; -const VOLLISTONEVOL = 121; -const VOLNUKE = 122; -const VOLSETDATE = 123; - -const PARTVALID = 0x01; -const VOK = 0x02; -const VBUSY = 110; - -const VOLSERTRELE_ERROR = 1492325120 ; -const VOLSERNO_OP = 1492325121 ; -const VOLSERREAD_DUMPERROR = 1492325122 ; -const VOLSERDUMPERROR = 1492325123 ; -const VOLSERATTACH_ERROR = 1492325124 ; -const VOLSERILLEGAL_PARTITION = 1492325125 ; -const VOLSERDETACH_ERROR = 1492325126 ; -const VOLSERBAD_ACCESS = 1492325127 ; -const VOLSERVLDB_ERROR = 1492325128 ; -const VOLSERBADNAME = 1492325129 ; -const VOLSERVOLMOVED = 1492325130 ; -const VOLSERBADOP = 1492325131 ; -const VOLSERBADRELEASE = 1492325132 ; -const VOLSERVOLBUSY = 1492325133 ; -const VOLSERNO_MEMORY = 1492325134 ; -const VOLSERNOVOL = 1492325135 ; -const VOLSERMULTIRWVOL = 1492325136 ; -const VOLSERFAILEDOP = 1492325137 ; +%#include <config.h> +%#include <roken.h> +%#include <fs_errors.h> + +error-function conv_to_arla_errno + +const VLDB_MAXSERVER = 80; +const VOLSERVICE_PORT = 7005; +const VOLSERVICE_ID = 4; +const INVALID_BID = 0; +const VOLSER_MAXVOLNAME = 65; +const VOLSER_OLDMAXVOLNAME = 32; +const VOLSER_MAX_REPSITES = 7; +const VNAMESIZE = 32; + +const VOLCREATEVOLUME = 100; +const VOLDELETEVOLUME = 101; +const VOLRESTORE = 102; +const VOLFORWARD = 103; +const VOLENDTRANS = 104; +const VOLCLONE = 105; +const VOLSETFLAGS = 106; +const VOLGETFLAGS = 107; +const VOLTRANSCREATE = 108; +const VOLDUMP = 109; +const VOLGETNTHVOLUME = 110; +const VOLSETFORWARDING = 111; +const VOLGETNAME = 112; +const VOLGETSTATUS = 113; +const VOLSIGNALRESTORE = 114; +const VOLLISTPARTITIONS = 115; +const VOLLISTVOLUMES = 116; +const VOLSETIDTYPES = 117; +const VOLMONITOR = 118; +const VOLPARTITIONINFO = 119; +const VOLRECLONE = 120; +const VOLLISTONEVOLUME = 121; +const VOLNUKEVOLUME = 122; +const VOLSETDATE = 123; +const VOLXLISTVOLUMES = 124; +const VOLXLISTONEVOL = 125; +const VOLSETINFO = 126; +const VOLXLISTPARTITIONS= 127; +const VOLFORWARDMULTIPLE= 128; + +const PARTVALID = 0x01; +const VOK = 0x02; +const VBUSY = 110; + +const VOLSERTRELE_ERROR = 1492325120; +const VOLSERNO_OP = 1492325121; +const VOLSERREAD_DUMPERROR = 1492325122; +const VOLSERDUMPERROR = 1492325123; +const VOLSERATTACH_ERROR = 1492325124; +const VOLSERILLEGAL_PARTITION = 1492325125; +const VOLSERDETACH_ERROR = 1492325126; +const VOLSERBAD_ACCESS = 1492325127; +const VOLSERVLDB_ERROR = 1492325128; +const VOLSERBADNAME = 1492325129; +const VOLSERVOLMOVED = 1492325130; +const VOLSERBADOP = 1492325131; +const VOLSERBADRELEASE = 1492325132; +const VOLSERVOLBUSY = 1492325133; +const VOLSERNO_MEMORY = 1492325134; +const VOLSERNOVOL = 1492325135; +const VOLSERMULTIRWVOL = 1492325136; +const VOLSERFAILEDOP = 1492325137; struct volser_trans { volser_trans *next; @@ -153,12 +159,52 @@ struct volintInfo { long spare3; }; +struct xvolintInfo { + char name[VNAMESIZE]; + long volid; + long type; + long backupID; + long parentID; + long cloneID; + long status; + long copyDate; + char inUse; + long creationDate; + long accessDate; + long updateDate; + long backupDate; + long dayUse; + long filecount; + long maxquota; + long size; + int32_t stat_reads[4]; + int32_t stat_writes[4]; + int32_t stat_fileSameAuthor[6]; + int32_t stat_fileDiffAuthor[6]; + int32_t stat_dirSameAuthor[6]; + int32_t stat_dirDiffAuthor[6]; +}; + +/* + * same site total, same site authenticated + * diff site total, diff site authenticated + */ + +/* + * 0-60 s + * 1-10 min + * 10-60 min + * 1-24 hour + * 1-7 days + * >7 days + */ + struct transDebugInfo { long tid; long time; long creationTime; long returnCode; - long volid ; + long volid; long partition; short iflags; char vflags; @@ -172,7 +218,7 @@ struct transDebugInfo { }; struct pIDs { - long partIds[26]; + long partIds[26]; /* -1 if none */ }; struct diskPartition { @@ -193,47 +239,124 @@ struct restoreCookie { typedef transDebugInfo transDebugEntries<>; typedef volintInfo volEntries<>; +typedef xvolintInfo xvolEntries<>; +typedef int32_t part_entries<>; +typedef int32_t multi_results<>; +struct replica { + int32_t trans_id; + struct destServer destserver; +}; + +typedef replica replicas<>; AFSVolCreateVolume(IN long partition, - IN char *name, - IN long type, - IN long parent, - INOUT long *volid, - OUT long *trans) = 100 ; + IN string name, + IN long type, + IN long parent, + INOUT long *volid, + OUT long *trans) = VOLCREATEVOLUME; + +AFSVolDeleteVolume(IN long trans) = VOLDELETEVOLUME; + +AFSVolNukeVolume(IN long partID, + IN long volID) = VOLNUKEVOLUME; + +AFSVolDump(IN long fromTrans, + IN long fromDate) split = VOLDUMP; + +AFSVolSignalRestore(IN char *name, + IN int type, + IN long pid, + IN long cloneid) = VOLSIGNALRESTORE; + +AFSVolRestore(IN long toTrans, + IN long flags, + IN restoreCookie *cookie) split = VOLRESTORE; + +AFSVolForward(IN int32_t fromTrans, + IN int32_t fromData, + IN struct destServer *destination, + IN long destTrans, + IN struct restoreCookie *cookie) = VOLFORWARD; + +AFSVolClone(IN long trans, + IN long purgeVol, + IN long newType, + IN char *newName, + INOUT long *newVol) = VOLCLONE; + +AFSVolReClone(IN long tid, + IN long cloneID) = VOLRECLONE; + +AFSVolSetForwarding(IN long tid, + IN long newsite) = VOLSETFORWARDING; AFSVolTransCreate(IN long volume, - IN long partition, - IN long flags, - OUT long *trans) = 108 ; + IN long partition, + IN long flags, + OUT long *trans) = VOLTRANSCREATE; AFSVolEndTrans(IN long trans, - OUT long *rcode) = 104 ; + OUT long *rcode) = VOLENDTRANS; AFSVolGetFlags(IN long trans, - OUT long *flags) = 107 ; + OUT long *flags) = VOLGETFLAGS; AFSVolSetFlags(IN long trans, - IN long flags) = 106 ; + IN long flags) = VOLSETFLAGS; AFSVolGetName(IN long tid, - OUT string tname<256>) = 112 ; + OUT string tname<256>) = VOLGETNAME; + +AFSVolGetStatus(IN long tid, + OUT volser_status *status) = VOLGETSTATUS; + +AFSVolSetIdsTypes(IN long tId, + IN char *name, + IN long type, + IN long pId, + IN long cloneId, + IN long backupId) = VOLSETIDTYPES; AFSVolSetDate(IN long tid, - IN long newDate) = 123 ; + IN long newDate) = VOLSETDATE; -AFSVolListPartitions(OUT struct pIDs *partIDs) = 115 ; +AFSVolListPartitions(OUT struct pIDs *partIDs) = VOLLISTPARTITIONS; AFSVolPartitionInfo(IN string name<>, - OUT struct diskPartition *partition) = 119 ; + OUT struct diskPartition *partition) = VOLPARTITIONINFO; AFSVolListVolumes(IN long partID, IN long flags, - OUT struct volEntries *resultEntries) = 116 ; + OUT struct volEntries *resultEntries) = VOLLISTVOLUMES; AFSVolListOneVolume(IN long partID, - IN long volid, - OUT struct volEntries *resultEntries) = 121 ; + IN long volid, + OUT struct volEntries *resultEntries) = VOLLISTONEVOLUME; + +AFSVolGetNthVolume(IN long index, + OUT long *volume, + OUT long *partition) = VOLGETNTHVOLUME; -AFSVolMonitor(OUT transDebugEntries *result) = 118 ; +AFSVolMonitor(OUT transDebugEntries *result) = VOLMONITOR; +AFSVolXListVolumes(IN long partID, + IN long flags, + OUT struct xvolEntries *resultEntries) = VOLXLISTVOLUMES; + +AFSVolXListOneVolume(IN long partID, + IN long volid, + OUT struct xvolEntries *resultEntries) = VOLXLISTONEVOL; + +AFSVolSetInfo(IN long transid, + IN volintInfo *volinfo) = VOLSETINFO; + +AFSVolXListPartitions(OUT part_entries *ent) = VOLXLISTPARTITIONS; + +AFSVolForwardMultiple(IN int32_t fromTrans, + IN int32_t fromData, + IN replicas *destinations, + IN long spare0, + IN struct restoreCookie *cookie, + IN multi_results *results) = VOLFORWARDMULTIPLE; diff --git a/usr.sbin/afs/src/rxkad/rxk_clnt.c b/usr.sbin/afs/src/rxkad/rxk_clnt.c index c8d536145b5..bba65f80244 100644 --- a/usr.sbin/afs/src/rxkad/rxk_clnt.c +++ b/usr.sbin/afs/src/rxkad/rxk_clnt.c @@ -1,6 +1,6 @@ -/* $OpenBSD: rxk_clnt.c,v 1.1.1.1 1998/09/14 21:53:19 art Exp $ */ +/* $OpenBSD: rxk_clnt.c,v 1.2 1999/04/30 01:59:16 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,7 +39,7 @@ #include "rxkad_locl.h" -RCSID("$KTH: rxk_clnt.c,v 1.4 1998/02/22 21:12:25 lha Exp $"); +RCSID("$KTH: rxk_clnt.c,v 1.5 1999/03/12 17:09:44 assar Exp $"); /* This code also links into the kernel so we need to use osi_Alloc() * to avoid calling malloc(). Similar trick with memcpy() */ @@ -163,8 +163,9 @@ client_GetResponse(const struct rx_securityClass *obj_, if (rx_SlowReadPacket(pkt, 0, sizeof(c), &c) != sizeof(c)) return RXKADPACKETSHORT; - if (ntohl(c.version) != RXKAD_VERSION) - return RXKADINCONSISTENCY; + if (ntohl(c.version) < RXKAD_VERSION) + return RXKADINCONSISTENCY; /* Don't know how to make vers 1 response. */ + /* Always make a vers 2 response. */ if (ntohl(c.min_level) > obj->level) return RXKADLEVELFAIL; diff --git a/usr.sbin/afs/src/rxkad/rxk_serv.c b/usr.sbin/afs/src/rxkad/rxk_serv.c index 443c168ec43..af1b7b037c3 100644 --- a/usr.sbin/afs/src/rxkad/rxk_serv.c +++ b/usr.sbin/afs/src/rxkad/rxk_serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rxk_serv.c,v 1.1.1.1 1998/09/14 21:53:20 art Exp $ */ +/* $OpenBSD: rxk_serv.c,v 1.2 1999/04/30 01:59:16 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -43,7 +43,7 @@ #include <krb5.h> #endif -RCSID("$KTH: rxk_serv.c,v 1.4 1998/02/22 21:12:27 lha Exp $"); +RCSID("$KTH: rxk_serv.c,v 1.5 1999/04/18 22:21:43 map Exp $"); /* Security object specific server data */ typedef struct rxkad_serv_class { @@ -330,7 +330,8 @@ decode_krb4_ticket(rxkad_serv_class *obj, { time_t end = krb_life_to_time(start, klife); time_t now = time(0); - start -= CLOCK_SKEW; + if (start > CLOCK_SKEW) /* Transarc sends 0 as start if localauth */ + start -= CLOCK_SKEW; if (now < start) return RXKADNOAUTH; else if (now > end) diff --git a/usr.sbin/afs/src/rxkad/rxkad_locl.h b/usr.sbin/afs/src/rxkad/rxkad_locl.h index e4f3e060544..bf777888b8e 100644 --- a/usr.sbin/afs/src/rxkad/rxkad_locl.h +++ b/usr.sbin/afs/src/rxkad/rxkad_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rxkad_locl.h,v 1.1.1.1 1998/09/14 21:53:19 art Exp $ */ +/* $OpenBSD: rxkad_locl.h,v 1.2 1999/04/30 01:59:16 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,12 +37,12 @@ * SUCH DAMAGE. */ -/* @(#)$KTH: rxkad_locl.h,v 1.8 1998/03/28 16:35:49 lha Exp $ */ +/* @(#)$KTH: rxkad_locl.h,v 1.9 1998/10/23 02:15:47 lha Exp $ */ #ifndef __RXKAD_LOCL_H #define __RXKAD_LOCL_H -/* $KTH: rxkad_locl.h,v 1.8 1998/03/28 16:35:49 lha Exp $ */ +/* $KTH: rxkad_locl.h,v 1.9 1998/10/23 02:15:47 lha Exp $ */ #ifdef HAVE_CONFIG_H #include <config.h> @@ -61,13 +61,17 @@ #endif #ifdef NDEBUG +#ifndef assert #define assert(e) ((void)0) +#endif #else +#ifndef assert #define assert(e) ((e) ? (void)0 : (void)osi_Panic("assert(%s) failed: file %s, line %d\n", #e, __FILE__, __LINE__, #e)) #endif +#endif #include <des.h> -#include <kerberosIV/krb.h> +#include <krb.h> #undef RCSID #include <rx/rx.h> diff --git a/usr.sbin/afs/src/util/date_rfc822.c b/usr.sbin/afs/src/util/date_rfc822.c index 5b1133a7ed3..99b56f37efd 100644 --- a/usr.sbin/afs/src/util/date_rfc822.c +++ b/usr.sbin/afs/src/util/date_rfc822.c @@ -1,6 +1,6 @@ -/* $OpenBSD: date_rfc822.c,v 1.1.1.1 1998/09/14 21:53:21 art Exp $ */ +/* $OpenBSD: date_rfc822.c,v 1.2 1999/04/30 01:59:16 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -38,12 +38,12 @@ */ /* - * $KTH: date_rfc822.c,v 1.5 1998/02/11 03:43:32 art Exp $ + * $KTH: date_rfc822.c,v 1.6 1999/01/03 01:49:21 assar Exp $ */ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: date_rfc822.c,v 1.5 1998/02/11 03:43:32 art Exp $"); +RCSID("$KTH: date_rfc822.c,v 1.6 1999/01/03 01:49:21 assar Exp $"); #endif #include <roken.h> @@ -51,8 +51,9 @@ RCSID("$KTH: date_rfc822.c,v 1.5 1998/02/11 03:43:32 art Exp $"); #include "date_rfc822.h" /* - * Return current date in RFC822-format with timezone GMT. - * Memory is allocated with strdup. + * Return current date in RFC822-format (actually not 822, but + * according to section 5.2.14 of rfc1123) with timezone GMT. Memory + * is allocated with strdup. */ char * @@ -60,21 +61,6 @@ date_time2rfc822 (time_t t) { char tmp [80]; - strftime (tmp, sizeof (tmp), "%A, %d-%h-%y %H:%M:%S %Z", gmtime (&t)); + strftime (tmp, sizeof (tmp), "%A, %d-%h-%Y %H:%M:%S %Z", gmtime (&t)); return strdup (tmp); } - -#if 0 /* XXX */ -/* - * Convert from RFC 822 representation of date into a time_t. - */ - -time_t -date_rfc8222time (char *s) -{ - struct tm tm; - - strptime (s, "%d-%h-%y %H:%M:%S ", &tm); - return timegm (&tm); -} -#endif diff --git a/usr.sbin/afs/src/util/timeprio.c b/usr.sbin/afs/src/util/eefile.c index 4e4441bad11..e979e1bd7b1 100644 --- a/usr.sbin/afs/src/util/timeprio.c +++ b/usr.sbin/afs/src/util/eefile.c @@ -1,6 +1,6 @@ -/* $OpenBSD: timeprio.c,v 1.1.1.1 1998/09/14 21:53:24 art Exp $ */ +/* $OpenBSD: eefile.c,v 1.1 1999/04/30 01:59:16 art Exp $ */ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,78 +37,65 @@ * SUCH DAMAGE. */ +/* + * + */ + #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: timeprio.c,v 1.1 1998/07/07 15:57:11 lha Exp $"); +RCSID("$KTH: eefile.c,v 1.2 1999/03/06 18:02:21 lha Exp $"); #endif -#include <stdlib.h> -#include "bool.h" -#include "timeprio.h" - +#include <stdio.h> +#include <roken.h> +#include <err.h> +#include "eefile.h" -static int -timeprio_cmp(void *a1, void *b1) +void +eefopen (const char *name, const char *mode, fileblob *f) { - Tpel *a = a1, *b = b1; - - return a->time > b->time; -} + int streamfd; + asprintf (&f->curname, "%sXXXXXX", name); + if (f->curname == NULL) + err (1, "malloc"); -Timeprio * -timeprionew(unsigned size) -{ - return (Timeprio *) prionew(size, timeprio_cmp); + streamfd = mkstemp(f->curname); + f->stream = fdopen (streamfd, mode); + if (f->stream == NULL) + err (1, "open %s mode %s", f->curname, mode); + f->newname = estrdup(name); } void -timepriofree(Timeprio *prio) +eefclose (fileblob *f) { - priofree(prio); + if (fclose (f->stream)) + err (1, "close %s", f->curname); + if (rename(f->curname, f->newname)) + err (1, "rename %s, %s", f->curname, f->newname); + free(f->curname); + free(f->newname); } -int -timeprioinsert(Timeprio *prio, time_t time, void *data) +size_t +eefread (void *ptr, size_t size, size_t nitems, fileblob *f) { - Tpel *el = malloc(sizeof(Tpel)); - if (!el) - return -1; + size_t res; - el->time = time; - el->data = data; - if (prioinsert(prio, el)) { - free(el); - el = NULL; - } - return el ? 0 : -1; + res = fread (ptr, size, nitems, f->stream); + if (res == 0) + err (1, "read %s", f->curname); + return res; } -void * -timepriohead(Timeprio *prio) +size_t +eefwrite (const void *ptr, size_t size, size_t nitems, fileblob *f) { - Tpel *el = priohead(prio); - - return el->data; -} - -void -timeprioremove(Timeprio *prio) -{ - void *el; + size_t res; - if (timeprioemptyp((Prio *)prio)) - return; - - el = priohead(prio); - if (el) free (el); - - prioremove((Prio *)prio); -} - -Bool -timeprioemptyp(Timeprio *prio) -{ - return prioemptyp(prio); + res = fwrite (ptr, size, nitems, f->stream); + if (res == 0) + err (1, "write %s", f->curname); + return res; } - diff --git a/usr.sbin/afs/src/util/mem.c b/usr.sbin/afs/src/util/eefile.h index c5a6630edca..532857eefa2 100644 --- a/usr.sbin/afs/src/util/mem.c +++ b/usr.sbin/afs/src/util/eefile.h @@ -1,6 +1,6 @@ -/* $OpenBSD: mem.c,v 1.1.1.1 1998/09/14 21:53:24 art Exp $ */ +/* $OpenBSD: eefile.h,v 1.1 1999/04/30 01:59:16 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,53 +37,25 @@ * SUCH DAMAGE. */ -/* - * - */ +/* $KTH: eefile.h,v 1.1 1999/02/27 11:02:39 assar Exp $ */ -#ifdef HAVE_CONFIG_H -#include <config.h> -RCSID("$KTH: mem.c,v 1.3 1998/02/22 11:22:17 assar Exp $"); -#endif +#ifndef _EEFILE_ +#define _EEFILE_ #include <stdio.h> -#include "mem.h" - -/* - * Like malloc, but write an error message if not succesful. - */ - -void * -emalloc(size_t sz) -{ - void *tmp = malloc(sz); - - if( tmp ) - return tmp; - else { - fprintf(stderr, "malloc for %u bytes failed\n", sz); - exit(1); - } -} - -/* - * Like realloc, but write an error message if not succesful. - */ - -void * -erealloc (void *ptr, size_t sz) -{ - void *tmp; - - if (ptr) - tmp = realloc (ptr, sz); - else - tmp = malloc (sz); - - if (tmp) - return tmp; - else { - fprintf (stderr, "realloc for %u bytes failed\n", sz); - exit (1); - } -} +#include <stdlib.h> + +struct _fileblob { + FILE *stream; + char *curname; + char *newname; +}; + +typedef struct _fileblob fileblob; +void eefopen(const char *name, const char *mode, fileblob *f); +void eefclose(fileblob *); +size_t eefread (void *ptr, size_t size, size_t nitems, fileblob *stream); +size_t eefwrite (const void *ptr, size_t size, size_t nitems, + fileblob *stream); + +#endif /* _EEFILE_ */ diff --git a/usr.sbin/afs/src/util/efile.c b/usr.sbin/afs/src/util/efile.c index 21546752acc..4f8331182e2 100644 --- a/usr.sbin/afs/src/util/efile.c +++ b/usr.sbin/afs/src/util/efile.c @@ -1,6 +1,6 @@ -/* $OpenBSD: efile.c,v 1.1.1.1 1998/09/14 21:53:22 art Exp $ */ +/* $OpenBSD: efile.c,v 1.2 1999/04/30 01:59:16 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -43,34 +43,28 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: efile.c,v 1.4 1998/02/22 11:22:14 assar Exp $"); +RCSID("$KTH: efile.c,v 1.5 1999/02/27 11:04:50 assar Exp $"); #endif #include <stdio.h> #include "efile.h" FILE * -efopen (char *name, char *mode) +efopen (const char *name, const char *mode) { FILE *tmp; tmp = fopen (name, mode); - if (tmp == NULL) { - fprintf (stderr, "Could not open file %s in mode %s\n", - name, mode); - perror ("open"); - exit (1); - } + if (tmp == NULL) + err (1, "open %s mode %s", name, mode); return tmp; } void efclose (FILE *f) { - if (fclose (f)) { - fprintf (stderr, "Problems closing a file\n"); - perror ("close"); - } + if (fclose (f)) + err (1, "close"); } size_t @@ -79,11 +73,8 @@ efread (void *ptr, size_t size, size_t nitems, FILE *stream) size_t res; res = fread (ptr, size, nitems, stream); - if (res == 0) { - fprintf (stderr, "Error reading\n"); - perror ("read"); - exit (1); - } + if (res == 0) + err (1, "read"); return res; } @@ -93,10 +84,7 @@ efwrite (const void *ptr, size_t size, size_t nitems, FILE *stream) size_t res; res = fwrite (ptr, size, nitems, stream); - if (res == 0) { - fprintf (stderr, "Error writing\n"); - perror ("read"); - exit (1); - } + if (res == 0) + err (1, "write"); return res; } diff --git a/usr.sbin/afs/src/util/efile.h b/usr.sbin/afs/src/util/efile.h index 0bb72a5d0d5..88f363effc5 100644 --- a/usr.sbin/afs/src/util/efile.h +++ b/usr.sbin/afs/src/util/efile.h @@ -1,6 +1,6 @@ -/* $OpenBSD: efile.h,v 1.1.1.1 1998/09/14 21:53:22 art Exp $ */ +/* $OpenBSD: efile.h,v 1.2 1999/04/30 01:59:16 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ * SUCH DAMAGE. */ -/* $KTH: efile.h,v 1.2 1997/11/09 23:48:47 assar Exp $ */ +/* $KTH: efile.h,v 1.3 1999/02/27 11:04:50 assar Exp $ */ #ifndef _EFILE_ #define _EFILE_ @@ -45,7 +45,7 @@ #include <stdio.h> #include <stdlib.h> -FILE *efopen(char *name, char *mode); +FILE *efopen(const char *name, const char *mode); void efclose(FILE *); size_t efread (void *ptr, size_t size, size_t nitems, FILE *stream); size_t efwrite (const void *ptr, size_t size, size_t nitems, FILE *stream); diff --git a/usr.sbin/afs/src/util/fnameutil.c b/usr.sbin/afs/src/util/fnameutil.c index 80dd238fff0..1c7e2fa3db2 100644 --- a/usr.sbin/afs/src/util/fnameutil.c +++ b/usr.sbin/afs/src/util/fnameutil.c @@ -1,6 +1,6 @@ -/* $OpenBSD: fnameutil.c,v 1.1.1.1 1998/09/14 21:53:21 art Exp $ */ +/* $OpenBSD: fnameutil.c,v 1.2 1999/04/30 01:59:17 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -43,12 +43,12 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: fnameutil.c,v 1.6 1998/03/13 04:36:32 assar Exp $"); +RCSID("$KTH: fnameutil.c,v 1.7 1999/02/13 04:41:26 assar Exp $"); #endif #include <string.h> #include <ctype.h> -#include <mem.h> +#include <roken.h> #include "fnameutil.h" /* diff --git a/usr.sbin/afs/src/util/hash.c b/usr.sbin/afs/src/util/hash.c index 59290bbab0b..3026b8c2b04 100644 --- a/usr.sbin/afs/src/util/hash.c +++ b/usr.sbin/afs/src/util/hash.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hash.c,v 1.1.1.1 1998/09/14 21:53:23 art Exp $ */ +/* $OpenBSD: hash.c,v 1.2 1999/04/30 01:59:17 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -43,7 +43,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: hash.c,v 1.10 1998/03/18 19:30:03 art Exp $"); +RCSID("$KTH: hash.c,v 1.12 1998/12/02 00:48:38 assar Exp $"); #endif #include <assert.h> @@ -113,17 +113,19 @@ hashtabsearch(Hashtab * htab, void *ptr) /* if already there, set new value */ /* !NULL if succesful */ -void * -hashtabadd(Hashtab * htab, void *ptr) +static void * +_add(Hashtab * htab, void *ptr, Bool unique) { Hashentry *h = _search(htab, ptr); Hashentry **tabptr; assert(htab && ptr); - if (h) + if (h) { + if (unique) + return NULL; free((void *) h->ptr); - else { + } else { h = (Hashentry *) malloc(sizeof(Hashentry)); if (h == NULL) { return NULL; @@ -139,6 +141,18 @@ hashtabadd(Hashtab * htab, void *ptr) return h; } +void * +hashtabaddreplace (Hashtab *htab, void *ptr) +{ + return _add (htab, ptr, FALSE); +} + +void * +hashtabadd (Hashtab *htab, void *ptr) +{ + return _add (htab, ptr, TRUE); +} + /* delete element with key key. Iff freep, free Hashentry->ptr */ int diff --git a/usr.sbin/afs/src/util/hash.h b/usr.sbin/afs/src/util/hash.h index 9bad44737d9..818a69e583b 100644 --- a/usr.sbin/afs/src/util/hash.h +++ b/usr.sbin/afs/src/util/hash.h @@ -1,6 +1,6 @@ -/* $OpenBSD: hash.h,v 1.1.1.1 1998/09/14 21:53:23 art Exp $ */ +/* $OpenBSD: hash.h,v 1.2 1999/04/30 01:59:17 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -41,7 +41,7 @@ * hash.h. Header file for hash table functions */ -/* $KTH: hash.h,v 1.4 1997/11/27 18:45:59 mho Exp $ */ +/* $KTH: hash.h,v 1.5 1998/12/01 23:09:22 assar Exp $ */ #include <bool.h> @@ -74,8 +74,11 @@ void *hashtabsearch(Hashtab *htab, /* The hash table */ void *ptr); /* The key */ -void *hashtabadd(Hashtab *htab, /* The hash table */ - void *ptr); /* The element */ +void *hashtabaddreplace(Hashtab *htab, /* The hash table */ + void *ptr); /* The element */ + +void *hashtabadd(Hashtab *htab, + void *ptr); int _hashtabdel(Hashtab *htab, /* The table */ void *ptr, /* Key */ diff --git a/usr.sbin/afs/src/util/heap.c b/usr.sbin/afs/src/util/heap.c new file mode 100644 index 00000000000..959c0c42ed1 --- /dev/null +++ b/usr.sbin/afs/src/util/heap.c @@ -0,0 +1,295 @@ +/* $OpenBSD: heap.c,v 1.1 1999/04/30 01:59:17 art Exp $ */ +/* + * Copyright (c) 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Heap + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +RCSID("$KTH: heap.c,v 1.1 1998/12/28 00:14:40 assar Exp $"); +#endif + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include "heap.h" + +/* + * Allocate a new heap of size `sz' with compare function `cmp'. + */ + +Heap * +heap_new (unsigned sz, heap_cmp_fn cmp) +{ + Heap *ret; + int i; + + ret = malloc (sizeof(*ret)); + if (ret == NULL) + return ret; + + ret->cmp = cmp; + ret->max_sz = sz; + ret->sz = 0; + ret->data = malloc (sz * sizeof(*ret->data)); + if (ret->data == NULL) { + free (ret); + return NULL; + } + for (i = 0; i < sz; ++i) { + ret->data[i].data = NULL; + ret->data[i].ptr = NULL; + } + return ret; +} + +static inline unsigned +parent (unsigned n) +{ + return (n + 1) / 2 - 1; +} + +static inline unsigned +left_child (unsigned n) +{ + return 2 * n + 1; +} + +static inline unsigned +right_child (unsigned n) +{ + return 2 * n + 2; +} + +static heap_ptr dummy; + +/* + * + */ + +static void +assign (Heap *h, unsigned n, heap_element el) +{ + h->data[n] = el; + *(h->data[n].ptr) = n; +} + +/* + * + */ + +static void +upheap (Heap *h, unsigned n) +{ + heap_element v = h->data[n]; + + while (n > 0 && (*h->cmp)(h->data[parent(n)].data, v.data) > 0) { + assign (h, n, h->data[parent(n)]); + n = parent(n); + } + assign (h, n, v); +} + +/* + * + */ + +static void +downheap (Heap *h, unsigned n) +{ + heap_element v = h->data[n]; + + while (n < h->sz / 2) { + int cmp1, cmp2; + unsigned new_n; + + assert (left_child(n) < h->sz); + + new_n = left_child(n); + + cmp1 = (*h->cmp)(v.data, h->data[new_n].data); + + if (right_child(n) < h->sz) { + cmp2 = (*h->cmp)(v.data, h->data[right_child(n)].data); + if (cmp2 > cmp1) { + cmp1 = cmp2; + new_n = right_child(n); + } + } + + if (cmp1 > 0) { + assign (h, n, h->data[new_n]); + n = new_n; + } else { + break; + } + } + assign (h, n, v); +} + +/* + * Insert a new element `data' into `h'. + * Return 0 if succesful or else -1. + */ + +int +heap_insert (Heap *h, const void *data, heap_ptr *ptr) +{ + assert (data != NULL); + + if (h->sz == h->max_sz) { + unsigned new_sz = h->max_sz * 2; + heap_element *tmp; + + tmp = realloc (h->data, new_sz * sizeof(*h->data)); + if (tmp == NULL) + return -1; + h->max_sz = new_sz; + h->data = tmp; + } + if (ptr == NULL) + ptr = &dummy; + + h->data[h->sz].data = data; + h->data[h->sz].ptr = ptr; + upheap (h, h->sz); + ++h->sz; + return 0; +} + +/* + * Return the head of the heap `h' (or NULL if it's empty). + */ + +const void * +heap_head (Heap *h) +{ + if (h->sz == 0) + return NULL; + else + return h->data[0].data; +} + +/* + * Remove element `n' from the heap `h' + */ + +static void +remove_this (Heap *h, unsigned n) +{ + assert (n < h->sz); + + --h->sz; + h->data[n] = h->data[h->sz]; + h->data[h->sz].data = NULL; + h->data[h->sz].ptr = NULL; + if (n != h->sz) { + downheap (h, n); + upheap (h, n); + } +} + +/* + * Remove the head from the heap `h'. + */ + +void +heap_remove_head (Heap *h) +{ + remove_this (h, 0); +} + +/* + * Remove this very element from the heap `h'. + * Return 0 if succesful and -1 if it couldn't be found. + */ + +int +heap_remove (Heap *h, heap_ptr ptr) +{ + if (h->sz == 0) + return -1; + + remove_this (h, ptr); + return 0; +} + +/* + * Delete the heap `h' + */ + +void +heap_delete (Heap *h) +{ + free (h->data); + free (h); +} + +/* + * + */ + +static Bool +do_verify (Heap *h, unsigned n) +{ + if (left_child(n) < h->sz) { + if((*h->cmp)(h->data[n].data, h->data[left_child(n)].data) > 0) + return FALSE; + if (!do_verify (h, left_child(n))) + return FALSE; + } + if (right_child(n) < h->sz) { + if((*h->cmp)(h->data[n].data, h->data[right_child(n)].data) > 0) + return FALSE; + if (!do_verify (h, right_child(n))) + return FALSE; + } + return TRUE; +} + +/* + * Verify that `h' is really a heap. + */ + +Bool +heap_verify (Heap *h) +{ + return do_verify (h, 0); +} diff --git a/usr.sbin/afs/src/util/heap.h b/usr.sbin/afs/src/util/heap.h new file mode 100644 index 00000000000..d13bb1a30d1 --- /dev/null +++ b/usr.sbin/afs/src/util/heap.h @@ -0,0 +1,91 @@ +/* $OpenBSD: heap.h,v 1.1 1999/04/30 01:59:17 art Exp $ */ +/* + * Copyright (c) 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * an abstract heap implementation + */ + +/* $KTH: heap.h,v 1.1 1998/12/28 00:14:41 assar Exp $ */ + +#ifndef _HEAP_ +#define _HEAP_ + +#include "bool.h" + +typedef int (*heap_cmp_fn)(const void *, const void *); + +typedef unsigned heap_ptr; + +struct heap_element { + const void *data; + heap_ptr *ptr; +}; + +typedef struct heap_element heap_element; + +struct heap { + heap_cmp_fn cmp; + unsigned max_sz; + unsigned sz; + heap_element *data; +}; + +typedef struct heap Heap; + +Heap *heap_new (unsigned sz, heap_cmp_fn cmp); + +int +heap_insert (Heap *h, const void *data, heap_ptr *ptr); + +const void * +heap_head (Heap *h); + +void +heap_remove_head (Heap *h); + +int +heap_remove (Heap *h, heap_ptr ptr); + +void +heap_delete (Heap *h); + +Bool +heap_verify (Heap *h); + +#endif /* _HEAP_ */ diff --git a/usr.sbin/afs/src/util/heaptest.c b/usr.sbin/afs/src/util/heaptest.c new file mode 100644 index 00000000000..ff0e5164eb3 --- /dev/null +++ b/usr.sbin/afs/src/util/heaptest.c @@ -0,0 +1,120 @@ +/* $OpenBSD: heaptest.c,v 1.1 1999/04/30 01:59:17 art Exp $ */ +/* + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +RCSID("$KTH: heaptest.c,v 1.2 1999/02/13 05:03:25 assar Exp $"); + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <err.h> +#include "heap.h" + +struct foo { + int i; + heap_ptr hptr; +}; + +static int +cmp(const void *v1, const void *v2) +{ + const struct foo *foo1 = (const struct foo *)v1; + const struct foo *foo2 = (const struct foo *)v2; + + return foo1->i - foo2->i; +} + +static int +testit (unsigned n) +{ + struct foo *foos, *bars; + Heap *h1, *h2; + int i; + + foos = malloc (n * sizeof(*foos)); + bars = malloc (n * sizeof(*bars)); + assert (foos != NULL && bars != NULL); + h1 = heap_new (n, cmp); + h2 = heap_new (n, cmp); + assert (h1 != NULL && h2 != NULL); + for (i = 0; i < n; ++i) { + foos[i].i = bars[i].i = rand(); + heap_insert (h1, (void *)&foos[i], NULL); + heap_insert (h2, (void *)&foos[i], &foos[i].hptr); + if (!heap_verify(h1) || !heap_verify(h2)) + abort (); + } + for (i = 0; i < n; ++i) { + heap_remove (h2, foos[i].hptr); + if (!heap_verify(h2)) + abort (); + } + qsort (bars, n, sizeof(*bars), cmp); + for (i = 0; i < n; ++i) { + struct foo *f = (struct foo *)heap_head (h1); + + if (bars[i].i != f->i) + abort (); + heap_remove_head (h1); + if (!heap_verify(h1)) + abort (); + } + heap_delete (h1); + heap_delete (h2); + free (foos); + free (bars); + return 0; +} + +int +main(int argc, char **argv) +{ + int i, n; + + if (argc != 2) + errx (1, "argc != 2"); + + n = atoi (argv[1]); + for (i = 0; i < n; ++i) + testit (rand () % 1000); + return 0; +} diff --git a/usr.sbin/afs/src/util/ip.c b/usr.sbin/afs/src/util/ip.c index 6955038ef28..20097f489ee 100644 --- a/usr.sbin/afs/src/util/ip.c +++ b/usr.sbin/afs/src/util/ip.c @@ -1,6 +1,6 @@ -/* $OpenBSD: ip.c,v 1.1.1.1 1998/09/14 21:53:23 art Exp $ */ +/* $OpenBSD: ip.c,v 1.2 1999/04/30 01:59:17 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,7 +39,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: ip.c,v 1.5 1998/03/13 04:38:09 assar Exp $"); +RCSID("$KTH: ip.c,v 1.6 1999/01/03 01:54:45 assar Exp $"); #endif #include <stdio.h> @@ -75,7 +75,8 @@ ipgetaddr (const char *addr, struct in_addr *ret) * If no luck with dns, return dot-separated instead. */ -char *ipgetname (struct in_addr *addr) +const char * +ipgetname (struct in_addr *addr) { struct hostent *hostent; diff --git a/usr.sbin/afs/src/util/ip.h b/usr.sbin/afs/src/util/ip.h index 8429f3cf2e2..6ae3cdcb901 100644 --- a/usr.sbin/afs/src/util/ip.h +++ b/usr.sbin/afs/src/util/ip.h @@ -1,6 +1,6 @@ -/* $OpenBSD: ip.h,v 1.1.1.1 1998/09/14 21:53:23 art Exp $ */ +/* $OpenBSD: ip.h,v 1.2 1999/04/30 01:59:17 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ * SUCH DAMAGE. */ -/* $KTH: ip.h,v 1.3 1998/03/13 04:38:25 assar Exp $ */ +/* $KTH: ip.h,v 1.4 1999/01/03 01:55:08 assar Exp $ */ #ifndef _IP_ #define _IP_ @@ -47,6 +47,6 @@ #include <arpa/inet.h> struct in_addr *ipgetaddr (const char *addr, struct in_addr *ret); -char *ipgetname (struct in_addr *addr); +const char *ipgetname (struct in_addr *addr); #endif /* _IP_ */ diff --git a/usr.sbin/afs/src/util/list.c b/usr.sbin/afs/src/util/list.c index 740adce011d..51681f826fb 100644 --- a/usr.sbin/afs/src/util/list.c +++ b/usr.sbin/afs/src/util/list.c @@ -1,4 +1,4 @@ -/* $OpenBSD: list.c,v 1.1.1.1 1998/09/14 21:53:23 art Exp $ */ +/* $OpenBSD: list.c,v 1.2 1999/04/30 01:59:17 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -43,7 +43,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: list.c,v 1.7 1998/07/05 18:25:55 assar Exp $"); +RCSID("$KTH: list.c,v 1.10 1998/12/27 02:11:06 assar Exp $"); #endif #include <assert.h> @@ -163,16 +163,6 @@ listaddtail (List *list, void *data) } /* - * TRUE iff the list is empty. - */ - -Bool -listemptyp (List *list) -{ - return list->head == NULL; -} - -/* * Remove an element from the head of the list. * Return this element. */ @@ -238,36 +228,6 @@ listdel (List *list, Listitem *item) free (item); } -Listitem * -listhead (List *list) -{ - return list->head; -} - -Listitem * -listtail (List *list) -{ - return list->tail; -} - -Listitem * -listprev (List *list, Listitem *item) -{ - return item->prev; -} - -Listitem * -listnext (List *list, Listitem *item) -{ - return item->next; -} - -void * -listdata (Listitem *item) -{ - return item->data; -} - /* * Iterate through all the items in a list. */ diff --git a/usr.sbin/afs/src/util/list.h b/usr.sbin/afs/src/util/list.h index f8aaa572311..42a905c6a64 100644 --- a/usr.sbin/afs/src/util/list.h +++ b/usr.sbin/afs/src/util/list.h @@ -1,4 +1,4 @@ -/* $OpenBSD: list.h,v 1.1.1.1 1998/09/14 21:53:23 art Exp $ */ +/* $OpenBSD: list.h,v 1.2 1999/04/30 01:59:17 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -41,12 +41,13 @@ * list handling functions */ -/* $KTH: list.h,v 1.4 1998/07/05 18:25:00 assar Exp $ */ +/* $KTH: list.h,v 1.9 1999/01/11 02:24:33 rb Exp $ */ #ifndef _LIST_ #define _LIST_ #include "bool.h" +#include <roken.h> struct listitem { void *data; @@ -81,19 +82,53 @@ void *listdelhead (List *list); void *listdeltail (List *list); -Bool listemptyp (List *list); - -Listitem *listhead (List *list); - -Listitem *listtail (List *list); - -Listitem *listprev (List *list, Listitem *item); - -Listitem *listnext (List *list, Listitem *item); - -void *listdata (Listitem *item); - void listiter (List *list, Bool (*fn)(List *, Listitem *, void *arg), void *arg); +/* + * inline functions + */ + +static inline Listitem * __attribute__ ((unused)) +listhead (List *list) +{ + return list->head; +} + +static inline Listitem * __attribute__ ((unused)) +listtail (List *list) +{ + return list->tail; +} + +static inline Listitem * __attribute__ ((unused)) +listprev (List *list, Listitem *item) +{ + return item->prev; +} + +static inline Listitem * __attribute__ ((unused)) +listnext (List *list, Listitem *item) +{ + return item->next; +} + +static inline void * __attribute__ ((unused)) +listdata (Listitem *item) +{ + return item->data; +} + +static inline Bool __attribute__ ((unused)) +listemptyp (List *list) +{ + return (Bool)(list->head == NULL); +} + +static inline Bool __attribute__ ((unused)) +listnextp(Listitem *item) +{ + return (Bool)(item->next != NULL); +} + #endif /* _LIST_ */ diff --git a/usr.sbin/afs/src/util/log.c b/usr.sbin/afs/src/util/log.c index 0ad4414c401..1665b3886da 100644 --- a/usr.sbin/afs/src/util/log.c +++ b/usr.sbin/afs/src/util/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.1.1.1 1998/09/14 21:53:23 art Exp $ */ +/* $OpenBSD: log.c,v 1.2 1999/04/30 01:59:17 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -43,7 +43,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: log.c,v 1.12 1998/07/09 19:57:26 art Exp $"); +RCSID("$KTH: log.c,v 1.13 1998/10/04 19:41:10 assar Exp $"); #endif #include <stdio.h> @@ -171,20 +171,22 @@ log_vprint_file (Log_method *lm, char *fmt, va_list args) struct timeval tv = { 0, 0 }; char *time; time_t t; + FILE *f = (FILE *)lm->data.v; gettimeofday(&tv, NULL); t = tv.tv_sec; time = strdup(ctime(&t)); if (time) { time[strlen(time)-1] = '\0'; - fprintf ((FILE *)lm->data.v, "%s: ", time); + fprintf (f, "%s: ", time); free(time); } else - fprintf ((FILE *)lm->data.v, "unknown time:"); + fprintf (f, "unknown time:"); - fprintf ((FILE *)lm->data.v, "%s: ", __progname); - vfprintf ((FILE *)lm->data.v, fmt, args); - putc ('\n', (FILE *)lm->data.v); + fprintf (f, "%s: ", __progname); + vfprintf (f, fmt, args); + putc ('\n', f); + fflush (f); } static void diff --git a/usr.sbin/afs/src/util/prio.c b/usr.sbin/afs/src/util/prio.c deleted file mode 100644 index ecd314eafda..00000000000 --- a/usr.sbin/afs/src/util/prio.c +++ /dev/null @@ -1,173 +0,0 @@ -/* $OpenBSD: prio.c,v 1.1.1.1 1998/09/14 21:53:24 art Exp $ */ -/* - * Copyright (c) 1998 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Kungliga Tekniska - * Högskolan and its contributors. - * - * 4. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -RCSID("$KTH: prio.c,v 1.1 1998/07/07 15:57:10 lha Exp $"); -#endif - -#include <stdlib.h> -#include "bool.h" -#include "prio.h" - -#define PRIO_PARENT(x) (((x) + 1)/ 2 -1 ) -#define PRIO_LEFT(x) (2 * (i) + 1) -#define PRIO_RIGHT(x) (2 * (i) + 2) - - -Prio * -prionew(unsigned size, prio_cmp cmp) -{ - Prio *prio; - - if (!size || !cmp) - return NULL; - - prio = calloc(sizeof(Prio), 1); - if (!prio) - return prio; - - prio->heap = calloc(sizeof(Prio), size); - if (!prio->heap) - free(prio); - - prio->cmp = cmp; - prio->sz = size; - - return prio; -} - -void -priofree(Prio *prio) -{ - if (!prio) - return; - - free(prio); -} - -static void -heapify(Prio *prio, unsigned i) -{ - unsigned j; - void *el; - - if (!prio || i > prio->sz) - return; - - el = &prio->heap[0]; - while (prio->size && i <= PRIO_PARENT(prio->size)) { - j = PRIO_LEFT(i); - if (j < prio->size) { - if (prio->cmp(prio->heap[i], prio->heap[j]) < 0) - j++; - - if (prio->cmp(prio->heap[0], prio->heap[j]) < 0) - break; - - prio->heap[i] = prio->heap[j]; - } - i = j; - } - prio->heap[i] = el; -} - - - -int -prioinsert(Prio *prio, void *data) -{ - void **ptr; - unsigned i; - - if (!prio || !data) - return -1; - - - if (prio->sz == prio->size) { - ptr = realloc(prio->heap, prio->sz *2); - if (!ptr) - return -1; - - prio->heap = ptr; - } - - i = prio->size++; - - while (i > 0 && - prio->cmp(data,prio->heap[PRIO_PARENT(i)]) < 0) - { - prio->heap[i] = prio->heap[PRIO_PARENT(i)]; - i = PRIO_PARENT(i); - } - prio->heap[i] = data; - return 0; -} - -void * -priohead(Prio *prio) -{ - if (!prio) - return NULL; - - return prio->heap[0]; -} - -void -prioremove(Prio *prio) -{ - if (!prio) - return; - - if (prioemptyp (prio)) /* underflow */ - return; - - prio->heap[0] = prio->heap[--prio->size]; - heapify (prio, prio->size); -} - -Bool -prioemptyp(Prio *prio) -{ - if (!prio || prio->size == 0) - return TRUE; - - return FALSE; -} - diff --git a/usr.sbin/afs/src/util/strutil.c b/usr.sbin/afs/src/util/strutil.c index 63dbcb0377c..1fd5e152498 100644 --- a/usr.sbin/afs/src/util/strutil.c +++ b/usr.sbin/afs/src/util/strutil.c @@ -1,6 +1,6 @@ -/* $OpenBSD: strutil.c,v 1.1.1.1 1998/09/14 21:53:25 art Exp $ */ +/* $OpenBSD: strutil.c,v 1.2 1999/04/30 01:59:18 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -43,7 +43,7 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: strutil.c,v 1.5 1998/03/18 19:30:42 art Exp $"); +RCSID("$KTH: strutil.c,v 1.7 1998/12/20 15:56:33 assar Exp $"); #endif #include <string.h> @@ -55,10 +55,11 @@ RCSID("$KTH: strutil.c,v 1.5 1998/03/18 19:30:42 art Exp $"); */ char * -strtrim (char *str) +strtrim (char *s_str) { - char *s; - unsigned len = strlen (str); + unsigned len = strlen (s_str); + unsigned char *str = (unsigned char *)s_str; + unsigned char *s; for (s = str + len - 1; s >= str && *s && isspace(*s); --s) ; @@ -67,39 +68,6 @@ strtrim (char *str) for (s = str; *s && isspace(*s); ++s) ; if (s != str) -#ifdef HAVE_MEMMOVE memmove (str, s, len - (str - s)); -#else - bcopy (s, str, len - (str - s)); -#endif - return str; -} - -/* - * Uppercase all characters in string and return it. - */ - -char * -strupr (char *s) -{ - char *t = s; - - for (; *t; t++) - *t = toupper (*t); - return s; + return s_str; } - -/* - * Lowercase all characters in string and return it. - */ - -char * -strlwr (char *s) -{ - char *t = s; - - for (; *t; t++) - *t = tolower (*t); - return s; -} - diff --git a/usr.sbin/afs/src/util/strutil.h b/usr.sbin/afs/src/util/strutil.h index f74cd8c8826..f3c2813facf 100644 --- a/usr.sbin/afs/src/util/strutil.h +++ b/usr.sbin/afs/src/util/strutil.h @@ -1,6 +1,6 @@ -/* $OpenBSD: strutil.h,v 1.1.1.1 1998/09/14 21:53:25 art Exp $ */ +/* $OpenBSD: strutil.h,v 1.2 1999/04/30 01:59:18 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,13 +37,11 @@ * SUCH DAMAGE. */ -/* $KTH: strutil.h,v 1.2 1997/11/09 23:48:58 assar Exp $ */ +/* $KTH: strutil.h,v 1.3 1998/08/28 20:49:36 assar Exp $ */ #ifndef _STRUTIL_ #define _STRUTIL_ -char *strupr (char *); -char *strlwr (char *); char *strtrim (char *); #endif /* _STRUTIL_ */ diff --git a/usr.sbin/afs/src/util/util-tester.c b/usr.sbin/afs/src/util/util-tester.c index a1be8a97a79..c7afbf78257 100644 --- a/usr.sbin/afs/src/util/util-tester.c +++ b/usr.sbin/afs/src/util/util-tester.c @@ -1,6 +1,6 @@ -/* $OpenBSD: util-tester.c,v 1.1.1.1 1998/09/14 21:53:26 art Exp $ */ +/* $OpenBSD: util-tester.c,v 1.2 1999/04/30 01:59:19 art Exp $ */ /* - * Copyright (c) 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -42,7 +42,6 @@ #include <sys/time.h> #include "bool.h" -#include "timeprio.h" #include "hash.h" struct timeval time1, time2; @@ -74,30 +73,6 @@ endtesting(int bool) int -test_timeprio(void) -{ - Timeprio *tp = timeprionew(100); - - starttesting("timeprio"); - - timeprioinsert(tp, 10, "ten"); - timeprioinsert(tp, 40, "fourty"); - timeprioinsert(tp, 30, "thirty"); - - - while(!timeprioemptyp(tp)) { - printf("timepriohead(tp) = %s\n", (char *) timepriohead(tp)); - timeprioremove(tp); - } - - timepriofree(tp); - - endtesting(0); - - return 0; -} - -int hash_cmp(void *foo, void *bar) { return strcmp((char *) foo, (char *)bar); @@ -151,11 +126,5 @@ test_hash(void) int main(int argc, char **argv) { - test_timeprio(); - test_hash(); - return 0; + return test_hash(); } - - - - diff --git a/usr.sbin/afs/src/ydr/lex.h b/usr.sbin/afs/src/ydr/lex.h index 511101d1124..b4ace921607 100644 --- a/usr.sbin/afs/src/ydr/lex.h +++ b/usr.sbin/afs/src/ydr/lex.h @@ -1,6 +1,6 @@ -/* $OpenBSD: lex.h,v 1.1.1.1 1998/09/14 21:53:26 art Exp $ */ +/* $OpenBSD: lex.h,v 1.2 1999/04/30 01:59:19 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,11 +37,11 @@ * SUCH DAMAGE. */ -/* $KTH: lex.h,v 1.3 1998/02/19 05:11:49 assar Exp $ */ +/* $KTH: lex.h,v 1.4 1999/03/01 08:38:22 assar Exp $ */ #ifndef _LEX_ #define _LEX_ -void error_message (char *, ...); +void error_message (int errorp, char *, ...); #endif /* _LEX_ */ diff --git a/usr.sbin/afs/src/ydr/lex.l b/usr.sbin/afs/src/ydr/lex.l index 9cc0f69f91e..686e6966681 100644 --- a/usr.sbin/afs/src/ydr/lex.l +++ b/usr.sbin/afs/src/ydr/lex.l @@ -1,6 +1,6 @@ %{ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,9 +39,15 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: lex.l,v 1.1.1.1 1998/09/14 21:53:27 art Exp $"); +RCSID("$Id: lex.l,v 1.2 1999/04/30 01:59:19 art Exp $"); #endif +/* + * This is to handle the definition of this symbol in some AIX + * headers, which will conflict with the definition that lex will + * generate for it. It's only a problem for AIX lex. + */ + #undef ECHO #include <stdio.h> @@ -64,10 +70,10 @@ static void parse_lineno (char *s); %} %% -^\#[ ][0-9]+[ ]\"[^\n\"]*\".*$ { parse_filename (yytext); } -^\#line[ ][0-9]+[ ]\"[^\n\"]*\".*$ { parse_filename (yytext); } -^\#[ ][0-9]+ { parse_lineno (yytext); } -^\#line[ ][0-9]+ { parse_lineno (yytext); } +^\#[ ][0-9]+[ ]\"[^\n\"]*\".*\n { parse_filename (yytext); } +^\#line[ ][0-9]+[ ]\"[^\n\"]*\".*\n { parse_filename (yytext); } +^\#[ ][0-9]+.*\n { parse_lineno (yytext); } +^\#line[ ][0-9]+.*\n { parse_lineno (yytext); } ^\#ident.*$ { } const { return T_CONST; } enum { return T_ENUM; } @@ -88,6 +94,9 @@ char { return T_CHAR; } string { return T_STRING; } opaque { return T_OPAQUE; } package { return T_PACKAGE; } +prefix { return T_PREFIX; } +proc { return T_PROC; } +error-function { return T_ERROR_FUNCTION; } split { return T_SPLIT; } multi { return T_MULTI; } IN { return T_IN; } @@ -111,11 +120,11 @@ if (sym == NULL) { else if (sym->type == TTYPEDEF || sym->type == TENUM || sym->type == TSTRUCT) return T_IDTYPE; else - error_message ("Ignoring \"%s\"\n", yytext); + error_message (0, "Ignoring \"%s\"\n", yytext); } [ \t] ; \n { lineno++; } -. { error_message("Ignoring char(%c)\n", *yytext); } +. { error_message(0, "Ignoring char(%c)\n", *yytext); } %% #ifndef yywrap @@ -127,7 +136,7 @@ yywrap (void) #endif /* !yywrap */ void -error_message (char *format, ...) +error_message (int errorp, char *format, ...) { va_list args; @@ -135,6 +144,8 @@ error_message (char *format, ...) fprintf (stderr, "%s:%d: ", filename, lineno); vfprintf (stderr, format, args); va_end (args); + if (errorp) + parse_errors = 1; } static void diff --git a/usr.sbin/afs/src/ydr/main.c b/usr.sbin/afs/src/ydr/main.c index 395e4dc78c7..4fceeb732dc 100644 --- a/usr.sbin/afs/src/ydr/main.c +++ b/usr.sbin/afs/src/ydr/main.c @@ -1,6 +1,6 @@ -/* $OpenBSD: main.c,v 1.1.1.1 1998/09/14 21:53:27 art Exp $ */ +/* $OpenBSD: main.c,v 1.2 1999/04/30 01:59:19 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,14 +39,14 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: main.c,v 1.9 1998/03/13 04:46:33 assar Exp $"); +RCSID("$KTH: main.c,v 1.15 1999/03/01 08:45:13 assar Exp $"); #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <mem.h> +#include <roken.h> #include <fnameutil.h> #include "sym.h" #include "output.h" @@ -55,6 +55,8 @@ RCSID("$KTH: main.c,v 1.9 1998/03/13 04:46:33 assar Exp $"); extern FILE *yyin; +int parse_errors; + /* * ydr - generate stub routines for encode/decoding and RX */ @@ -110,9 +112,32 @@ main (int argc, char **argv) yyin = popen (arg, "r"); free (arg); ret = yyparse (); - generate_server_switch (serverfile, serverhdrfile); + generate_server_switch (serverfile.stream, serverhdrfile.stream); + generate_tcpdump_patches (td_file.stream, filename); pclose (yyin); close_generator (filename); unlink (tmp_filename); - return ret; + + if (getenv("USER") && strcmp(getenv("USER"), "art") == 0) { + char *foo; + + if (asprintf(&foo, "indent %s.cs.c", filename) > 0) { + system(foo); + free(foo); + } + if (asprintf(&foo, "indent %s.ss.c", filename) > 0) { + system(foo); + free(foo); + } + if (asprintf(&foo, "indent %s.ydr.c", filename) > 0) { + system(foo); + free(foo); + } + if (asprintf(&foo, "indent %s.h", filename) > 0) { + system(foo); + free(foo); + } + } + + return ret + parse_errors; } diff --git a/usr.sbin/afs/src/ydr/output.c b/usr.sbin/afs/src/ydr/output.c index d8236675e06..4e7658e0cad 100644 --- a/usr.sbin/afs/src/ydr/output.c +++ b/usr.sbin/afs/src/ydr/output.c @@ -1,6 +1,6 @@ -/* $OpenBSD: output.c,v 1.1.1.1 1998/09/14 21:53:26 art Exp $ */ +/* $OpenBSD: output.c,v 1.2 1999/04/30 01:59:19 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,15 +39,16 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: output.c,v 1.31 1998/09/06 23:33:39 assar Exp $"); +RCSID("$KTH: output.c,v 1.56 1999/03/05 05:13:56 assar Exp $"); #endif #include <stdio.h> -#include <list.h> -#include <efile.h> +#include <assert.h> #include <string.h> +#include <list.h> +#include <eefile.h> #include <strutil.h> -#include <mem.h> +#include <err.h> #include <roken.h> #include "sym.h" #include "output.h" @@ -61,20 +62,33 @@ RCSID("$KTH: output.c,v 1.31 1998/09/06 23:33:39 assar Exp $"); char *package = ""; /* + * Add this in front of the real functions implementing the server + * functions called. + */ + +char *prefix = ""; + +/* * File handles for the generated files themselves. */ -FILE *headerfile, - *clientfile, - *serverfile, - *clienthdrfile, - *serverhdrfile, - *ydrfile; +fileblob headerfile, + clientfile, + serverfile, + clienthdrfile, + serverhdrfile, + td_file, + ydrfile; -long tmpcnt = 0 ; +long tmpcnt = 0; -typedef enum { ENCODE_RX, DECODE_RX, ENCODE_MEM, DECODE_MEM } EncodeType; +/* + * Function to convert error codes with (if non-NULL) + */ +char *error_function = NULL; + +typedef enum { ENCODE_RX, DECODE_RX, ENCODE_MEM, DECODE_MEM } EncodeType; static void print_type (char *name, Type *type, FILE *f); static Bool print_entry (List *list, Listitem *item, void *i); @@ -86,6 +100,8 @@ static int sizeof_type (Type *type); static int sizeof_symbol (Symbol *); static void encode_type (char *name, Type *type, FILE *f, EncodeType encodetype); +static void print_type (char *name, Type *type, FILE *f); +static void display_type (char *where, char *name, Type *type, FILE *f); static Bool encode_entry (List *list, Listitem *item, void *arg); static void encode_struct (Symbol *s, char *name, FILE *f, EncodeType encodetype); @@ -94,6 +110,7 @@ static void encode_typedef (Symbol *s, char *name, FILE *f, EncodeType encodetype); static void encode_symbol (Symbol *s, char *name, FILE *f, EncodeType encodetype); +static void print_symbol (char *where, Symbol *s, char *name, FILE *f); static void print_type (char *name, Type *type, FILE *f) @@ -118,7 +135,10 @@ print_type (char *name, Type *type, FILE *f) fprintf (f, "u_int32_t %s", name); break; case TSTRING : - fprintf (f, "char %s[%d]", name, type->size); + if (type->size) + fprintf (f, "char %s[%d]", name, type->size); + else + fprintf (f, "char *%s", name); break; case TPOINTER : { @@ -232,7 +252,7 @@ sizeof_type (Type *t) else return t->size; case TOPAQUE : - return -1; + return 1; case TUSERDEF : return sizeof_symbol (t->symbol); case TARRAY : @@ -332,7 +352,7 @@ generate_sizeof (Symbol *s, FILE *f) if (sz != -1) { char *name; - name = strdup (s->name); + name = estrdup (s->name); fprintf (f, "#define %s_SIZE %d\n", strupr (name), sz); free (name); } @@ -343,7 +363,7 @@ generate_header (Symbol *s, FILE *f) { switch (s->type) { case TUNDEFINED : - fprintf (f, "What is %s doing in generate_heaer?", s->name); + fprintf (f, "What is %s doing in generate_header?", s->name); break; case TSTRUCT : generate_hdr_struct (s, f); @@ -399,6 +419,10 @@ encode_function (Type *type, EncodeType encodetype) abort(); } +/* + * encode/decode long + */ + static void encode_long (char *name, Type *type, FILE *f, EncodeType encodetype) { @@ -422,7 +446,7 @@ encode_long (char *name, Type *type, FILE *f, EncodeType encodetype) break; case ENCODE_MEM : fprintf (f, "{ int32_t tmp = %s(%s); " - "if (*total_len < sizeof(int32_t)) { errno = EFAULT; return NULL ; } " + "if (*total_len < sizeof(int32_t)) goto fail;\n" "bcopy ((char*)&tmp, ptr, sizeof(int32_t)); " "ptr += sizeof(int32_t); " "*total_len -= sizeof(int32_t);}\n", @@ -431,7 +455,7 @@ encode_long (char *name, Type *type, FILE *f, EncodeType encodetype) break; case DECODE_MEM : fprintf (f, "{ int32_t tmp; " - "if (*total_len < sizeof(int32_t)) { errno = EFAULT; return NULL ; } " + "if (*total_len < sizeof(int32_t)) goto fail;" "bcopy (ptr, (char *)&tmp, sizeof(int32_t)); " "%s = %s(tmp); " "ptr += sizeof(int32_t); " @@ -444,8 +468,21 @@ encode_long (char *name, Type *type, FILE *f, EncodeType encodetype) } } -#ifdef not_yet +/* + * print long + */ + static void +print_long (char *where, char *name, Type *type, FILE *f) +{ + fprintf (f, "printf(\" %s = %%d\", %s%s);", name, where, name); +} + +/* + * + */ + +static void __attribute__ ((unused)) encode_char (char *name, Type *type, FILE *f, EncodeType encodetype) { switch (encodetype) { @@ -462,13 +499,13 @@ encode_char (char *name, Type *type, FILE *f, EncodeType encodetype) name, name, name); break; case ENCODE_MEM : - fprintf (f, "{ if (*total_len < sizeof(char)) { errno = EFAULT; return NULL ; } " + fprintf (f, "{ if (*total_len < sizeof(char)) goto fail;\n" "*((char *)ptr) = %s; " "ptr += sizeof(char); *total_len -= sizeof(char);}\n", name); break; case DECODE_MEM : - fprintf (f, "{ if (*total_len < sizeof(char)) { errno = EFAULT; return NULL ; } " + fprintf (f, "{ if (*total_len < sizeof(char)) goto fail;\n" "%s = *((char *)ptr); " "ptr += sizeof(char); *total_len -= sizeof(char);}\n", name); @@ -478,7 +515,7 @@ encode_char (char *name, Type *type, FILE *f, EncodeType encodetype) } } -static void +static void __attribute__ ((unused)) encode_short (char *name, Type *type, FILE *f, EncodeType encodetype) { switch (encodetype) { @@ -494,23 +531,23 @@ encode_short (char *name, Type *type, FILE *f, EncodeType encodetype) case DECODE_RX : fprintf (f, "{ int16_t u;\n" "if(rx_Read(call, &u, sizeof(u)) != sizeof(u))\n" - "goto fail;\n" + "goto fail;\n" "%s = %s (u);\n" "}\n", name, encode_function (type, encodetype)); break; case ENCODE_MEM : - fprintf (f, "{ in16_t tmp = %s(%s); " - "if (*total_len < sizeof(int16_t)) { errno = EFAULT; return NULL ; } " - "bcopy ((char*)&tmp, ptr, sizeof(int16_t)); " - "ptr += sizeof(int16_t); " - "*total_len -= sizeof(int16_t);}\n", - encode_function (type, encodetype), + fprintf (f, "{ in16_t tmp = %s(%s); " + "if (*total_len < sizeof(int16_t)) goto fail;\n" + "bcopy ((char*)&tmp, ptr, sizeof(int16_t)); " + "ptr += sizeof(int16_t); " + "*total_len -= sizeof(int16_t);}\n", + encode_function (type, encodetype), name); break; case DECODE_MEM : fprintf (f, "{ int16_t tmp; " - "if (*total_len < sizeof(int16_t)) { errno = EFAULT; return NULL ; } " + "if (*total_len < sizeof(int16_t)) goto fail;\n" "bcopy (ptr, (char *)&tmp, sizeof(int16_t)); " "%s = %s(tmp); " "ptr += sizeof(int16_t); " @@ -522,7 +559,10 @@ encode_short (char *name, Type *type, FILE *f, EncodeType encodetype) abort (); } } -#endif + +/* + * encode/decode TSTRING + */ static void encode_string (char *name, Type *type, FILE *f, EncodeType encodetype) @@ -550,11 +590,15 @@ encode_string (char *name, Type *type, FILE *f, EncodeType encodetype) "unsigned padlen;\n" "char zero[4] = {0, 0, 0, 0};\n"); encode_type ("len", &lentype, f, encodetype); - if (type->size != 0) + if (type->size != 0) { fprintf (f, "if (len >= %u)\n" "abort();\n", type->size); + } else { + fprintf(f, "%s = malloc(len + 1);\n", name); + } + fprintf (f, "if(rx_Read(call, %s, len) != len)\n" "goto fail;\n" @@ -567,23 +611,34 @@ encode_string (char *name, Type *type, FILE *f, EncodeType encodetype) case ENCODE_MEM : fprintf (f, "{\nunsigned len = strlen(%s);\n" - "if (*total_len < len) { errno = EFAULT; return NULL ; } " + "if (*total_len < len) goto fail;\n" "*total_len -= len;\n", name); encode_type ("len", &lentype, f, encodetype); fprintf (f, "strncpy (ptr, %s, len);\n", name); - fprintf (f, "ptr += len + (4 - (len %% 4) %% 4);\n}\n"); + fprintf (f, "ptr += len + (4 - (len %% 4) %% 4);\n" + "*total_len -= len + (4 - (len %% 4) %% 4);\n}\n"); break; case DECODE_MEM : fprintf (f, "{\nunsigned len;\n"); encode_type ("len", &lentype, f, encodetype); fprintf (f, - "if (*total_len < len) { errno = EFAULT; return NULL ; }\n" - "*total_len -= len;\n" + "if (*total_len < len) goto fail;\n" + "*total_len -= len;\n"); + if (type->size != 0) { + fprintf (f, + "if(len >= %u)\n" + "abort();\n", + type->size); + } else { + fprintf (f, "%s = malloc(len + 1);\n", name); + } + fprintf (f, "memcpy (%s, ptr, len);\n" "%s[len] = '\\0';\n" - "ptr += len + (4 - (len %% 4)) %% 4;\n}\n", + "ptr += len + (4 - (len %% 4)) %% 4;\n" + "*total_len -= len + (4 - (len %% 4) %% 4);\n}\n", name, name); break; default : @@ -591,12 +646,27 @@ encode_string (char *name, Type *type, FILE *f, EncodeType encodetype) } } +/* + * print TSTRING + */ + +static void +print_string (char *where, char *name, Type *type, FILE *f) +{ + fprintf (f, "/* printing TSTRING %s%s */\n", where, name); + fprintf (f, "printf(\" %s = %%s\", %s%s);", name, where, name); +} + +/* + * encode/decode TARRAY + */ + static void encode_array (char *name, Type *type, FILE *f, EncodeType encodetype) { if (type->subtype->type == TOPAQUE) { if (type->size % 4 != 0) - error_message ("Opaque array should be" + error_message (1, "Opaque array should be" "multiple of 4"); switch (encodetype) { case ENCODE_RX : @@ -612,14 +682,14 @@ encode_array (char *name, Type *type, FILE *f, EncodeType encodetype) name, type->size, type->size); break; case ENCODE_MEM : - fprintf (f, "if (*total_len < %u) { errno = EFAULT; return NULL ; }\n" + fprintf (f, "if (*total_len < %u) goto fail;\n" "memcpy (ptr, %s, %u);\n", type->size, name, type->size); fprintf (f, "ptr += %u; *total_len -= %u;\n", type->size, type->size); break; case DECODE_MEM : - fprintf (f, "if (*total_len < %u) { errno = EFAULT; return NULL ; }\n" + fprintf (f, "if (*total_len < %u) goto fail;" "memcpy (%s, ptr, %u);\n", type->size, name, type->size); fprintf (f, "ptr += %u; *total_len -= %u;\n", @@ -641,6 +711,50 @@ encode_array (char *name, Type *type, FILE *f, EncodeType encodetype) } } +/* + * encode/decode TARRAY + */ + +static void +print_array (char *where, char *name, Type *type, FILE *f) +{ + fprintf (f, "{\nunsigned int i%lu;\n", tmpcnt); + + fprintf (f, "/* printing ARRAY %s%s */\n", where, name); + + if (type->subtype->type == TOPAQUE) { + if (type->size % 4 != 0) + error_message (1, "print_array: Opaque array should be" + "multiple of 4"); + + fprintf (f, "char *ptr = %s%s;\n", where, name); + fprintf (f, "printf(\"0x\");"); + fprintf (f, "for (i%lu = 0; i%lu < %d; ++i%lu)\n" + "printf(\"%%x\", ptr[i%lu]);", + tmpcnt, tmpcnt, + type->size, tmpcnt, tmpcnt); + + } else { + char *ptr; + fprintf (f, "for (i%lu = 0; i%lu < %d; ++i%lu) {\n", + tmpcnt, tmpcnt, type->size, tmpcnt); + asprintf(&ptr, "%s%s[i%ld]", where, name, tmpcnt); + tmpcnt++; + display_type (ptr, "", type->subtype, f); + tmpcnt--; + free(ptr); + fprintf (f, "\nif (i%lu != %d - 1) printf(\",\");\n", + tmpcnt, type->size); + + fprintf (f, "}\n"); + } + fprintf (f, "}\n"); +} + +/* + * encode/decode TVARRAY + */ + static void encode_varray (char *name, Type *type, FILE *f, EncodeType encodetype) { @@ -715,6 +829,45 @@ encode_varray (char *name, Type *type, FILE *f, EncodeType encodetype) } } +/* + * print TVARRAY + */ + +static void +print_varray (char *where, char *name, Type *type, FILE *f) +{ + fprintf (f, "{\nunsigned int i%lu;\n", tmpcnt); + + fprintf (f, "/* printing TVARRAY %s%s */\n", where, name); + + if (type->subtype->type == TOPAQUE) { + fprintf (f, "char *ptr = %s%s.val;\n", where, name); + fprintf (f, "printf(\"0x\");"); + fprintf (f, "for (i%lu = 0; i%lu < %s%s.len; ++i%lu)\n" + "printf(\"%%x\", ptr[i%lu]);", + tmpcnt, tmpcnt, + where, name, tmpcnt, tmpcnt); + } else { + char *ptr; + fprintf (f, "for (i%lu = 0; i%lu < %s%s.len; ++i%lu) {\n", + tmpcnt, tmpcnt, where, name, tmpcnt); + asprintf(&ptr, "%s%s.val[i%ld]", where, name, tmpcnt); + tmpcnt++; + display_type (ptr, "", type->subtype, f); + tmpcnt--; + free(ptr); + fprintf (f, "\nif (i%lu != %s%s.len - 1) printf(\",\");\n", + tmpcnt, where, name); + + fprintf (f, "}\n"); + } + fprintf (f, "}\n"); +} + +/* + * encode/decode pointer + */ + static void encode_pointer (char *name, Type *type, FILE *f, EncodeType encodetype) { @@ -755,6 +908,10 @@ encode_pointer (char *name, Type *type, FILE *f, EncodeType encodetype) } } +/* + * encode type + */ + static void encode_type (char *name, Type *type, FILE *f, EncodeType encodetype) { @@ -779,7 +936,8 @@ encode_type (char *name, Type *type, FILE *f, EncodeType encodetype) encode_string (name, type, f, encodetype); break; case TOPAQUE : - error_message ("Type opaque only allowed as part of an array"); + error_message (1, + "Type opaque only allowed as part of an array"); break; case TUSERDEF : encode_symbol (type->symbol, name, f, encodetype); @@ -798,6 +956,55 @@ encode_type (char *name, Type *type, FILE *f, EncodeType encodetype) } } +/* + * print type + */ + +static void +display_type (char *where, char *name, Type *type, FILE *f) +{ + assert (where); + + switch (type->type) { + case TCHAR : + case TUCHAR : +#if 0 + print_char (name, type, f, encodetype); + break; +#endif + case TSHORT : + case TUSHORT : +#if 0 + print_short (name, type, f, encodetype); + break; +#endif + case TLONG : + case TULONG : + print_long (where, name, type, f); + break; + case TSTRING : + print_string (where, name, type, f); + break; + case TOPAQUE : + fprintf (f, "printf(\"printing TOPAQUE\\n\");"); + break; + case TUSERDEF : + print_symbol (where, type->symbol, name, f); + break; + case TARRAY : + print_array (where, name, type, f); + break; + case TVARRAY : + print_varray (where, name, type, f); + break; + case TPOINTER : + fprintf (f, "printf(\"printing TPOINTER\\n\");"); + break; + default : + abort(); + } +} + struct context { char *name; FILE *f; @@ -805,6 +1012,10 @@ struct context { EncodeType encodetype; }; +/* + * helpfunction for encode_struct + */ + static Bool encode_entry (List *list, Listitem *item, void *arg) { @@ -832,6 +1043,10 @@ encode_entry (List *list, Listitem *item, void *arg) return FALSE; } +/* + * encode/decode TSTRUCT + */ + static void encode_struct (Symbol *s, char *name, FILE *f, EncodeType encodetype) { @@ -845,6 +1060,75 @@ encode_struct (Symbol *s, char *name, FILE *f, EncodeType encodetype) listiter (s->u.list, encode_entry, (void *)&context); } +/* + * help function for print_struct + */ + +struct printcontext { + char *where; + char *name; + FILE *f; + Symbol *symbol; +}; + +static Bool +print_structentry (List *list, Listitem *item, void *arg) +{ + StructEntry *s = (StructEntry *)listdata (item); + struct printcontext *context = (struct printcontext *)arg; + + char *tmp; + char *tmp2; + + asprintf(&tmp, ".%s", s->name); + asprintf(&tmp2, "%s%s", context->where, context->name); + + if (s->type->type == TPOINTER + && s->type->subtype->type == TUSERDEF + && s->type->subtype->symbol->type == TSTRUCT + && strcmp(s->type->subtype->symbol->name, + context->symbol->name) == 0) { + fprintf (context->f, + "ydr_print_%s%s(%s%s, ptr);\n", + package, + context->symbol->name, + tmp2, + tmp); + } else { + display_type (tmp2, tmp, s->type, context->f); + } + + free(tmp); + free(tmp2); + + fprintf (context->f, "\n"); + + return FALSE; +} + +/* + * print TSTRUCT + */ + +static void +print_struct (char *where, Symbol *s, char *name, FILE *f) +{ + struct printcontext context; + + context.name = name; + context.symbol = s; + context.f = f; + context.where = where ; + + fprintf (f, "/* printing TSTRUCT %s%s */\n", where, name); + + listiter (s->u.list, print_structentry, (void *)&context); +} + +/* + * encode/decode TENUM + */ + static void encode_enum (Symbol *s, char *name, FILE *f, EncodeType encodetype) { @@ -857,12 +1141,63 @@ encode_enum (Symbol *s, char *name, FILE *f, EncodeType encodetype) encode_type (tmp, &type, f, encodetype); } +/* + * print TENUM + */ + +static Bool +gen_printenum (List *list, Listitem *item, void *arg) +{ + Symbol *s = (Symbol *)listdata (item); + FILE *f = (FILE *)arg; + + fprintf (f, "case %d:\n" + "printf(\"%s\");\n" + "break;\n", + (int) s->u.val, s->name); + + return FALSE; +} + +static void +print_enum (char *where, Symbol *s, char *name, FILE *f) +{ + fprintf (f, "/* print ENUM %s */\n", where); + + fprintf (f, "printf(\"%s = \");", name); + fprintf (f, "switch(%s) {\n", where); + listiter (s->u.list, gen_printenum, f); + fprintf (f, + "default:\n" + "printf(\" unknown enum %%d\", %s);\n" + "}\n", + where); +} + +/* + * encode/decode TTYPEDEF + */ + static void encode_typedef (Symbol *s, char *name, FILE *f, EncodeType encodetype) { encode_type (name, s->u.type, f, encodetype); } +/* + * print TTYPEDEF + */ + +static void +print_typedef (char *where, Symbol *s, char *name, FILE *f) +{ + display_type (where, name, s->u.type, f); +} + +/* + * Encode symbol/TUSERDEF + */ + static void encode_symbol (Symbol *s, char *name, FILE *f, EncodeType encodetype) { @@ -882,6 +1217,28 @@ encode_symbol (Symbol *s, char *name, FILE *f, EncodeType encodetype) } /* + * print symbol/TUSERDEF + */ + +static void +print_symbol (char *where, Symbol *s, char *name, FILE *f) +{ + switch (s->type) { + case TSTRUCT : + print_struct (where, s, name, f); + break; + case TENUM : + print_enum (where, s, name, f); + break; + case TTYPEDEF : + print_typedef (where, s, name, f); + break; + default : + abort(); + } +} + +/* * Generate the definition of an encode/decode function. */ @@ -897,7 +1254,26 @@ generate_function_definition (Symbol *s, FILE *f, Bool encodep) || s->type == TTYPEDEF) ; else - error_message ("What is %s (type %d) doing here?\n", + error_message (1, "What is %s (type %d) doing here?\n", + s->name, s->type); +} + +/* + * Generate the definition of a print function. + */ + +static void +generate_printfunction_definition (Symbol *s, FILE *f) +{ + if (s->type == TSTRUCT || s->type == TENUM || s->type == TTYPEDEF) { + fprintf (f, + "void ydr_print_%s(%s *o)", + s->name, s->name); + } else if (s->type == TCONST || s->type == TENUMVAL + || s->type == TTYPEDEF) + ; + else + error_message (1, "What is %s (type %d) doing here?\n", s->name, s->type); } @@ -912,12 +1288,35 @@ generate_function (Symbol *s, FILE *f, Bool encodep) generate_function_definition (s, f, encodep); fprintf (f, "\n{\n"); encode_symbol (s, "(*o)", f, encodep ? ENCODE_MEM : DECODE_MEM); - fprintf (f, "return ptr;\n}\n"); + fprintf (f, "return ptr;\n" + "fail:\n" + "errno = EFAULT;\n" + "return NULL;}\n"); } else if (s->type == TCONST || s->type == TENUMVAL || s->type == TTYPEDEF) ; else - error_message ("What is %s (type %d) doing here?\n", + error_message (1, "What is %s (type %d) doing here?\n", + s->name, s->type); +} + +/* + * Generate a print function + */ + +void +generate_printfunction (Symbol *s, FILE *f) +{ + if (s->type == TSTRUCT || s->type == TENUM || s->type == TTYPEDEF) { + generate_printfunction_definition (s, f); + fprintf (f, "\n{\n"); + print_symbol ("(*o)", s, "", f); + fprintf (f, "return;\n}\n"); + } else if (s->type == TCONST || s->type == TENUMVAL + || s->type == TTYPEDEF) + ; + else + error_message (1, "What is %s (type %d) doing here?\n", s->name, s->type); } @@ -935,7 +1334,25 @@ generate_function_prototype (Symbol *s, FILE *f, Bool encodep) || s->type == TTYPEDEF) ; else - error_message ("What is %s (type %d) doing here?\n", + error_message (1, "What is %s (type %d) doing here?\n", + s->name, s->type); +} + +/* + * Generate an prototype for a print function + */ + +void +generate_printfunction_prototype (Symbol *s, FILE *f) +{ + if (s->type == TSTRUCT || s->type == TENUM || s->type == TTYPEDEF) { + generate_printfunction_definition (s, f); + fprintf (f, ";\n"); + } else if (s->type == TCONST || s->type == TENUMVAL + || s->type == TTYPEDEF) + ; + else + error_message (1, "What is %s (type %d) doing here?\n", s->name, s->type); } @@ -948,7 +1365,7 @@ gen1 (List *list, Listitem *item, void *arg) if ((a->argtype == TOUT || a->argtype == TINOUT) && a->type->type != TPOINTER && a->type->type != TSTRING) - error_message ("Argument %s is OUT and not pointer or string.\n", + error_message (1, "Argument %s is OUT and not pointer or string.\n", a->name); fprintf (f, ", "); if (a->argtype == TIN) @@ -1177,10 +1594,11 @@ generate_simple_stub (Symbol *s, FILE *f, FILE *headerf) fprintf (f, "return rx_EndCall (call,0);\n" "fail:\n" - "ret = rx_Error(call);\n" + "ret = %s(rx_Error(call));\n" "rx_EndCall (call, 0);\n" "return ret;\n" - "}\n"); + "}\n", + error_function ? error_function : ""); } static void @@ -1209,7 +1627,9 @@ generate_split_stub (Symbol *s, FILE *f, FILE *headerf) if (findargtype(s->u.proc.arguments, TIN) || findargtype(s->u.proc.arguments, TINOUT)) fprintf (f, "fail:\n" - "return rx_Error(call);\n"); + "return %s(rx_Error(call));\n", + error_function ? error_function : ""); + fprintf (f, "}\n\n"); fprintf (headerf, "int End%s%s(\nstruct rx_call *call\n", @@ -1228,10 +1648,58 @@ generate_split_stub (Symbol *s, FILE *f, FILE *headerf) if (findargtype(s->u.proc.arguments, TOUT) || findargtype(s->u.proc.arguments, TINOUT)) fprintf (f, "fail:\n" - "return rx_Error(call);\n"); + "return %s(rx_Error(call));\n", + error_function ? error_function : ""); + fprintf (f, "}\n\n"); } +struct gen_args { + FILE *f; + int firstp; + int arg_type; +}; + +static Bool +genmacro (List *list, Listitem *item, void *arg) +{ + Argument *a = (Argument *)listdata (item); + struct gen_args *args = (struct gen_args *)arg; + + if (a->argtype == args->arg_type || a->argtype == TINOUT) { + fprintf (args->f, "%s%s", + args->firstp ? "" : ", ", a->name); + args->firstp = 0; + } + + return FALSE; +} + +static void +generate_multi (Symbol *s, FILE *f) +{ + struct gen_args gen_args; + + fprintf (f, "\n#include <rx/rx_multi.h>"); + fprintf (f, "\n#define multi_%s%s(", package, s->name); + gen_args.f = f; + gen_args.firstp = 1; + gen_args.arg_type = TIN; + listiter (s->u.proc.arguments, genmacro, &gen_args); + fprintf (f, ") multi_Body("); + fprintf (f, "Start%s%s(multi_call", package, s->name); + gen_args.f = f; + gen_args.firstp = 0; + gen_args.arg_type = TIN; + listiter (s->u.proc.arguments, genmacro, &gen_args); + fprintf (f, "), End%s%s(multi_call", package, s->name); + gen_args.f = f; + gen_args.firstp = 0; + gen_args.arg_type = TOUT; + listiter (s->u.proc.arguments, genmacro, f); + fprintf (f, "))\n"); +} + void generate_client_stub (Symbol *s, FILE *f, FILE *headerf) { @@ -1248,94 +1716,114 @@ generate_client_stub (Symbol *s, FILE *f, FILE *headerf) static List *func_list; +static void +generate_standard_c_prologue (FILE *f, + const char *filename, + const char *basename) +{ + fprintf (f, "/* Generated from %s.xg */\n", basename); + fprintf (f, "#include \"%s.h\"\n\n", basename); + fprintf (f, "#include <stdio.h>\n"); + fprintf (f, "#include <stdlib.h>\n"); + fprintf (f, "#include <string.h>\n"); + fprintf (f, "#include <netinet/in.h>\n"); + fprintf (f, "#include <errno.h>\n"); + fprintf (f, "#ifndef HAVE_BCOPY\n" + "#define bcopy(a,b,c) memcpy((b),(a),(c))\n" + "#endif /* !HAVE_BCOPY */\n\n"); + fprintf (f, "#ifdef RCSID\n" + "RCSID(\"%s generated from %s.xg with $KTH: output.c,v 1.56 1999/03/05 05:13:56 assar Exp $\");\n" + "#endif\n\n", filename, basename); +} + /* * open all files */ void -init_generate (char *filename) +init_generate (const char *filename) { char *tmp; char *fileuppr; func_list = listnew (); - tmp = (char *)emalloc (strlen (filename) + 17); - sprintf (tmp, "%s.h", filename); - headerfile = efopen (tmp, "w"); - fileuppr = strdup (filename); + asprintf (&tmp, "%s.h", filename); + if (tmp == NULL) + err (1, "malloc"); + eefopen (tmp, "w", &headerfile); + free (tmp); + + fileuppr = estrdup (filename); strupr (fileuppr); - fprintf (headerfile, "/* Generated from %s.xg */\n", filename); - fprintf (headerfile, "#ifndef _%s_\n" + fprintf (headerfile.stream, "/* Generated from %s.xg */\n", filename); + fprintf (headerfile.stream, "#ifndef _%s_\n" "#define _%s_\n\n", fileuppr, fileuppr); + fprintf (headerfile.stream, "#include <atypes.h>\n\n"); free (fileuppr); - sprintf (tmp, "%s.ydr.c", filename); - ydrfile = efopen (tmp, "w"); - fprintf (ydrfile, "/* Generated from %s.xg */\n", filename); - fprintf (ydrfile, "#include <%s.h>\n\n", filename); - fprintf (ydrfile, "#include <stdio.h>\n"); - fprintf (ydrfile, "#include <stdlib.h>\n"); - fprintf (ydrfile, "#include <sys/types.h>\n"); - fprintf (ydrfile, "#include <netinet/in.h>\n"); - fprintf (ydrfile, "#include <roken.h>\n"); - fprintf (ydrfile, "#ifndef HAVE_BCOPY\n" - "#define bcopy(a,b,c) memcpy((b),(a),(c))\n" - "#endif /* !HAVE_BCOPY */\n\n"); - - sprintf (tmp, "%s.cs.c", filename); - clientfile = efopen (tmp, "w"); - fprintf (clientfile, "/* Generated from %s.xg */\n", filename); - fprintf (clientfile, "#include \"%s.h\"\n\n", filename); - fprintf (clientfile, "#include \"%s.cs.h\"\n\n", filename); - fprintf (clientfile, "#include <stdio.h>\n"); - fprintf (clientfile, "#include <stdlib.h>\n"); - fprintf (clientfile, "#include <sys/types.h>\n"); - fprintf (clientfile, "#include <netinet/in.h>\n"); - fprintf (clientfile, "#include <roken.h>\n"); - fprintf (clientfile, "#ifndef HAVE_BCOPY\n" - "#define bcopy(a,b,c) memcpy((b),(a),(c))\n" - "#endif /* !HAVE_BCOPY */\n\n"); - - sprintf (tmp, "%s.ss.c", filename); - serverfile = efopen (tmp, "w"); - fprintf (serverfile, "/* Generated from %s.xg */\n", filename); - fprintf (serverfile, "#include \"%s.h\"\n\n", filename); - fprintf (serverfile, "#include \"%s.ss.h\"\n\n", filename); - fprintf (serverfile, "#include <stdio.h>\n"); - fprintf (serverfile, "#include <stdlib.h>\n"); - fprintf (serverfile, "#include <sys/types.h>\n"); - fprintf (serverfile, "#include <netinet/in.h>\n"); - fprintf (serverfile, "#include <roken.h>\n"); - fprintf (serverfile, "#ifndef HAVE_BCOPY\n" - "#define bcopy(a,b,c) memcpy((b),(a),(c))\n" - "#endif /* !HAVE_BCOPY */\n\n"); + asprintf (&tmp, "%s.ydr.c", filename); + if (tmp == NULL) + err (1, "malloc"); + eefopen (tmp, "w", &ydrfile); + generate_standard_c_prologue (ydrfile.stream, tmp, filename); + free (tmp); - sprintf (tmp, "%s.cs.h", filename); - clienthdrfile = efopen (tmp, "w"); - fprintf (clienthdrfile, "/* Generated from %s.xg */\n", filename); + asprintf (&tmp, "%s.cs.c", filename); + if (tmp == NULL) + err (1, "malloc"); + eefopen (tmp, "w", &clientfile); + generate_standard_c_prologue (clientfile.stream, tmp, filename); + fprintf (clientfile.stream, "#include \"%s.cs.h\"\n\n", filename); + free (tmp); - sprintf (tmp, "%s.ss.h", filename); - serverhdrfile = efopen (tmp, "w"); - fprintf (serverhdrfile, "/* Generated from %s.xg */\n", filename); - fprintf (serverhdrfile, "#include <rx/rx.h>\n"); + asprintf (&tmp, "%s.ss.c", filename); + if (tmp == NULL) + err (1, "malloc"); + eefopen (tmp, "w", &serverfile); + generate_standard_c_prologue (serverfile.stream, tmp, filename); + fprintf (serverfile.stream, "#include \"%s.ss.h\"\n\n", filename); + free (tmp); + asprintf (&tmp, "%s.cs.h", filename); + if (tmp == NULL) + err (1, "malloc"); + eefopen (tmp, "w", &clienthdrfile); + free (tmp); + fprintf (clienthdrfile.stream, "/* Generated from %s.xg */\n", filename); + fprintf (clienthdrfile.stream, "#include <rx/rx.h>\n"); + fprintf (clienthdrfile.stream, "#include \"%s.h\"\n\n", filename); + + asprintf (&tmp, "%s.ss.h", filename); + if (tmp == NULL) + err (1, "malloc"); + eefopen (tmp, "w", &serverhdrfile); + free (tmp); + fprintf (serverhdrfile.stream, "/* Generated from %s.xg */\n", filename); + fprintf (serverhdrfile.stream, "#include <rx/rx.h>\n"); + fprintf (serverhdrfile.stream, "#include \"%s.h\"\n\n", filename); + + asprintf (&tmp, "%s.td.c", filename); + if (tmp == NULL) + err (1, "malloc"); + eefopen (tmp, "w", &td_file); free (tmp); } void -close_generator (char *filename) +close_generator (const char *filename) { - char *fileupr = strdup (filename); + char *fileupr = estrdup (filename); strupr (fileupr); - fprintf (headerfile, "\n#endif /* %s */\n", fileupr); - efclose (headerfile); - efclose (clientfile); - efclose (serverfile); - efclose (clienthdrfile); - efclose (serverhdrfile); - efclose (ydrfile); + fprintf (headerfile.stream, "\n#endif /* %s */\n", fileupr); + eefclose (&headerfile); + eefclose (&clientfile); + eefclose (&serverfile); + eefclose (&clienthdrfile); + eefclose (&serverhdrfile); + eefclose (&ydrfile); + eefclose (&td_file); } /* @@ -1344,12 +1832,12 @@ close_generator (char *filename) */ void -generate_server_stub (Symbol *s, FILE *f, FILE *headerf) +generate_server_stub (Symbol *s, FILE *f, FILE *headerf, FILE *h_file) { fprintf (headerf, "int _%s%s(\nstruct rx_call *call);\n", package, s->name); - fprintf (headerf, "int %s%s(\nstruct rx_call *call\n", - package, s->name); + fprintf (headerf, "int %s%s%s(\nstruct rx_call *call\n", + prefix, package, s->name); listiter (s->u.proc.arguments, gen1, headerf); fprintf (headerf, ");\n\n"); @@ -1360,7 +1848,7 @@ generate_server_stub (Symbol *s, FILE *f, FILE *headerf) listiter (s->u.proc.arguments, gendeclare, f); fprintf (f, "\n"); listiter (s->u.proc.arguments, gendecodein, f); - fprintf (f, "_result = %s%s(", package, s->name); + fprintf (f, "_result = %s%s%s(", prefix, package, s->name); if (/* s->u.proc.splitp */ 1) { fprintf (f, "call"); if (!listemptyp (s->u.proc.arguments)) @@ -1368,15 +1856,23 @@ generate_server_stub (Symbol *s, FILE *f, FILE *headerf) } listiter (s->u.proc.arguments, genargs, f); fprintf (f, ");\n"); + fprintf (f, "if (_result) goto funcfail;\n"); listiter (s->u.proc.arguments, genencodeout, f); listiter (s->u.proc.arguments, genfree, f); fprintf (f, "return _result;\n"); - if (!listemptyp(s->u.proc.arguments)) - fprintf(f, "fail:\n" - "return rx_Error(call);\n"); - fprintf(f, "}\n\n"); + if (!listemptyp(s->u.proc.arguments)) { + fprintf(f, "fail:\n"); + listiter (s->u.proc.arguments, genfree, f); + fprintf(f, "return rx_Error(call);\n"); + + } + fprintf(f, "funcfail:\n" + "return _result;\n" + "}\n\n"); listaddtail (func_list, s); + if (s->u.proc.flags & TMULTI) + generate_multi (s, h_file); } static Bool @@ -1426,3 +1922,139 @@ generate_server_switch (FILE *c_file, "return rx_Error(call);\n" "}\n\n"); } + +static Bool +gentcpdump_decode (List *list, Listitem *item, void *arg) +{ + Argument *a = (Argument *)listdata (item); + FILE *f = (FILE *)arg; + + if (a->type->type == TPOINTER) + encode_type (a->name, a->type->subtype, f, ENCODE_MEM); + else + encode_type (a->name, a->type, f, ENCODE_MEM); + + fprintf (f, "++found;\n"); + return FALSE; +} + +/* + * + */ + +static Bool +gentcpdump_print (List *list, Listitem *item, void *arg) +{ + Argument *a = (Argument *)listdata (item); + FILE *f = (FILE *)arg; + + fprintf (f, "if (found > 0)\n\n" + "{ --found;\n"); + + if (a->type->type == TPOINTER) + display_type ("", a->name, a->type->subtype, f); + else + display_type ("", a->name, a->type, f); + + if (listnextp(item)) + fprintf (f, "printf(\",\");\n"); + + fprintf (f, "} else\n" + "goto failandquit;\n"); + + return FALSE; +} + +/* + * + */ + +void +generate_tcpdump_stub (Symbol *s, FILE *f) +{ + fprintf (f, "void %s%s_print(char *ptr, size_t *total_len)\n" + "{\n" + "int found = 0;\n", + package, s->name); + listiter (s->u.proc.arguments, gendeclare, f); + fprintf (f, "\n"); + + listiter (s->u.proc.arguments, gentcpdump_decode, f); + if (!listemptyp(s->u.proc.arguments)) + fprintf(f, "fail:\n"); + fprintf (f, "printf(\"{\");"); + listiter (s->u.proc.arguments, gentcpdump_print, f); + fprintf (f, "printf(\"}\\n\");"); + + fprintf (f, "\nreturn ptr;\n"); + if (!listemptyp(s->u.proc.arguments)) + fprintf(f, "failandquit:\n" + "printf(\"Error decoding paket\");\n" + "return NULL;"); + fprintf(f, "}\n\n"); +} + + +static Bool +gentcpdump_case (List *list, Listitem *item, void *arg) +{ + Symbol *s = (Symbol *)listdata (item); + FILE *f = (FILE *)arg; + + fprintf (f, "case %u:\n" + "printf(\"%s%s(\");\n" + "ret = %s%s_print(ptr, &total_len);\n" + "break;\n", + s->u.proc.id, + package, + s->name, + package, + s->name); + + return FALSE; +} + +/* + * generate tcpdump patches + */ + + +void +generate_tcpdump_patches(FILE *td_file, const char *filename) +{ + Type optype = {TULONG}; + + fprintf(td_file, "/* generated by $KTH: output.c,v 1.56 1999/03/05 05:13:56 assar Exp $ */\n\n"); + + fprintf (td_file, + "#include <stdio.h>\n" + "#include <stdlib.h>\n" + "#include \"%s.h\"\n", + filename); + + fprintf (td_file, "%stcpdump_print(const unsigned char *ptr," + "unsigned int len," + "unsigned char *bp2)\n" + "{\n" + "u_int32_t opcode;\n" + "size_t *total_len = len;\n" + "char *ret;\n", + package); + + encode_type ("opcode", &optype, td_file, DECODE_MEM); + + fprintf (td_file, "switch(opcode) {\n"); + + listiter (func_list, gentcpdump_case, td_file); + + fprintf (td_file, "default:\n" + "printf (\"Unknown opcode %%s->%%d\\n\", " + "package, opcode);\n" + "}\n" + "fail:\n" + "printf(\"Error decoding packet\\n\");\n" + "}\n\n"); + +} + + diff --git a/usr.sbin/afs/src/ydr/output.h b/usr.sbin/afs/src/ydr/output.h index 054da7bdf29..a67c1914fc7 100644 --- a/usr.sbin/afs/src/ydr/output.h +++ b/usr.sbin/afs/src/ydr/output.h @@ -1,6 +1,6 @@ -/* $OpenBSD: output.h,v 1.1.1.1 1998/09/14 21:53:27 art Exp $ */ +/* $OpenBSD: output.h,v 1.2 1999/04/30 01:59:19 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,27 +37,38 @@ * SUCH DAMAGE. */ -/* $KTH: output.h,v 1.7 1998/04/27 20:17:17 assar Exp $ */ +/* $KTH: output.h,v 1.12 1999/03/04 06:43:03 assar Exp $ */ #ifndef _OUTPUT_ #define _OUTPUT_ #include <stdio.h> #include <bool.h> +#include <eefile.h> void generate_header (Symbol *s, FILE *f); void generate_sizeof (Symbol *s, FILE *f); void generate_function (Symbol *s, FILE *f, Bool encodep); void generate_function_prototype (Symbol *s, FILE *f, Bool encodep); +void generate_printfunction (Symbol *s, FILE *f); +void generate_printfunction_prototype (Symbol *s, FILE *f); void generate_client_stub (Symbol *s, FILE *f, FILE *headerf); -void generate_server_stub (Symbol *s, FILE *f, FILE *headerf); +void generate_server_stub (Symbol *s, FILE *f, FILE *headerf, FILE *h_file); +void generate_tcpdump_stub (Symbol *s, FILE *f); void generate_server_switch (FILE *c_f, FILE *h_file); -void init_generate (char *filename); -void close_generator (char *filename); +void generate_tcpdump_patches(FILE *td_file, const char *filename); +void init_generate (const char *filename); +void close_generator (const char *filename); extern char *package; -extern FILE *headerfile, *clientfile, *serverfile, *clienthdrfile, - *serverhdrfile, *ydrfile; +extern char *prefix; + +extern fileblob headerfile, clientfile, serverfile, clienthdrfile, + serverhdrfile, ydrfile, td_file; + +extern char *error_function; + +extern int parse_errors; #endif /* _OUTPUT_ */ diff --git a/usr.sbin/afs/src/ydr/parse.y b/usr.sbin/afs/src/ydr/parse.y index 9ed3b67ee35..de59894f46e 100644 --- a/usr.sbin/afs/src/ydr/parse.y +++ b/usr.sbin/afs/src/ydr/parse.y @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,13 +39,13 @@ %{ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$Id: parse.y,v 1.1.1.1 1998/09/14 21:53:27 art Exp $"); +RCSID("$Id: parse.y,v 1.2 1999/04/30 01:59:19 art Exp $"); #endif #include <stdio.h> #include <list.h> #include <bool.h> -#include <mem.h> +#include <roken.h> #include "sym.h" #include "types.h" #include "output.h" @@ -69,12 +69,12 @@ void yyerror (char *); %token T_ENUM T_STRUCT T_CONST T_UNSIGNED T_ULONG T_INT T_CHAR T_STRING %token T_LONG T_TYPEDEF T_OPAQUE T_IN T_OUT T_INOUT T_SPLIT T_MULTI -%token T_SHORT T_USHORT T_UCHAR T_ASIS -%token <name> T_IDENTIFIER T_VERBATIM T_PACKAGE +%token T_SHORT T_USHORT T_UCHAR T_ASIS T_PROC +%token <name> T_IDENTIFIER T_VERBATIM T_PACKAGE T_PREFIX T_ERROR_FUNCTION %token <constant> T_CONSTANT %token <sym> T_IDCONST T_IDTYPE -%type <constant> constant opt_constant +%type <constant> constant opt_constant opt_proc %type <constant> param_type %type <sym> enumentry type_decl proc_decl %type <list> enumentries enumbody structbody memberdecls params @@ -94,16 +94,22 @@ specification: ; declaration: type_decl { - generate_header ($1, headerfile); - generate_sizeof ($1, headerfile); - generate_function ($1, ydrfile, TRUE); - generate_function_prototype ($1, headerfile, TRUE); - generate_function ($1, ydrfile, FALSE); - generate_function_prototype ($1, headerfile, FALSE); + generate_header ($1, headerfile.stream); + generate_sizeof ($1, headerfile.stream); + generate_function ($1, ydrfile.stream, TRUE); + generate_function_prototype ($1, headerfile.stream, TRUE); + generate_function ($1, ydrfile.stream, FALSE); + generate_function_prototype ($1, headerfile.stream, FALSE); + generate_printfunction ($1, ydrfile.stream); + generate_printfunction_prototype ($1, headerfile.stream); } | proc_decl { - generate_client_stub ($1, clientfile, clienthdrfile); - generate_server_stub ($1, serverfile, serverhdrfile); + generate_client_stub ($1, clientfile.stream, + clienthdrfile.stream); + generate_server_stub ($1, serverfile.stream, + serverhdrfile.stream, + headerfile.stream); + generate_tcpdump_stub ($1, td_file.stream); } ; @@ -111,6 +117,12 @@ type_decl : T_ENUM T_IDENTIFIER enumbody ';' { $$ = define_enum ($2, $3); } | T_STRUCT T_IDENTIFIER { define_struct($2); } structbody ';' { $$ = set_struct_body ($2, $4); } + | T_STRUCT type structbody ';' + { if($2->symbol && $2->symbol->type != TSTRUCT) + error_message (1, "%s is not a struct\n", + $2->symbol->name); + $$ = set_struct_body_sym ($2->symbol, $3); + } | T_TYPEDEF memberdecl ';' { $$ = define_typedef ($2); } | T_CONST T_IDENTIFIER '=' constant ';' @@ -119,16 +131,20 @@ type_decl : T_ENUM T_IDENTIFIER enumbody ';' flags: { $$ = TSIMPLE; } | T_SPLIT { $$ = TSPLIT; } - | T_MULTI { $$ = TSPLIT | TSIMPLE; } + | T_MULTI { $$ = TSPLIT | TSIMPLE | TMULTI; } + ; + +opt_proc: { $$ = 0; }/* empty */ + | T_PROC { $$ = 0; } ; -proc_decl: T_IDENTIFIER '(' params ')' flags '=' constant ';' +proc_decl: opt_proc T_IDENTIFIER '(' params ')' flags '=' constant ';' { $$ = (Symbol *)emalloc(sizeof(Symbol)); $$->type = TPROC; - $$->name = $1; - $$->u.proc.arguments = $3; - $$->u.proc.id = $7; - $$->u.proc.flags = $5; + $$->name = $2; + $$->u.proc.arguments = $4; + $$->u.proc.id = $8; + $$->u.proc.flags = $6; } ; @@ -149,12 +165,17 @@ param: param_type memberdecl param_type: T_IN { $$ = TIN; } | T_OUT { $$ = TOUT; } | T_INOUT { $$ = TINOUT; } + | { $$ = TIN; } ; directive: T_PACKAGE T_IDENTIFIER { package = $2; } + | T_PREFIX T_IDENTIFIER + { prefix = $2; } | T_VERBATIM - { fprintf (headerfile, "%s\n", $1); } + { fprintf (headerfile.stream, "%s\n", $1); } + | T_ERROR_FUNCTION T_IDENTIFIER + { error_function = $2; } ; enumbody: '{' enumentries '}' { $$ = $2; } @@ -179,105 +200,70 @@ memberdecl: T_ASIS memberdecl2 memberdecl2: type T_IDENTIFIER { $$ = createstructentry ($2, $1); } - | T_STRUCT type T_IDENTIFIER - { - $$ = createstructentry ($3, $2); - } | T_STRING T_IDENTIFIER '<' opt_constant '>' - { Type *t = (Type *)emalloc (sizeof(Type)); - t->type = TSTRING; - t->size = $4; - t->flags = 0; + { Type *t = create_type (TSTRING, NULL, $4, NULL, NULL, 0); + $$ = createstructentry ($2, t); + } + | T_STRING T_IDENTIFIER + { Type *t = create_type (TSTRING, NULL, 0, NULL, NULL, 0); $$ = createstructentry ($2, t); } | type T_IDENTIFIER '[' opt_constant ']' - { Type *t = (Type *)emalloc(sizeof(Type)); - t->type = TARRAY; - t->size = $4; - t->subtype = $1; - t->flags = 0; + { Type *t = create_type (TARRAY, NULL, $4, $1, NULL, 0); $$ = createstructentry ($2, t); } | type T_IDENTIFIER '<' opt_constant '>' - { Type *t = (Type *)emalloc(sizeof(Type)); - t->type = TVARRAY; - t->size = $4; - t->subtype = $1; - t->indextype = NULL; - t->flags = 0; + { Type *t = create_type (TVARRAY, NULL, $4, $1, NULL, 0); $$ = createstructentry ($2, t); } | type T_IDENTIFIER '<' type '>' - { Type *t = (Type *)emalloc(sizeof(Type)); - t->type = TVARRAY; - t->size = 0; - t->subtype = $1; - t->indextype = $4; - t->flags = 0; + { Type *t = create_type (TVARRAY, NULL, 0, $1, $4, 0); $$ = createstructentry ($2, t); } ; type: long_or_int - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TLONG; - $$->flags = 0; } + { $$ = create_type (TLONG, NULL, 0, NULL, NULL, 0); } | T_UNSIGNED - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TULONG; - $$->flags = 0; } + { $$ = create_type (TULONG, NULL, 0, NULL, NULL, 0); } | T_ULONG - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TULONG; - $$->flags = 0; } + { $$ = create_type (TULONG, NULL, 0, NULL, NULL, 0); } | T_UNSIGNED T_LONG - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TULONG; - $$->flags = 0; } + { $$ = create_type (TULONG, NULL, 0, NULL, NULL, 0); } | T_CHAR - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TCHAR; - $$->flags = 0; } + { $$ = create_type (TCHAR, NULL, 0, NULL, NULL, 0); } | T_UCHAR - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TUCHAR; - $$->flags = 0; } + { $$ = create_type (TUCHAR, NULL, 0, NULL, NULL, 0); } | T_UNSIGNED T_CHAR - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TUCHAR; - $$->flags = 0; } + { $$ = create_type (TUCHAR, NULL, 0, NULL, NULL, 0); } | T_SHORT - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TSHORT; - $$->flags = 0; } + { $$ = create_type (TSHORT, NULL, 0, NULL, NULL, 0); } | T_USHORT - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TUSHORT; - $$->flags = 0; } + { $$ = create_type (TUSHORT, NULL, 0, NULL, NULL, 0); } | T_UNSIGNED T_SHORT - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TUSHORT; - $$->flags = 0; } + { $$ = create_type (TUSHORT, NULL, 0, NULL, NULL, 0); } | T_STRING - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TSTRING; - $$->flags = 0; } + { $$ = create_type (TSTRING, NULL, 0, NULL, NULL, 0); } | T_OPAQUE - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TOPAQUE; - $$->flags = 0; } + { $$ = create_type (TOPAQUE, NULL, 0, NULL, NULL, 0); } | type '*' - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TPOINTER; - $$->subtype = $1; - $$->flags = 0; } + { $$ = create_type (TPOINTER, NULL, 0, $1, NULL, 0); } | T_IDTYPE - { $$ = (Type *)emalloc(sizeof(Type)); - $$->type = TUSERDEF; - $$->symbol = $1; - $$->flags = 0; + { $$ = create_type (TUSERDEF, $1, 0, NULL, NULL, 0); if ($$->symbol->type != TSTRUCT && $$->symbol->type != TENUM && $$->symbol->type != TTYPEDEF) - error_message ("%s used as a type\n", $$->symbol->name); + error_message (1, "%s used as a type\n", + $$->symbol->name); } + | T_STRUCT type + { + $$ = $2; + if ($$->symbol && $$->symbol->type != TSTRUCT) + error_message (1, "%s is not a struct\n", + $$->symbol->name); + } + | T_STRUCT T_IDENTIFIER + { $$ = create_type (TUSERDEF, define_struct($2), 0, NULL, + NULL, 0); + } ; long_or_int: T_LONG @@ -300,7 +286,7 @@ constant: T_CONSTANT { $$ = $1; } | T_IDCONST { Symbol *s = $1; if (s->type != TCONST) { - error_message ("%s not a constant\n", s->name); + error_message (1, "%s not a constant\n", s->name); } else $$ = s->u.val; } @@ -310,5 +296,5 @@ constant: T_CONSTANT { $$ = $1; } void yyerror (char *s) { - error_message ("%s\n", s); + error_message (1, "%s\n", s); } diff --git a/usr.sbin/afs/src/ydr/sym.h b/usr.sbin/afs/src/ydr/sym.h index b6ec90f24e7..6602af59c34 100644 --- a/usr.sbin/afs/src/ydr/sym.h +++ b/usr.sbin/afs/src/ydr/sym.h @@ -1,6 +1,6 @@ -/* $OpenBSD: sym.h,v 1.1.1.1 1998/09/14 21:53:27 art Exp $ */ +/* $OpenBSD: sym.h,v 1.2 1999/04/30 01:59:20 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ * SUCH DAMAGE. */ -/* $KTH: sym.h,v 1.5 1998/02/19 05:15:52 assar Exp $ */ +/* $KTH: sym.h,v 1.6 1999/03/04 06:43:03 assar Exp $ */ #ifndef _SYM_ #define _SYM_ @@ -54,7 +54,7 @@ typedef enum TUNDEFINED, TSTRUCT, TENUM, TCONST, TENUMVAL, TTYPEDEF, TPROC } SymbolType; -enum { TSPLIT = 1, TSIMPLE = 2}; +enum { TSPLIT = 1, TSIMPLE = 2, TMULTI = 4}; typedef struct { SymbolType type; diff --git a/usr.sbin/afs/src/ydr/symbol.c b/usr.sbin/afs/src/ydr/symbol.c index 2c1d67590b0..7866b6b4b3d 100644 --- a/usr.sbin/afs/src/ydr/symbol.c +++ b/usr.sbin/afs/src/ydr/symbol.c @@ -1,6 +1,6 @@ -/* $OpenBSD: symbol.c,v 1.1.1.1 1998/09/14 21:53:27 art Exp $ */ +/* $OpenBSD: symbol.c,v 1.2 1999/04/30 01:59:20 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,15 +39,15 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: symbol.c,v 1.4 1998/02/19 05:16:28 assar Exp $"); +RCSID("$KTH: symbol.c,v 1.7 1999/02/13 04:44:16 assar Exp $"); #endif #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <mem.h> #include "sym.h" #include <hash.h> +#include <roken.h> static Hashtab *hashtab; @@ -102,8 +102,7 @@ findsym (char *name) return (Symbol *)hashtabsearch (hashtab, (void *)&tmp); } -#ifdef notyet -static Bool +static Bool __attribute__ ((unused)) printsymbol (void *ptr, void *arg) { Symbol *s = (Symbol *)ptr; @@ -134,7 +133,6 @@ printsymbol (void *ptr, void *arg) return FALSE; } -#endif void symiterate (Bool (*func)(void *, void *), void *arg) diff --git a/usr.sbin/afs/src/ydr/types.c b/usr.sbin/afs/src/ydr/types.c index 0ae0e902a39..eb674c0aa95 100644 --- a/usr.sbin/afs/src/ydr/types.c +++ b/usr.sbin/afs/src/ydr/types.c @@ -1,6 +1,6 @@ -/* $OpenBSD: types.c,v 1.1.1.1 1998/09/14 21:53:27 art Exp $ */ +/* $OpenBSD: types.c,v 1.2 1999/04/30 01:59:20 art Exp $ */ /* - * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -39,11 +39,11 @@ #ifdef HAVE_CONFIG_H #include <config.h> -RCSID("$KTH: types.c,v 1.3 1998/02/19 05:17:08 assar Exp $"); +RCSID("$KTH: types.c,v 1.7 1999/03/19 06:06:30 lha Exp $"); #endif #include <stdio.h> -#include <mem.h> +#include <roken.h> #include "types.h" #include "lex.h" @@ -55,7 +55,7 @@ define_const (char *name, int value) s = addsym (name); if (s->type != TUNDEFINED) { - error_message ("Redeclaration of %s\n", s->name); + error_message (1, "Redeclaration of %s\n", s->name); return NULL; } s->type = TCONST; @@ -71,7 +71,7 @@ define_enum (char *name, List *list) s = addsym (name); if (s->type != TUNDEFINED) { - error_message ("Redeclaration of %s\n", s->name); + error_message (1, "Redeclaration of %s\n", s->name); return NULL; } s->type = TENUM; @@ -86,8 +86,9 @@ define_struct (char *name) s = addsym (name); - if (s->type != TUNDEFINED) { - error_message ("Redeclaration of %s\n", s->name); + if (s->type != TSTRUCT && s->type != TUNDEFINED) { + error_message (1, "Redeclaration of %s as a different type\n", + s->name); return NULL; } s->type = TSTRUCT; @@ -96,17 +97,23 @@ define_struct (char *name) } Symbol * +set_struct_body_sym (Symbol *s, List *list) +{ + s->u.list = list; + return s; +} + +Symbol * set_struct_body (char *name, List *list) { Symbol *s; s = findsym(name); if (s == NULL) { - error_message("struct %s not declared", name); + error_message(1, "struct %s not declared", name); return NULL; } - s->u.list = list; - return s; + return set_struct_body_sym (s, list); } Symbol * @@ -117,7 +124,7 @@ define_typedef (StructEntry *entry) s = addsym (entry->name); if (s->type != TUNDEFINED) { - error_message ("Redeclaration of %s\n", s->name); + error_message (1, "Redeclaration of %s\n", s->name); return NULL; } s->type = TTYPEDEF; @@ -136,7 +143,7 @@ define_proc (char *name, List *args, unsigned id) s = addsym (name); if (s->type != TUNDEFINED) { - error_message ("Redeclaration of %s\n", s->name); + error_message (1, "Redeclaration of %s\n", s->name); return NULL; } s->type = TPROC; @@ -153,7 +160,7 @@ createenumentry (char *name, int value) s = addsym (name); if (s->type != TUNDEFINED) { - error_message ("Redeclaration of %s\n", s->name); + error_message (1,"Redeclaration of %s\n", s->name); return NULL; } s->type = TENUMVAL; @@ -172,5 +179,21 @@ createstructentry (char *name, Type *type) return e; } -Symbol * -define_proc (char *name, List *params, unsigned id); +struct Type * +create_type (TypeType type, Symbol *symbol, unsigned size, + Type *subtype, Type *indextype, int flags) +{ + Type *t; + + t = emalloc(sizeof(*t)); + + t->type = type; + t->symbol = symbol; + t->size = size; + t->subtype = subtype; + t->indextype = indextype; + t->flags = flags; + + return t; +} + diff --git a/usr.sbin/afs/src/ydr/types.h b/usr.sbin/afs/src/ydr/types.h index ed0305dbcbb..cc1b56e1a90 100644 --- a/usr.sbin/afs/src/ydr/types.h +++ b/usr.sbin/afs/src/ydr/types.h @@ -1,4 +1,4 @@ -/* $OpenBSD: types.h,v 1.1.1.1 1998/09/14 21:53:28 art Exp $ */ +/* $OpenBSD: types.h,v 1.2 1999/04/30 01:59:20 art Exp $ */ /* * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). @@ -37,10 +37,10 @@ * SUCH DAMAGE. */ -/* $KTH: types.h,v 1.5 1998/05/02 02:37:30 assar Exp $ */ +/* $KTH: types.h,v 1.8 1999/03/19 06:06:52 lha Exp $ */ -#ifndef _TYPES_ -#define _TYPES_ +#ifndef _YDR_TYPES_ +#define _YDR_TYPES_ #include "sym.h" @@ -78,10 +78,14 @@ typedef struct { Symbol *define_const (char *name, int value); Symbol *define_enum (char *name, List *list); Symbol *define_struct (char *name); -Symbol *set_struct_body(char *name, List *list); +Symbol *set_struct_body_sym (Symbol *s, List *list); +Symbol *set_struct_body (char *name, List *list); Symbol *define_typedef (StructEntry *entry); Symbol *define_proc (char *name, List *args, unsigned id); Symbol *createenumentry (char *name, int val); StructEntry *createstructentry (char *name, Type *type); +struct Type *create_type (TypeType type, Symbol *symbol, unsigned size, + Type *subtype, Type *indextype, int flags); -#endif /* _TYPES_ */ + +#endif /* _YDR_TYPES_ */ diff --git a/usr.sbin/afs/vos/Makefile b/usr.sbin/afs/vos/Makefile index f4f249c451c..af6275fb30c 100644 --- a/usr.sbin/afs/vos/Makefile +++ b/usr.sbin/afs/vos/Makefile @@ -1,7 +1,11 @@ PROG = vos MAN = BINDIR = /usr/sbin -SRCS = vos.c arlalib.c fs_lib.c +SRCS = vos.c arlalib.c fs_lib.c vos_common.c vos_createentry.c \ + vos_createvolume.c vos_dump.c vos_endtrans.c vos_examine.c \ + vos_listpart.c vos_listvldb.c vos_listvol.c vos_partinfo.c \ + vos_status.c vos_syncsite.c + LDADD += -lkafs DPADD += ${LIBKAFS} |