Introduce [IPC|SHM]_[INFO|STAT] to shmctl to make

`/compat/linux/usr/bin/ipcs -m` happy.
This commit is contained in:
Michael Reifenberger 2001-10-28 09:29:10 +00:00
parent 788bbd2d61
commit 491dec936c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=85623
4 changed files with 113 additions and 4 deletions

View File

@ -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:

View File

@ -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);

View File

@ -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 */

View File

@ -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;