/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos72V src/bos/kernel/sys/liveUpdate.h 1.39                            */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* Restricted Materials of IBM                                            */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2014,2020              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/* @(#)54       1.39  src/bos/kernel/sys/liveUpdate.h, liveupdate, bos72V, v2020_28A5 7/2/20 08:22:29 */

#ifndef _LIVEUPDATE_H_
#define _LIVEUPDATE_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/wlm.h>

typedef enum {
    KLU_START_ORIG,		/* Start Live Update on Original*/
    KLU_START_SURR,		/* Start Live Update on Surrogate*/
    KLU_STOP_ORIG,		/* Stop Live Update on Original	*/
    KLU_STOP_SURR,		/* Stop Live Update on Surrogate*/
    KLU_ERR_ORIG,		/* Live Update Error State	*/
    KLU_ERR_SURR,		/* Live Update Error State 
				   on Surrogate*/
                /* Checkpoint state defines */
    KLU_IN_CHKPNT,          /* Live Update Checkpoint State */
    KLU_STATE_QUERY,		/* Live Update query state 	*/
    KLU_STATE_CLEAN,		/* Live Update Clean State	*/
    KLU_DONE_SURR,		/* Done with sucess		*/
    KLU_STATE_RESET_ORIG,	/* Reset the kernel state	*/
    KLU_STATE_RESET_SURR,	/* Reste kernel state-surr	*/
    KLU_BLOCK_MNT,		/* Block the mounts		*/
    KLU_UNBLOCK_MNT,		/* Unblock the mount operations	*/
    KLU_MNT_QRY,		/* Obtain the number of pending */
				/* mounts/unmounts operations   */
    KLU_PAUSE,                  /* Request a pause operation    */
    KLU_RESUME,                 /* Request a resume             */
    KLU_PROG_QUERY,             /* Request progress             */
                                /* Returns the number blocked   */
                                /* requests.                    */
                                /* Returns -1 in case of error  */
    KLU_SET_PRINCIPAL,		/* Set Principal flag		*/
    KLU_UNSET_PRINCIPAL,	/* Unset Principla Flag		*/
    KLU_SET_ERROR,              /* Can be called to set error   */
                                /* for either orig. or surr.    */
    KLU_GET_UNSAFE_LKE,         /* Get the List of unsafe KEs   */
    KLU_GET_LKE,                /* Get the List of KEs          */
    KLU_CHK_U_LKE_STATUS,       /* Check if Unsafe KE list changed */
    KLU_CHK_LKE_STATUS,         /* Check if KE list changed     */
    KLU_CHROOTENV_SET,          /* LPAR is running in chrooted env */
    KLU_CHROOTENV_QUERY,        /* Check if running chroot'ed   */
    KLU_SET_LOG_FILE,           /* set log file                 */
    KLU_SET_POST_MCR,           /* Set POST_MCR bit             */
    KLU_UNSET_POST_MCR,         /* Unset POST_MCR bit           */
    KLU_REG_KHANDLER,           /* register kernel handler for  */ 
                                /* lvupdate                     */
    KLU_UNREG_KHANDLER,         /* unregister kernel handler for*/ 
                                /* lvupdate                     */   
    KLU_REG_KHANDLER_ORIG,      /* register kernel handler for  */ 
                                /* olvupdate                    */
    KLU_UNREG_KHANDLER_ORIG,    /* unregister kernel handler for*/
                                /* olvupdate                    */ 
    KLU_REG_KHANDLER_SURR,      /* register kernel handler for  */ 
                                /* slvupdate                    */
    KLU_UNREG_KHANDLER_SURR,    /* unregister kernel handler for*/ 
                                /* slvupdate                    */   
    KLU_REG_FORKHANDLER,        /* register kernel handler for  */ 
                                /* forked commands              */
    KLU_IN_MCR,                 /* mcr starts                   */
    KLU_OUT_MCR,                /* mcr ends                     */    
    KLU_SET_FAIL_ORIG,          /* clean up failed on orig, 
				   or olvupdate killed          */
    KLU_SET_FAIL_SURR,          /* clean up failed on surr, 
				   or slvupdate killed          */
    KLU_IN_FORK,                /* fork cmd entered             */
    KLU_STATUS_QUERY,           /* query if LVUPD_INMCR 
                                   or LVUPD_INFORK              */
    KLU_DONE_WARN_SURR,         /* Done with non-fatal errors
                                   during cleanup               */
    KLU_LOCK,                   /* Take LKU lock                */
    KLU_UNLOCK,                 /* Release LKU lock             */
    KLU_WARN_MCR_SURR,          /* MCR memory transfer          */
    KLU_STIME_QUERY, 		/* Query LKU system time        */
    KLU_STIME_SET, 		/* Set LKU system time delta    */
                                /* after restart of processes   */
    KLU_SET_MC_FLAGS,           /* Set millicode change flags   */
    KLU_GET_SUPPORTED_COMP_VERSIONS, /* Read lku_supported_versions */
    KLU_SET_COMP_VERSION,       /* store the common component version */
    KLU_GET_COMP_VERSION,       /* get the common component version */
    KLU_GET_TRC_BUFSZ,		/* get total size of trace buffers */
    KLU_READ_ERR_BUF,           /* read the LKU kernel err buf     */    
    KLU_WRITE_ERR_BUF,          /* write to the LKU kernel err buf */
    KLU_WARN_MCR_ORIG,          /* MCR memory transfer          */
    KLU_GET_KDB_AVAIL,          /* get kdb_avail kernel var     */
    KLU_UNSET_WARN_SURR,        /* unset the MCR warning status */
    KLU_FAIL,                   /* Fail LKU due to autofs mount */
    KLU_GET_CAPABILITIES,       /* read capabilities registered in kernel */
    KLU_CWD_MOBILE,             /* get mobile flag value of the current working directory */
    KLU_WRITE_ERR_BUF_NO_DUP,   /* write to the LKU kernel err buf without duplicate */
    KLU_CHECK_PKS_ENABLED       /* check if Partition Key Store is enabled */
} lvup_oper_t;

