Print this page
    
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/sys/ipc_impl.h
          +++ new/usr/src/uts/common/sys/ipc_impl.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright 2016, Joyent, Inc.
  24   24   */
  25   25  
  26   26  #ifndef _IPC_IMPL_H
  27   27  #define _IPC_IMPL_H
  28   28  
  29   29  #include <sys/types.h>
  30   30  #include <sys/ipc.h>
  31   31  #include <sys/mutex.h>
  32   32  #include <sys/ipc_rctl.h>
  33   33  #include <sys/project.h>
  34   34  #include <sys/zone.h>
  35   35  #include <sys/sysmacros.h>
  36   36  #include <sys/avl.h>
  37   37  #include <sys/id_space.h>
  38   38  #include <sys/cred.h>
  39   39  #include <sys/list.h>
  40   40  
  41   41  #ifdef  __cplusplus
  42   42  extern "C" {
  43   43  #endif
  44   44  
  45   45  typedef uint64_t ipc_time_t;
  46   46  
  47   47  /* For xxxctl64 */
  48   48  #define IPC_SET64       13      /* set options */
  49   49  #define IPC_STAT64      14      /* get options */
  50   50  
  51   51  /*
  52   52   * There are two versions of the userland ipc_perm structure:
  53   53   *   ipc_perm     - the version used by user applications and by the kernel
  54   54   *                  when the user and kernel data models match (in ipc.h)
  55   55   *   ipc_perm32   - the 64-bit kernel's view of a 32-bit struct ipc_perm
  56   56   */
  57   57  #if     defined(_SYSCALL32)
  58   58  struct ipc_perm32 {
  59   59          uid32_t         uid;    /* owner's user id */
  60   60          gid32_t         gid;    /* owner's group id */
  61   61          uid32_t         cuid;   /* creator's user id */
  62   62          gid32_t         cgid;   /* creator's group id */
  63   63          mode32_t        mode;   /* access modes */
  64   64          uint32_t        seq;    /* slot usage sequence number */
  65   65          key32_t         key;    /* key */
  66   66          int32_t         pad[4]; /* reserve area */
  67   67  };
  68   68  #endif  /* _SYSCALL32 */
  69   69  
  70   70  /*
  71   71   * This is the ipc_perm equivalent used in the xxxid_ds64 structures.
  72   72   * It, like the structures it is used in, is intended only for use in
  73   73   * communication between the kernel and user programs, and has the same
  74   74   * layout across all data models.
  75   75   *
  76   76   * The xxxid_ds64 structures rely on ipc_perm64 being a multiple of
  77   77   * 8 bytes so subsequent fields are 64-bit aligned on x86.
  78   78   */
  79   79  typedef struct ipc_perm64 {
  80   80          uid_t   ipcx_uid;       /* owner's user id */
  81   81          gid_t   ipcx_gid;       /* owner's group id */
  82   82          uid_t   ipcx_cuid;      /* creator's user id */
  83   83          gid_t   ipcx_cgid;      /* creator's group id */
  84   84          mode_t  ipcx_mode;      /* access modes */
  85   85          key_t   ipcx_key;       /* key */
  86   86          projid_t ipcx_projid;   /* allocating project id */
  87   87          zoneid_t ipcx_zoneid;   /* creator's zone id */
  88   88  } ipc_perm64_t;
  89   89  
  90   90  /*
  91   91   * These are versions of xxxid_ds which are intended only for use in
  92   92   * communication between the kernel and user programs, and therefore
  93   93   * have the same layout across all data models.  Omitted are all
  94   94   * implementation-specific fields which would be of no use to user
  95   95   * programs.
  96   96   */
  97   97  struct shmid_ds64 {
  98   98          ipc_perm64_t    shmx_perm;      /* operation permission struct */
  99   99          pid_t           shmx_lpid;      /* pid of last shmop */
 100  100          pid_t           shmx_cpid;      /* pid of creator */
 101  101          uint64_t        shmx_segsz;     /* size of segment in bytes */
 102  102          uint64_t        shmx_nattch;    /* # of attaches */
 103  103          uint64_t        shmx_cnattch;   /* # of ISM attaches */
 104  104          uint64_t        shmx_lkcnt;     /* lock count ??? */
 105  105          ipc_time_t      shmx_atime;     /* last shmat time */
 106  106          ipc_time_t      shmx_dtime;     /* last shmdt time */
 107  107          ipc_time_t      shmx_ctime;     /* last change time */
 108  108  };
 109  109  
 110  110  struct semid_ds64 {
 111  111          ipc_perm64_t    semx_perm;      /* operation permission struct */
 112  112          ushort_t        semx_nsems;     /* # of semaphores in set */
 113  113          ushort_t        _semx_pad[3];   /* pad to 8-byte multiple */
 114  114          ipc_time_t      semx_otime;     /* last semop time */
 115  115          ipc_time_t      semx_ctime;     /* last change time */
 116  116  };
 117  117  
 118  118  struct msqid_ds64 {
 119  119          ipc_perm64_t    msgx_perm;      /* operation permission struct */
 120  120          uint64_t        msgx_cbytes;    /* current # bytes on q */
 121  121          uint64_t        msgx_qnum;      /* # of messages on q */
 122  122          uint64_t        msgx_qbytes;    /* max # of bytes on q */
 123  123          pid_t           msgx_lspid;     /* pid of last msgsnd */
 124  124          pid_t           msgx_lrpid;     /* pid of last msgrcv */
 125  125          ipc_time_t      msgx_stime;     /* last msgsnd time */
 126  126          ipc_time_t      msgx_rtime;     /* last msgrcv time */
 127  127          ipc_time_t      msgx_ctime;     /* last change time */
 128  128  };
 129  129  
 130  130  #ifdef _KERNEL
 131  131  
 132  132  /*
 133  133   * Implementation macros
 134  134   */
 135  135  #define IPC_FREE(x)     (((x)->ipc_mode & IPC_ALLOC) == 0)
 136  136  
 137  137  #define IPC_SEQ_BITS    7
 138  138  #define IPC_SEQ_MASK    ((1 << IPC_SEQ_BITS) - 1)
 139  139  #define IPC_SEQ_SHIFT   (31 - IPC_SEQ_BITS)
 140  140  #define IPC_INDEX_MASK  ((1 << IPC_SEQ_SHIFT) - 1)
 141  141  #define IPC_SEQ(x)      ((unsigned int)(x) >> IPC_SEQ_SHIFT)
 142  142  #define IPC_INDEX(x)    ((unsigned int)(x) & IPC_INDEX_MASK)
 143  143  
 144  144  #define IPC_IDS_MIN     (PAGESIZE / 64)         /* starting # of entries */
 145  145  #define IPC_IDS_MAX     (1 << IPC_SEQ_SHIFT)    /* maximum # of entries */
 146  146  #define IPC_ID_INVAL    UINT_MAX
 147  147  
 148  148  #define IPC_PROJ_USAGE(p, s) \
 149  149          (*(rctl_qty_t *)(((char *)&p->ipc_proj->kpj_data.kpd_ipc) + \
 150  150          s->ipcs_rctlofs))
 151  151  #define IPC_ZONE_USAGE(p, s) \
 152  152          (*(rctl_qty_t *)(((char *)&p->ipc_zone_ref.zref_zone->zone_ipc) + \
 153  153          s->ipcs_rctlofs))
 154  154  #define IPC_LOCKED(s, o) \
 155  155          MUTEX_HELD(&s->ipcs_table[IPC_INDEX(o->ipc_id)].ipct_lock)
 156  156  
 157  157  /*
 158  158   * The kernel's ipc_perm structure.
 159  159   */
 160  160  typedef struct kipc_perm {
 161  161          avl_node_t ipc_avl;     /* avl node if key is non-private */
 162  162          list_node_t ipc_list;   /* list node in list of all ids */
 163  163          uint_t  ipc_ref;        /* reference count              */
 164  164          uid_t   ipc_uid;        /* owner's user id              */
 165  165          gid_t   ipc_gid;        /* owner's group id             */
 166  166          uid_t   ipc_cuid;       /* creator's user id            */
 167  167          gid_t   ipc_cgid;       /* creator's group id           */
 168  168          mode_t  ipc_mode;       /* access modes                 */
 169  169          key_t   ipc_key;        /* key                          */
 170  170          kproject_t *ipc_proj;   /* creator's project            */
 171  171          uint_t  ipc_id;         /* id                           */
 172  172          zoneid_t ipc_zoneid;    /* creator's zone id            */
 173  173          zone_ref_t ipc_zone_ref; /* reference to creator's zone */
 174  174  } kipc_perm_t;
 175  175  
 176  176  typedef struct ipc_slot {
 177  177          kmutex_t        ipct_lock;      /* bucket lock          */
 178  178          kipc_perm_t     *ipct_data;     /* data                 */
 179  179          uint_t          ipct_seq;       /* sequence number      */
 180  180          struct ipc_slot *ipct_chain;    /* for stale arrays     */
 181  181          char            ipct_pad[64 - sizeof (kmutex_t) - 3 * sizeof (void *)];
 182  182  } ipc_slot_t;
 183  183  
 184  184  typedef void(ipc_func_t)(kipc_perm_t *);
 185  185  
 186  186  typedef struct ipc_service {
 187  187          kmutex_t        ipcs_lock;      /* lock for (de)allocation, keys */
 188  188          avl_tree_t      ipcs_keys;      /* objects sorted by key        */
 189  189          ipc_slot_t      *ipcs_table;    /* table of objects             */
 190  190          uint_t          ipcs_tabsz;     /* size of table                */
 191  191          uint_t          ipcs_count;     /* # of objects allocated       */
 192  192          rctl_hndl_t     ipcs_proj_rctl; /* id limiting rctl handle      */
 193  193          rctl_hndl_t     ipcs_zone_rctl; /* id limiting rctl handle      */
 194  194          size_t          ipcs_rctlofs;   /* offset in kproject_data_t    */
 195  195          id_space_t      *ipcs_ids;      /* id space for objects         */
 196  196          size_t          ipcs_ssize;     /* object size (for allocation) */
 197  197          ipc_func_t      *ipcs_dtor;     /* object destructor            */
 198  198          ipc_func_t      *ipcs_rmid;     /* object removal               */
 199  199          list_t          ipcs_usedids;   /* list of allocated ids        */
 200  200          int             ipcs_atype;     /* audit type (see c2/audit.h)  */
 201  201  } ipc_service_t;
 202  202  
 203  203  int ipcperm_access(kipc_perm_t *, int, cred_t *);
 204  204  int ipcperm_set(ipc_service_t *, struct cred *, kipc_perm_t *,
 205  205      struct ipc_perm *, model_t);
 206  206  void ipcperm_stat(struct ipc_perm *, kipc_perm_t *, model_t);
 207  207  int ipcperm_set64(ipc_service_t *, struct cred *, kipc_perm_t *,
 208  208      ipc_perm64_t *);
 209  209  void ipcperm_stat64(ipc_perm64_t *, kipc_perm_t *);
 210  210  
 211  211  ipc_service_t *ipcs_create(const char *, rctl_hndl_t, rctl_hndl_t, size_t,
 212  212      ipc_func_t *, ipc_func_t *, int, size_t);
 213  213  void ipcs_destroy(ipc_service_t *);
 214  214  void ipcs_lock(ipc_service_t *);
 215  215  void ipcs_unlock(ipc_service_t *);
 216  216  
 217  217  kmutex_t *ipc_lock(ipc_service_t *, int);
 218  218  kmutex_t *ipc_relock(ipc_service_t *, int, kmutex_t *);
 219  219  kmutex_t *ipc_lookup(ipc_service_t *, int, kipc_perm_t **);
 220  220  
 221  221  void ipc_hold(ipc_service_t *, kipc_perm_t *);
 222  222  void ipc_rele(ipc_service_t *, kipc_perm_t *);
 223  223  void ipc_rele_locked(ipc_service_t *, kipc_perm_t *);
 224  224  
 225  225  int ipc_get(ipc_service_t *, key_t, int, kipc_perm_t **, kmutex_t **);
 226  226  int ipc_commit_begin(ipc_service_t *, key_t, int, kipc_perm_t *);
 227  227  kmutex_t *ipc_commit_end(ipc_service_t *, kipc_perm_t *);
 228  228  void ipc_cleanup(ipc_service_t *, kipc_perm_t *);
 229  229  
 230  230  void ipc_rmsvc(ipc_service_t *, kipc_perm_t *);
 231  231  int ipc_rmid(ipc_service_t *, int, cred_t *);
 232  232  int ipc_ids(ipc_service_t *, int *, uint_t, uint_t *);
 233  233  
 234  234  void ipc_remove_zone(ipc_service_t *, zoneid_t);
 235  235  
 236  236  #else   /* _KERNEL */
 237  237  
 238  238  int msgctl64(int, int, struct msqid_ds64 *);
 239  239  int semctl64(int, int, int, ...);
 240  240  int shmctl64(int, int, struct shmid_ds64 *);
 241  241  
 242  242  #endif  /* _KERNEL */
 243  243  
 244  244  
 245  245  #ifdef  __cplusplus
 246  246  }
 247  247  #endif
 248  248  
 249  249  #endif  /* _IPC_IMPL_H */
  
    | 
      ↓ open down ↓ | 
    249 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX