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>


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.

  23  */
  24 
  25 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T             */
  26 /*      All Rights Reserved                                     */
  27 
  28 
  29 /*
  30  * Common Inter-Process Communication routines.
  31  *
  32  * Overview
  33  * --------
  34  *
  35  * The System V inter-process communication (IPC) facilities provide
  36  * three services, message queues, semaphore arrays, and shared memory
  37  * segments, which are mananged using filesystem-like namespaces.
  38  * Unlike a filesystem, these namespaces aren't mounted and accessible
  39  * via a path -- a special API is used to interact with the different
  40  * facilities (nothing precludes a VFS-based interface, but the
  41  * standards require the special APIs).  Furthermore, these special
  42  * APIs don't use file descriptors, nor do they have an equivalent.


1200         service->ipcs_table[index].ipct_data = NULL;
1201 
1202         if (perm->ipc_key != IPC_PRIVATE)
1203                 avl_remove(&service->ipcs_keys, perm);
1204         list_remove(&service->ipcs_usedids, perm);
1205         perm->ipc_mode &= ~IPC_ALLOC;
1206 
1207         id_free(service->ipcs_ids, index);
1208 
1209         if (service->ipcs_table[index].ipct_seq++ == IPC_SEQ_MASK)
1210                 service->ipcs_table[index].ipct_seq = 0;
1211         service->ipcs_count--;
1212         ASSERT(IPC_PROJ_USAGE(perm, service) > 0);
1213         ASSERT(IPC_ZONE_USAGE(perm, service) > 0);
1214         IPC_PROJ_USAGE(perm, service) -= 1;
1215         IPC_ZONE_USAGE(perm, service) -= 1;
1216         ASSERT(service->ipcs_count || ((IPC_PROJ_USAGE(perm, service) == 0) &&
1217             (IPC_ZONE_USAGE(perm, service) == 0)));
1218 }
1219 








1220 









1221 /*
1222  * Common code to perform an IPC_RMID.  Returns an errno value on
1223  * failure, 0 on success.
1224  */
1225 int
1226 ipc_rmid(ipc_service_t *service, int id, cred_t *cr)
1227 {
1228         kipc_perm_t *perm;
1229         kmutex_t *lock;
1230 
1231         mutex_enter(&service->ipcs_lock);
1232 
1233         lock = ipc_lookup(service, id, &perm);
1234         if (lock == NULL) {
1235                 mutex_exit(&service->ipcs_lock);
1236                 return (EINVAL);
1237         }
1238 
1239         ASSERT(service->ipcs_count > 0);
1240 
1241         if (secpolicy_ipc_owner(cr, perm) != 0) {
1242                 mutex_exit(lock);
1243                 mutex_exit(&service->ipcs_lock);
1244                 return (EPERM);
1245         }
1246 
1247         /*
1248          * Nothing can fail from this point on.
1249          */
1250         ipc_remove(service, perm);
1251         mutex_exit(&service->ipcs_lock);
1252 
1253         /* perform any per-service removal actions */
1254         service->ipcs_rmid(perm);
1255 
1256         ipc_rele(service, perm);
1257 
1258         return (0);
1259 }
1260 
1261 /*
1262  * Implementation for shmids, semids, and msgids.  buf is the address
1263  * of the user buffer, nids is the size, and pnids is a pointer to
1264  * where we write the actual number of ids that [would] have been
1265  * copied out.
1266  */
1267 int
1268 ipc_ids(ipc_service_t *service, int *buf, uint_t nids, uint_t *pnids)
1269 {
1270         kipc_perm_t *perm;
1271         size_t  idsize = 0;
1272         int     error = 0;
1273         int     idcount;
1274         int     *ids;
1275         int     numids = 0;
1276         zoneid_t zoneid = getzoneid();
1277         int     global = INGLOBALZONE(curproc);




   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2016 Joyent, Inc.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T             */
  27 /*      All Rights Reserved                                     */
  28 
  29 
  30 /*
  31  * Common Inter-Process Communication routines.
  32  *
  33  * Overview
  34  * --------
  35  *
  36  * The System V inter-process communication (IPC) facilities provide
  37  * three services, message queues, semaphore arrays, and shared memory
  38  * segments, which are mananged using filesystem-like namespaces.
  39  * Unlike a filesystem, these namespaces aren't mounted and accessible
  40  * via a path -- a special API is used to interact with the different
  41  * facilities (nothing precludes a VFS-based interface, but the
  42  * standards require the special APIs).  Furthermore, these special
  43  * APIs don't use file descriptors, nor do they have an equivalent.


1201         service->ipcs_table[index].ipct_data = NULL;
1202 
1203         if (perm->ipc_key != IPC_PRIVATE)
1204                 avl_remove(&service->ipcs_keys, perm);
1205         list_remove(&service->ipcs_usedids, perm);
1206         perm->ipc_mode &= ~IPC_ALLOC;
1207 
1208         id_free(service->ipcs_ids, index);
1209 
1210         if (service->ipcs_table[index].ipct_seq++ == IPC_SEQ_MASK)
1211                 service->ipcs_table[index].ipct_seq = 0;
1212         service->ipcs_count--;
1213         ASSERT(IPC_PROJ_USAGE(perm, service) > 0);
1214         ASSERT(IPC_ZONE_USAGE(perm, service) > 0);
1215         IPC_PROJ_USAGE(perm, service) -= 1;
1216         IPC_ZONE_USAGE(perm, service) -= 1;
1217         ASSERT(service->ipcs_count || ((IPC_PROJ_USAGE(perm, service) == 0) &&
1218             (IPC_ZONE_USAGE(perm, service) == 0)));
1219 }
1220 
1221 /*
1222  * Perform actual IPC_RMID, either via ipc_rmid or due to a delayed *_RMID.
1223  */
1224 void
1225 ipc_rmsvc(ipc_service_t *service, kipc_perm_t *perm)
1226 {
1227         ASSERT(service->ipcs_count > 0);
1228         ASSERT(MUTEX_HELD(&service->ipcs_lock));
1229 
1230         ipc_remove(service, perm);
1231         mutex_exit(&service->ipcs_lock);
1232 
1233         /* perform any per-service removal actions */
1234         service->ipcs_rmid(perm);
1235 
1236         ipc_rele(service, perm);
1237 }
1238 
1239 /*
1240  * Common code to perform an IPC_RMID.  Returns an errno value on
1241  * failure, 0 on success.
1242  */
1243 int
1244 ipc_rmid(ipc_service_t *service, int id, cred_t *cr)
1245 {
1246         kipc_perm_t *perm;
1247         kmutex_t *lock;
1248 
1249         mutex_enter(&service->ipcs_lock);
1250 
1251         lock = ipc_lookup(service, id, &perm);
1252         if (lock == NULL) {
1253                 mutex_exit(&service->ipcs_lock);
1254                 return (EINVAL);
1255         }
1256 
1257         ASSERT(service->ipcs_count > 0);
1258 
1259         if (secpolicy_ipc_owner(cr, perm) != 0) {
1260                 mutex_exit(lock);
1261                 mutex_exit(&service->ipcs_lock);
1262                 return (EPERM);
1263         }
1264 
1265         /*
1266          * Nothing can fail from this point on.
1267          */
1268         ipc_rmsvc(service, perm);

1269 





1270         return (0);
1271 }
1272 
1273 /*
1274  * Implementation for shmids, semids, and msgids.  buf is the address
1275  * of the user buffer, nids is the size, and pnids is a pointer to
1276  * where we write the actual number of ids that [would] have been
1277  * copied out.
1278  */
1279 int
1280 ipc_ids(ipc_service_t *service, int *buf, uint_t nids, uint_t *pnids)
1281 {
1282         kipc_perm_t *perm;
1283         size_t  idsize = 0;
1284         int     error = 0;
1285         int     idcount;
1286         int     *ids;
1287         int     numids = 0;
1288         zoneid_t zoneid = getzoneid();
1289         int     global = INGLOBALZONE(curproc);