typedef enum {
    KLU_ST_INIT,		/* Default State		        */
    KLU_ST_STARTED_ORIG,	/* Live Update started on Original      */
    KLU_ST_STARTED_SURR,	/* Live Update started on Surrogate     */
    KLU_ST_STOPPED_ORIG,	/* Live Update stopped on Original      */
    KLU_ST_STOPPED_SURR,	/* Live Update stopped on Surrogate     */
    KLU_ST_ERR_ORIG,		/* Live Update Error State on Original  */
    KLU_ST_ERR_SURR,		/* Live Update Error State on Surrogate */
    KLU_ST_DONE_SURR,		/* Done with sucess                     */
    KLU_ST_FAIL_ORIG,		/* Live Update Failure State on Original  */
    KLU_ST_FAIL_SURR		/* Live Update Failure State on Surrogate */
} lvup_state_t;

typedef enum {
    LVUP_PROCFS_BLK,            /* procfs open count                    */
    LVUP_BLKCNT_MAX             /* max index of count                   */
} lvup_fastblk_cnt_t;

#define LVUP_BLK_STR(i) \
    ((i==LVUP_PROCFS_BLK)?      "There is outstanding open on procfs":                          \
    "UNKNOWN")

#define KLU_CAPABILITIES_SIZE    1 /* size of KLU_CAPABILITIES */

/* Live Update kernel capabilities flags
 *  Caution:
 *  - do never suppress any value or change the position of an existing flag
 *    in klu_capabilities_t
 *  - update INIT_CAPABILITIES_MAP after each new add in klu_capabilities_t
 *    to define the new capability at the same position as in
 *    klu_capabilities_t.
 *    Example KLU_AUTOFS on the first, KLU_KERBEROS on the second
 *    and so on ...
 *  - for any added value in klu_capabilities_t, if the corresponding value
 *    in INIT_CAPABILITIES_MAP = -1, that means capability is not supported
 *  - the value in INIT_CAPABILITIES_MAP is defined as followed:
 *     - '-1',  if the capability is not supported in the kernel.
 *     - Any other values (different from '-1'), if the capability is
 *       supported by the kernel
 *  - the capability flags are grouped by 64 words.
 */
