/*
 *	Copyright (C) 1989-1998 Softway Pty Ltd, Sydney Australia.
 *	All Rights Reserved.
 */

/*
 * Copyright (c) 1997-1999 Sun Microsystems, Inc.
 */

/*
 *	This is unpublished proprietary source code of Softway Pty Ltd.
 *	The contents of this file are protected by copyright laws and
 *	international copyright treaties, as well as other intellectual
 *	property laws and treaties.  These contents may not be extracted,
 *	copied,	modified or redistributed either as a whole or part thereof
 *	in any form, and may not be used directly in, or to assist with,
 *	the creation of derivative works of any nature without prior
 *	written permission from Softway Pty Ltd.  The above copyright notice
 *	does not evidence any actual or intended publication of this file.
 */
/*
 *	RCE System Kernel Hooks header.
 */

#ifndef	_SYS_RCE_H
#define	_SYS_RCE_H

#pragma ident	"@(#)rce.h	1.12	99/02/10 SMI"

#ifdef	__cplusplus
extern "C" {
#endif

#include	<sys/types.h>
#include	<sys/systm.h>
#include	<sys/cred.h>
#include	<sys/vfs.h>
#include	<sys/priocntl.h>

/*
 * The purpose of SHR_IF_MAJOR and SHR_IF_MINOR are to ensure consistency
 * of the version of RCE interface mechanism used. We want to ensure
 * that the interface that a vendor uses to compile their kernel with
 * is the same version (or compatible with) that used to compile the
 * RCE module/library.
 * _SRM_INTERFACE_VERSION is a string "SHR_IF_MAJOR.SHR_IF_MINOR".
 *
 * At initialisation RCE checks the content of _srm_interface_version
 * and may require that a certain version is current or may adapt how it
 * presents the interface based on what the kernel expects.
 *
 * NOTE: Subsequent minor level versions at the same major level are
 * expected to be backwards compatible with the preceeding minor level.
 * However, no compatibility is guaranteed between different major levels.
 */

#define	SHR_IF_MAJOR	5
#define	SHR_IF_MINOR	0

#define	SHR_STRINGIT(s)	#s
#define	SHR_MK_VERSION(m, n)	SHR_STRINGIT(m) "." SHR_STRINGIT(n)
#define	_SRM_INTERFACE_VERSION	\
		SHR_MK_VERSION(SHR_IF_MAJOR, SHR_IF_MINOR)

extern const char	_srm_interface_version[];


/*
 *	Prototypes for all the SRM hooks called from the mainline
 *	kernel code.
 */

#include	<sys/proc.h>

struct as;

typedef struct srm_domain_ops {
	int	(*limitdisk)(vfs_t *, uid_t, blkcnt_t, int, int,
					blkcnt_t *, cred_t *);
	int	(*chownfile)(vfs_t *, uid_t, uid_t, blkcnt_t, int, int,
					long, cred_t *);
	int	(*umask)(void);
	int	(*setattr)(long, mode_t *);
} srm_domain_ops_t;

typedef struct rce_interface {
	int	(*start)(id_t, int);
	int	(*limitmemory)(size_t, struct as *, int);
	void	(*exit)(proc_t *);
	void	(*flush)(ulong_t);
	int	(*proccreate)(proc_t *, int);
	void	(*procdestroy)(proc_t *);
	void	(*pcntup)(kthread_id_t);
	void	(*pcntdn)(kthread_id_t);
	void	(*rdwr)(struct vnode *, int, int);
	void	(*setuid)(int, cred_t *);
	void	(*swtch)(kthread_id_t, kthread_id_t);
	void	(*lwpfail)(proc_t *, kthread_id_t);
	void	(*lwpexit)(proc_t *, kthread_id_t);
	int	(*lwpnew)(proc_t *);
	int	(*mode)(struct vnode *, uid_t, uid_t, mode_t, mode_t,
					cred_t *);
	int	(*request)(void *);
	int	(*classchange)(kthread_id_t, cred_t *, pcparms_t *);
	srm_domain_ops_t	*domain;
} rce_interface_t;


/*
 * The rce_ops pointer is NULL while the RCE
 * module is not loaded or has not initialised yet. During
 * initialisation it is set to point at a structure populated
 * with addresses of the hooks.
 */

extern volatile rce_interface_t	*rce_ops;


#define	SHR_SAFE	rce_ops

#define	SHR_START(c, p)	(SHR_SAFE ? rce_ops->start((c), (p)) : 0)


#define	SHR_LIMITMEMORY(n, a, l) \
	(SHR_SAFE ? rce_ops->limitmemory((n), (a), (l)) : 0)


#define	SHR_EXIT(p)	(SHR_SAFE ? rce_ops->exit((p)) : (void)0)

#define	SHR_FLUSH(a)	(SHR_SAFE ? rce_ops->flush((a)) : (void)0)

#define	SHR_PROCCREATE(p, f) \
		(SHR_SAFE ? rce_ops->proccreate((p), (f)) : 0)

#define	SHR_PROCDESTROY(p) \
		(SHR_SAFE ? rce_ops->procdestroy((p)) : (void)0)

#define	SHR_PCNTUP(t)	(SHR_SAFE ? rce_ops->pcntup((t)) : (void)0)

#define	SHR_PCNTDN(t)	(SHR_SAFE ? rce_ops->pcntdn((t)) : (void)0)

#define	SHR_RDWR(v, m, n) \
		(SHR_SAFE ? rce_ops->rdwr((v), (m), (n)) : (void)0)

#define	SHR_SETUID(e, c) \
		(SHR_SAFE ? rce_ops->setuid((e), (c)) : (void)0)

#define	SHR_SWTCH(t, n) \
		(SHR_SAFE ? rce_ops->swtch((t), (n)) : (void)0)


#define	SHR_LWPFAIL(p, t) \
		(SHR_SAFE ? rce_ops->lwpfail((p), (t)) : (void)0)

#define	SHR_LWPEXIT(p, t) \
		(SHR_SAFE ? rce_ops->lwpexit((p), (t)) : (void)0)

#define	SHR_LWPNEW(p)	(SHR_SAFE ? rce_ops->lwpnew((p)) : 0)
#define	SHR_MODE(v, u, g, m, n, c) \
	(SHR_SAFE ? rce_ops->mode((v), (u), (g), (m), (n), (c)) : (n))

#define	SHR_REQUEST(a)	(SHR_SAFE ? rce_ops->request((a)) : -1)

#define	SHR_CLASSCHANGE(t, c, p) \
	(SHR_SAFE ? rce_ops->classchange((t), (c), (p)) : 0)


/*
 * File systems domain hooks.
 */
#define	SRM_DSAFE	(SHR_SAFE && rce_ops->domain)

#define	SHR_LIMITDISK(v, u, n, b, l, s, c) \
	(SRM_DSAFE ? \
	rce_ops->domain->limitdisk((v), (u), (n), (b), (l), (s), (c)) : 0)

#define	SHR_CHOWNFILE(v, w, u, n, b, f, m, c) \
	(SRM_DSAFE ? \
	rce_ops->domain->chownfile((v), (w), (u), (n), (b), (f), (m), (c)) : 0)

#define	SHR_UMASK()	(SRM_DSAFE ? rce_ops->domain->umask() : 0)

#define	SHR_SETATTR(w, m) \
	(SRM_DSAFE ? rce_ops->domain->setattr((w), (m)) : 0)

#define	SHR_ACTIVE	(rce_ops != NULL)

/*
 * These control the behaviour of limit enforce/update functions:
 *	SHR_LIMITDISK()
 *	SHR_LIMITMEMORY()
 */
#define	LI_ENFORCE	(1<<0)	/* return error if denied & don't update */
#define	LI_UPDATE	(1<<1)	/* update allocation record */
#define	LI_ALLOC	(1<<2)	/* allocation increase */
#define	LI_FREE		(1<<3)	/* allocation decrease */

/*
 * These are for the flag argument to SHR_PROCCREATE():
 */
#define	SH_FORK_ALL	(1<<0)	/* A fork() which duplicates all threads */
#define	SH_FORK_POSIX	(1<<1)	/* A fork() duplicating just current thread */

/*
 * This is for the flag argument to SHR_PROCCREATE():
 * Used in combination with SH_FORK_ALL or SH_FORK_POSIX.
 */
#define	SH_FORK_V	(1<<7)	/* A vfork() */

/*
 * This is for the argument to SHR_FLUSH:
 * Used to notify SRM that the system is going to be suspended or resumed.
 */
#define	SH_CPR		(-1UL)

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_RCE_H */
