Introduce [IPC|SHM]_[INFO|STAT] to shmctl to make
`/compat/linux/usr/bin/ipcs -m` happy.
This commit is contained in:
parent
788bbd2d61
commit
491dec936c
sys
@ -70,6 +70,27 @@ struct l_shm_info {
|
||||
l_ulong swap_successes;
|
||||
};
|
||||
|
||||
static void
|
||||
bsd_to_linux_shminfo( struct shminfo *bpp, struct l_shminfo *lpp)
|
||||
{
|
||||
lpp->shmmax = bpp->shmmax;
|
||||
lpp->shmmin = bpp->shmmin;
|
||||
lpp->shmmni = bpp->shmmni;
|
||||
lpp->shmseg = bpp->shmseg;
|
||||
lpp->shmall = bpp->shmall;
|
||||
}
|
||||
|
||||
static void
|
||||
bsd_to_linux_shm_info( struct shm_info *bpp, struct l_shm_info *lpp)
|
||||
{
|
||||
lpp->used_ids = bpp->used_ids ;
|
||||
lpp->shm_tot = bpp->shm_tot ;
|
||||
lpp->shm_rss = bpp->shm_rss ;
|
||||
lpp->shm_swp = bpp->shm_swp ;
|
||||
lpp->swap_attempts = bpp->swap_attempts ;
|
||||
lpp->swap_successes = bpp->swap_successes ;
|
||||
}
|
||||
|
||||
struct l_ipc_perm {
|
||||
l_key_t key;
|
||||
l_uid16_t uid;
|
||||
@ -425,6 +446,8 @@ int
|
||||
linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
|
||||
{
|
||||
struct l_shmid_ds linux_shmid;
|
||||
struct l_shminfo linux_shminfo;
|
||||
struct l_shm_info linux_shm_info;
|
||||
struct shmctl_args /* {
|
||||
int shmid;
|
||||
int cmd;
|
||||
@ -434,6 +457,25 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
|
||||
caddr_t sg = stackgap_init();
|
||||
|
||||
switch (args->cmd) {
|
||||
|
||||
case LINUX_IPC_INFO:
|
||||
bsd_args.shmid = args->shmid;
|
||||
bsd_args.cmd = IPC_INFO;
|
||||
bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shminfo));
|
||||
if ((error = shmctl(td, &bsd_args)))
|
||||
return error;
|
||||
bsd_to_linux_shminfo( (struct shminfo *)bsd_args.buf, &linux_shminfo );
|
||||
return copyout(&linux_shminfo, (caddr_t)args->buf, sizeof(shminfo));
|
||||
|
||||
case LINUX_SHM_INFO:
|
||||
bsd_args.shmid = args->shmid;
|
||||
bsd_args.cmd = SHM_INFO;
|
||||
bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shm_info));
|
||||
if ((error = shmctl(td, &bsd_args)))
|
||||
return error;
|
||||
bsd_to_linux_shm_info( (struct shm_info *)bsd_args.buf, &linux_shm_info );
|
||||
return copyout(&linux_shm_info, (caddr_t)args->buf, sizeof(struct shm_info));
|
||||
|
||||
case LINUX_IPC_STAT:
|
||||
bsd_args.shmid = args->shmid;
|
||||
bsd_args.cmd = IPC_STAT;
|
||||
@ -443,6 +485,16 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
|
||||
bsd_to_linux_shmid_ds(bsd_args.buf, &linux_shmid);
|
||||
return copyout(&linux_shmid, (caddr_t)args->buf, sizeof(linux_shmid));
|
||||
|
||||
case LINUX_SHM_STAT:
|
||||
bsd_args.shmid = args->shmid;
|
||||
bsd_args.cmd = SHM_STAT;
|
||||
bsd_args.buf = (struct shmid_ds*)stackgap_alloc(&sg, sizeof(struct shmid_ds));
|
||||
if ((error = shmctl(td, &bsd_args))) {
|
||||
return error;
|
||||
}
|
||||
bsd_to_linux_shmid_ds(bsd_args.buf, &linux_shmid);
|
||||
return copyout(&linux_shmid, (caddr_t)args->buf, sizeof(linux_shmid));
|
||||
|
||||
case LINUX_IPC_SET:
|
||||
if ((error = copyin((caddr_t)args->buf, &linux_shmid,
|
||||
sizeof(linux_shmid))))
|
||||
@ -467,9 +519,6 @@ linux_shmctl(struct thread *td, struct linux_shmctl_args *args)
|
||||
}
|
||||
return shmctl(td, &bsd_args);
|
||||
|
||||
case LINUX_IPC_INFO:
|
||||
case LINUX_SHM_STAT:
|
||||
case LINUX_SHM_INFO:
|
||||
case LINUX_SHM_LOCK:
|
||||
case LINUX_SHM_UNLOCK:
|
||||
default:
|
||||
|
@ -96,6 +96,7 @@ struct shmmap_state {
|
||||
static void shm_deallocate_segment __P((struct shmid_ds *));
|
||||
static int shm_find_segment_by_key __P((key_t));
|
||||
static struct shmid_ds *shm_find_segment_by_shmid __P((int));
|
||||
static struct shmid_ds *shm_find_segment_by_shmidx __P((int));
|
||||
static int shm_delete_mapping __P((struct proc *p, struct shmmap_state *));
|
||||
static void shmrealloc __P((void));
|
||||
static void shminit __P((void));
|
||||
@ -179,6 +180,20 @@ shm_find_segment_by_shmid(shmid)
|
||||
return shmseg;
|
||||
}
|
||||
|
||||
static struct shmid_ds *
|
||||
shm_find_segment_by_shmidx(int segnum)
|
||||
{
|
||||
struct shmid_ds *shmseg;
|
||||
|
||||
if (segnum < 0 || segnum >= shmalloced)
|
||||
return NULL;
|
||||
shmseg = &shmsegs[segnum];
|
||||
if ((shmseg->shm_perm.mode & (SHMSEG_ALLOCATED | SHMSEG_REMOVED))
|
||||
!= SHMSEG_ALLOCATED )
|
||||
return NULL;
|
||||
return shmseg;
|
||||
}
|
||||
|
||||
static void
|
||||
shm_deallocate_segment(shmseg)
|
||||
struct shmid_ds *shmseg;
|
||||
@ -476,12 +491,38 @@ shmctl(td, uap)
|
||||
error = ENOSYS;
|
||||
goto done2;
|
||||
}
|
||||
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
||||
switch (uap->cmd) {
|
||||
case IPC_INFO:
|
||||
error = copyout( (caddr_t)&shminfo, uap->buf, sizeof( shminfo ) );
|
||||
if (error)
|
||||
goto done2;
|
||||
td->td_retval[0] = shmalloced;
|
||||
goto done2;
|
||||
case SHM_INFO: {
|
||||
struct shm_info shm_info;
|
||||
shm_info.used_ids = shm_nused;
|
||||
shm_info.shm_rss = 0; /*XXX where to get from ? */
|
||||
shm_info.shm_tot = 0; /*XXX where to get from ? */
|
||||
shm_info.shm_swp = 0; /*XXX where to get from ? */
|
||||
shm_info.swap_attempts = 0; /*XXX where to get from ? */
|
||||
shm_info.swap_successes = 0; /*XXX where to get from ? */
|
||||
error = copyout( (caddr_t)&shm_info, uap->buf, sizeof( shm_info ) );
|
||||
if (error)
|
||||
goto done2;
|
||||
td->td_retval[0] = shmalloced;
|
||||
goto done2;
|
||||
}
|
||||
}
|
||||
if( (uap->cmd) == SHM_STAT )
|
||||
shmseg = shm_find_segment_by_shmidx(uap->shmid);
|
||||
else
|
||||
shmseg = shm_find_segment_by_shmid(uap->shmid);
|
||||
if (shmseg == NULL) {
|
||||
error = EINVAL;
|
||||
goto done2;
|
||||
}
|
||||
switch (uap->cmd) {
|
||||
case SHM_STAT:
|
||||
case IPC_STAT:
|
||||
error = ipcperm(td, &shmseg->shm_perm, IPC_R);
|
||||
if (error)
|
||||
@ -489,6 +530,8 @@ shmctl(td, uap)
|
||||
error = copyout((caddr_t)shmseg, uap->buf, sizeof(inbuf));
|
||||
if (error)
|
||||
goto done2;
|
||||
else if( (uap->cmd) == SHM_STAT )
|
||||
td->td_retval[0] = IXSEQ_TO_IPCID( uap->shmid, shmseg->shm_perm );
|
||||
break;
|
||||
case IPC_SET:
|
||||
error = ipcperm(td, &shmseg->shm_perm, IPC_M);
|
||||
|
@ -75,6 +75,7 @@ struct ipc_perm {
|
||||
#define IPC_RMID 0 /* remove identifier */
|
||||
#define IPC_SET 1 /* set options */
|
||||
#define IPC_STAT 2 /* get options */
|
||||
#define IPC_INFO 3 /* get info */
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* Macros to convert between ipc ids and array indices or sequence ids */
|
||||
|
@ -50,6 +50,13 @@
|
||||
#define SHM_R (IPC_R)
|
||||
#define SHM_W (IPC_W)
|
||||
|
||||
/* predefine tbd *LOCK shmctl commands */
|
||||
#define SHM_LOCK 11
|
||||
#define SHM_UNLOCK 12
|
||||
|
||||
/* ipcs shmctl commands */
|
||||
#define SHM_STAT 13
|
||||
#define SHM_INFO 14
|
||||
|
||||
struct shmid_ds {
|
||||
struct ipc_perm shm_perm; /* operation permission structure */
|
||||
@ -79,6 +86,15 @@ struct shminfo {
|
||||
extern struct shminfo shminfo;
|
||||
extern struct shmid_ds *shmsegs;
|
||||
|
||||
struct shm_info {
|
||||
int used_ids;
|
||||
unsigned long shm_tot;
|
||||
unsigned long shm_rss;
|
||||
unsigned long shm_swp;
|
||||
unsigned long swap_attempts;
|
||||
unsigned long swap_successes;
|
||||
};
|
||||
|
||||
struct thread;
|
||||
struct proc;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user