typedef enum {
    KLU_AUTOFS          = 0,    /* support AUTOFS  (bit 0, first word) */
    KLU_KERBEROS        = 1,    /* support KLU_KERBEROS  (bit 1, first word) */
    KLU_ENC_LVS         = 2,    /* support encrypted LVs (bit 2, first word) */
    KLU_PKS             = 3     /* support PKS (bit 3, first word) */
} klu_capabilities_t;

#define INIT_CAPABILITIES_MAP {\
    KLU_AUTOFS, KLU_KERBEROS, -1, -1, -1, -1, -1, -1,\
    -1, -1, -1, -1, -1, -1, -1, -1,\
    -1, -1, -1, -1, -1, -1, -1, -1,\
    -1, -1, -1, -1, -1, -1, -1, -1,\
    -1, -1, -1, -1, -1, -1, -1, -1,\
    -1, -1, -1, -1, -1, -1, -1, -1,\
    -1, -1, -1, -1, -1, -1, -1, -1,\
    -1, -1, -1, -1, -1, -1, -1, -1\
}

/* Manage process lists */
#define PROC_ADD	0x1
#define PROC_REMOVE	0x2
#define PROC_QUERY	0x3

/* Live Update Status flags */
#define LVUP_BIT_PRINCIPAL	0x1
#define LVUP_BIT_ORIG		0x2
#define LVUP_BIT_SURROGATE	0x4
#define LVUP_BIT_ERROR		0x8
#define LVUP_BIT_BLOCK_MOUNT	0x10
#define LVUP_BIT_IN_CHKPNT      0x20
#define LVUP_PAUSE_OPER         0x40
#define LVUP_RESUME_OPER        0x80
#define LVUP_U_LLKE_TAKEN       0x100 /* List of Unsafe Loaded KEs taken */
#define LVUP_A_LLKE_TAKEN       0x200 /* List of All Loaded KEs taken */
#define LVUP_BIT_POST_MCR       0x400 /* MCR exited */
#define LVUP_BIT_IN_MCR         0x800 /* inside MCR */
#define LVUP_BIT_IN_FORK        0x1000 /* inside forked command, such as mirrorvg */
#define LVUP_CLEANUP_WARNING    0x2000 /* non-fatal error during surrogate cleanup */
#define LVUP_BIT_LOCK           0x4000 /* lock taken by first lvupdate process */
#define LVUP_MCR_WARNING        0x8000 /* non-fatal error during mcr */
#define LVUP_AIMC_CHANGED       0x10000 /* arch-independent millicode change */
#define LVUP_ADMC_CHANGED       0x20000 /* arch-dependent millicode change */
#define LVUP_BIT_ORIG_DONE      0x40000 /* set only on original post successful Live Update */
#define LVUP_BIT_FAIL           0x80000 /* Bit set to fail Live Update */

/*		Prototypes							*/

typedef enum {
    ID_PROC,
    ID_THREAD,
    ID_SHM,
    ID_SEM,
    ID_MSG,
    ID_RT_SHM,
    ID_RT_SEM,
    ID_RT_MSG
} lvup_id_t;

/* system calls */
extern int liveupdate_operations(lvup_oper_t cmd, int *query, void *data);
extern int lvup_setnextID(lvup_id_t type, id_t id);
extern int lvup_stopbase(void);
extern int lvup_chckpnt_status(int cmd, void *cmdp);
extern int klvup_fast_status(int cmd, unsigned int idx);

#define LIVE_UPDATE_TRY     0x1 /* Try Checkpoint       */
#define LIVE_UPDATE_DENY    0x2 /* Deny Checkpoint      */
#define LIVE_UPDATE_ALLOW   0x4 /* Allow Checkpoint     */
#define LIVE_UPDATE_CLEAR   0x8 /* Clear Checkpoint     */
#define LIVE_UPDATE_STATUS  0x10 /* Get Live Update status */
#define LIVE_UPDATE_FAIL    0x20 /* Fail Live Update */
#define LIVE_UPDATE_ERROR   0x40 /* Check if LVUP_BIT_ERROR status bit set */

extern int lvup_get_rdir(char *rdir, int *len, int flag);

/* lvup_get_rdir() flag values */
#define LVUP_USER_GET_RDIR  0x0 /* Get root dir from user space */
#define LVUP_KERN_GET_RDIR  0x1 /* Get root dir from kernel */

