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