/** * Returns 0 on success, -errno on failure. */ static int tapdisk_xenblkif_stats_destroy(struct td_xenblkif *blkif) { int err; err = shm_destroy(&blkif->xenvbd_stats.io_ring); if (unlikely(err)) goto out; free(blkif->xenvbd_stats.io_ring.path); blkif->xenvbd_stats.io_ring.path = NULL; err = shm_destroy(&blkif->xenvbd_stats.stats); if (unlikely(err)) goto out; free(blkif->xenvbd_stats.stats.path); blkif->xenvbd_stats.stats.path = NULL; if (likely(blkif->xenvbd_stats.root)) { err = rmdir(blkif->xenvbd_stats.root); if (unlikely(err && errno != ENOENT)) { err = errno; EPRINTF("failed to remove %s: %s\n", blkif->xenvbd_stats.root, strerror(err)); goto out; } err = 0; free(blkif->xenvbd_stats.root); blkif->xenvbd_stats.root = NULL; } out: return -err; }
/* Called with ns->shm_ids(ns).rwsem locked */ static int shm_try_destroy_current(int id, void *p, void *data) { struct ipc_namespace *ns = data; struct kern_ipc_perm *ipcp = p; struct shmid_kernel *shp = container_of(ipcp, struct shmid_kernel, shm_perm); if (shp->shm_creator != current) return 0; /* * Mark it as orphaned to destroy the segment when * kernel.shm_rmid_forced is changed. * It is noop if the following shm_may_destroy() returns true. */ shp->shm_creator = NULL; /* * Don't even try to destroy it. If shm_rmid_forced=0 and IPC_RMID * is not set, it shouldn't be deleted here. */ if (!ns->shm_rmid_forced) return 0; if (shm_may_destroy(ns, shp)) { shm_lock_by_ptr(shp); shm_destroy(ns, shp); } return 0; }
void mail_destroy(struct mail *m) { mail_free(m); if (m->base != NULL) { SHM_DEREGISTER(&m->shm); shm_destroy(&m->shm); } }
int shmctl(int id,int cmd,struct shmid_ds *buf) { int ret; if (cmd==IPC_STAT) ret = shm_stat(id,&(buf->shm_perm.uid),&(buf->shm_perm.gid),&(buf->shm_perm.cuid),&(buf->shm_perm.cgid),&(buf->shm_perm.mode),&(buf->shm_segsz),&(buf->shm_lpid),&(buf->shm_cpid),&(buf->shm_nattch),&(buf->shm_atime),&(buf->shm_dtime),&(buf->shm_ctime)); else if (cmd==IPC_SET) ret = shm_set(id,buf->shm_perm.uid,buf->shm_perm.gid,buf->shm_perm.mode); else if (cmd==IPC_RMID) shm_destroy(id); else ret = -EINVAL; errno = ret<0?-ret:0; return ret<0?-1:0; }
static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp) { if (shp->shm_nattch){ shp->shm_perm.mode |= SHM_DEST; /* Do not find it any more */ shp->shm_perm.key = IPC_PRIVATE; shm_unlock(shp); } else shm_destroy(ns, shp); }
static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp) { struct shmid_kernel *shp; shp = container_of(ipcp, struct shmid_kernel, shm_perm); if (shp->shm_nattch){ shp->shm_perm.mode |= SHM_DEST; shp->shm_perm.key = IPC_PRIVATE; shm_unlock(shp); } else shm_destroy(ns, shp); }
static int vbd_stats_destroy(td_vbd_t *vbd) { int err = 0; ASSERT(vbd); err = shm_destroy(&vbd->rrd.shm); if (unlikely(err)) { EPRINTF("failed to destroy RRD file: %s\n", strerror(err)); goto out; } free(vbd->rrd.shm.path); vbd->rrd.shm.path = NULL; out: return -err; }
int td_metrics_nbd_stop(stats_t *nbd_stats) { int err = 0; if(!nbd_stats->shm.path) goto end; err = shm_destroy(&nbd_stats->shm); if (unlikely(err)) { err = errno; EPRINTF("failed to destroy NBD metrics file: %s\n", strerror(err)); } free(nbd_stats->shm.path); nbd_stats->shm.path = NULL; end: return err; }
/* * remove the attach descriptor vma. * free memory for segment if it is marked destroyed. * The descriptor has already been removed from the current->mm->mmap list * and will later be kfree()d. */ static void shm_close(struct vm_area_struct *vma) { struct file * file = vma->vm_file; struct shm_file_data *sfd = shm_file_data(file); struct shmid_kernel *shp; struct ipc_namespace *ns = sfd->ns; down_write(&shm_ids(ns).rwsem); /* remove from the list of attaches of the shm segment */ shp = shm_lock(ns, sfd->id); BUG_ON(IS_ERR(shp)); shp->shm_lprid = task_tgid_vnr(current); shp->shm_dtim = get_seconds(); shp->shm_nattch--; if (shm_may_destroy(ns, shp)) shm_destroy(ns, shp); else shm_unlock(shp); up_write(&shm_ids(ns).rwsem); }
/* Called with ns->shm_ids(ns).rwsem locked */ static int shm_try_destroy_orphaned(int id, void *p, void *data) { struct ipc_namespace *ns = data; struct kern_ipc_perm *ipcp = p; struct shmid_kernel *shp = container_of(ipcp, struct shmid_kernel, shm_perm); /* * We want to destroy segments without users and with already * exit'ed originating process. * * As shp->* are changed under rwsem, it's safe to skip shp locking. */ if (shp->shm_creator != NULL) return 0; if (shm_may_destroy(ns, shp)) { shm_lock_by_ptr(shp); shm_destroy(ns, shp); } return 0; }
int td_metrics_blktap_stop(stats_t *blktap_stats) { int err = 0; if(!blktap_stats->shm.path) goto end; err = shm_destroy(&blktap_stats->shm); if (unlikely(err)) { err = errno; EPRINTF("failed to destroy blktap metrics file: %s\n", strerror(err)); } free(blktap_stats->shm.path); blktap_stats->shm.path = NULL; end: return err; }
int shmctl(int shmid, int cmd, struct shmid_ds *buf) { FAR struct shm_region_s *region; int ret; DEBUGASSERT(shmid >= 0 && shmid < CONFIG_ARCH_SHM_MAXREGIONS); region = &g_shminfo.si_region[shmid]; DEBUGASSERT((region->sr_flags & SRFLAG_INUSE) != 0); /* Get exclusive access to the region data structure */ ret = sem_wait(®ion->sr_sem); if (ret < 0) { shmerr("ERROR: sem_wait failed: %d\n", ret); return ret; } /* Handle the request according to the received cmd */ switch (cmd) { case IPC_STAT: { /* Place the current value of each member of the shmid_ds data * structure associated with shmid into the structure pointed to * by buf. */ DEBUGASSERT(buf); memcpy(buf, ®ion->sr_ds, sizeof(struct shmid_ds)); } break; case IPC_SET: { /* Set the value of the shm_perm.mode member of the shmid_ds * data structure associated with shmid to the corresponding * value found in the structure pointed to by buf. */ region->sr_ds.shm_perm.mode = buf->shm_perm.mode; } break; case IPC_RMID: { /* Are any processes attached to the region? */ if (region->sr_ds.shm_nattch > 0) { /* Yes.. just set the UNLINKED flag. The region will be removed when there are no longer any processes attached to it. */ region->sr_flags |= SRFLAG_UNLINKED; } else { /* No.. free the entry now */ shm_destroy(shmid); /* Don't try anything further on the deleted region */ return OK; } } break; default: shmerr("ERROR: Unrecognized command: %d\n", cmd); ret = -EINVAL; goto errout_with_semaphore; } /* Save the process ID of the the last operation */ region = &g_shminfo.si_region[shmid]; region->sr_ds.shm_lpid = getpid(); /* Save the time of the last shmctl() */ region->sr_ds.shm_ctime = time(NULL); /* Release our lock on the entry */ sem_post(®ion->sr_sem); return ret; errout_with_semaphore: sem_post(®ion->sr_sem); set_errno(-ret); return ERROR; }