/*
 * Live Update Kernel extensions support
 */
#define LU_KE_SAFE      0x1     /* Check Kernel Extension is safe   */
#define LU_KE_SAFE_ALL  0x2     /* Check all Kernel Extensions safe */
#define LU_KE_GET       0x4     /* Get the list of all Kernel Ext.  */

/* System time data to be checkpointed and restored */
typedef struct lvup_systime {
    unsigned int version;	  /* Version number for this struct      */
    time_t lvup_lbolt;		  /* lbolt + lvup_lbolt_delta            */
} lvup_systime_t;

typedef struct lvup_ke_obj {
    char ke_name[256];
    unsigned int flag;
} lvup_ke_obj_t;
extern LiveUpdateKExt(unsigned int, unsigned int *,lvup_ke_obj_t *);

/* Special file systems mounted from boot disk during Live Update */
#define LVUP_BASE       "/old/lvup_base"
#define LVUP_BASE_VAR   "/old/lvup_base/var"

/* Syscall to checkpoint/restart wlm data */
extern int lvup_wlm(int, struct wlm_info *, void *, int *, int);

extern int lvup_discover_processes(void);

#ifdef _KERNEL
extern void klvupdate_init(void );
extern void klvupdate_clean(void );

extern int klvup_startedOrig(void);
extern int klvup_startedSurr(void);
extern int lvup_status(void);
extern int klvup_chrooted(void); 
extern int klvup_progress(void);
extern int klvup_SetState(lvup_oper_t , lvup_state_t *);
/* Mount checks */
extern int klvup_mnt_hold(void);
extern void klvup_mnt_rele(void);

extern int klvup_chckpnt_status(int, char *, void *);
extern int klvup_baseProcsOps(int, pid_t);
extern int klvup_restartExitOps(int, unsigned short, pid_t);

extern int klvup_setnextID(lvup_id_t type, id_t id);
extern int klvup_getnextID(lvup_id_t type, id_t *id);
extern void klvup_freeIDs(void);
typedef enum {
    KLVUP_LOG_ERROR,
    KLVUP_LOG_DEBUG
} klvup_log_sev_t;
extern int klvup_err_list(klvup_log_sev_t, char *, va_list);
extern int klvup_err_list_internal(klvup_log_sev_t, char *, va_list);
extern int klvup_log(klvup_log_sev_t, char *, ...);
extern int klvup_log_internal(klvup_log_sev_t, char *, ...);
extern int klvup_process_in_chkpt(pid_t);

/* kext operation */
extern int klvup_ke_ops(lvup_oper_t, int *, void **);
extern int klvup_get_unsafe_lke_in_arr(int *, lvup_ke_obj_t **);
extern int klvup_get_lke_in_arr(int *, lvup_ke_obj_t **);
extern int klvup_write_errbuf(char *, int);

/* versioning */
extern int klvup_get_comp_version(int);

/* global variables */

/*
 * klvup_base_active indicates if liveupdate surrogate boot is in progress.
 *
 * It's an atomic variable, whose only possible values are 0 and 1. Once it
 * is at 0, it stays at 0 forever.
 * It is only set to 1 when the surrogate node boots during liveupdate. Once
 * the surrogate node is ready, it's cleared at 0, and stays at 0 forever.
 * When a node is not involved in liveupdate, then it is at 0 all the time.
 *
 * Therefore, to avoid paying the price of an atomic read for the most
 * common case (i.e. value is 0), we try a simple load first. We may
 * wrongly read a 1, but it is then corrected by the atomic read, and we
 * only pay the price during preparation of the surrogate node.
 */
extern int klvup_base_active;		
#define IS_BASE_ACTIVE() \
        (klvup_base_active ? fetch_and_nop(&klvup_base_active) : 0)

/* fetch_and_nop is not available to kernel extentions, so they will have
 * to use the older slower approach.
 */
#define KE_IS_BASE_ACTIVE() 	fetch_and_add(&klvup_base_active, 0)

#endif /* _KERNEL */

#ifdef __cplusplus
}
#endif

#endif /* _LIVEUPDATE_H_ */
