Subject: Re: ipc errors/Linux Emulation NetBSD-3BETA using Oracle
To: Jose Luis Rodriguez Garcia <jose.l.rodriguez@getronics.com>
From: Chuck Silvers <chuq@chuq.com>
List: current-users
Date: 11/04/2005 08:27:48
--KsGdsel6WgEHnImy
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Nov 02, 2005 at 09:43:27PM +0100, Jose Luis Rodriguez Garcia wrote:
> The patch solved this error. Thank you Chuck, but I have more errors 
> about ipc.
> 
> --------
> I had to add this line to linux_ipc.c
> extern int      shm_nused;
> 
> and I had to remove "static" from the declartion of shm_nused in sysv_shm.c:
> I changed it to:
> static int      shm_last_free, shm_committed;
> int     shm_nused;

oops, sorry.  I didn't include all the files in the patch.


> -------
> 
> I attach the output of debug with options SEM_DEBUG and SHMDEBUG
> I also attach the ouput of the command kdump *out|grep ipc

here's another patch that will print more info on the console.
could you run this one and send the output?

-Chuck

--KsGdsel6WgEHnImy
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff.linux-shm.5"

Index: src/sys/compat/linux/common/linux_ipc.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_ipc.c,v
retrieving revision 1.31
diff -u -p -r1.31 linux_ipc.c
--- src/sys/compat/linux/common/linux_ipc.c	26 Feb 2005 23:10:19 -0000	1.31
+++ src/sys/compat/linux/common/linux_ipc.c	4 Nov 2005 16:27:22 -0000
@@ -469,11 +469,15 @@ linux_sys_shmctl(l, v, retval)
 	struct sys___shmctl13_args nua;
 	struct shmid_ds *bsp, bs;
 	struct linux_shmid_ds ls;
-	int error;
+	struct linux_shminfo64 lsi64;
+	struct linux_shm_info lsi;
+	int error, i, cmd;
 
 	SCARG(&nua, shmid) = SCARG(uap, shmid);
-	switch (SCARG(uap, cmd)) {
+	cmd = SCARG(uap, cmd) & ~LINUX_IPC_64;
+	switch (cmd) {
 	case LINUX_IPC_STAT:
+	case LINUX_SHM_STAT:
 		sg = stackgap_init(p, 0);
 		bsp = stackgap_alloc(p, &sg, sizeof(struct shmid_ds));
 		SCARG(&nua, cmd) = IPC_STAT;
@@ -483,7 +487,12 @@ linux_sys_shmctl(l, v, retval)
 		if ((error = copyin(SCARG(&nua, buf), &bs, sizeof bs)))
 			return error;
 		bsd_to_linux_shmid_ds(&bs, &ls);
+		if (cmd == LINUX_SHM_STAT) {
+			retval[0] = IXSEQ_TO_IPCID(bs.shm_perm._key,
+						   bs.shm_perm);
+		}
 		return copyout(&ls, SCARG(uap, buf), sizeof ls);
+
 	case LINUX_IPC_SET:
 		if ((error = copyin(SCARG(uap, buf), &ls, sizeof ls)))
 			return error;
@@ -495,22 +504,47 @@ linux_sys_shmctl(l, v, retval)
 		SCARG(&nua, cmd) = IPC_SET;
 		SCARG(&nua, buf) = bsp;
 		break;
+
 	case LINUX_IPC_RMID:
 		SCARG(&nua, cmd) = IPC_RMID;
 		SCARG(&nua, buf) = NULL;
 		break;
+
 	case LINUX_SHM_LOCK:
 		SCARG(&nua, cmd) = SHM_LOCK;
 		SCARG(&nua, buf) = NULL;
 		break;
+
 	case LINUX_SHM_UNLOCK:
 		SCARG(&nua, cmd) = SHM_UNLOCK;
 		SCARG(&nua, buf) = NULL;
 		break;
+
 	case LINUX_IPC_INFO:
-	case LINUX_SHM_STAT:
+		memset(&lsi64, 0, sizeof lsi64);
+		lsi64.l_shmmax = shminfo.shmmax;
+		lsi64.l_shmmin = shminfo.shmmin;
+		lsi64.l_shmmni = shminfo.shmmni;
+		lsi64.l_shmseg = shminfo.shmseg;
+		lsi64.l_shmall = shminfo.shmall;
+		return copyout(&lsi64, SCARG(uap, buf), sizeof lsi64);
+
 	case LINUX_SHM_INFO:
+		memset(&lsi, 0, sizeof lsi);
+		lsi.l_used_ids = shm_nused;
+		for (i = 0; i < shminfo.shmmni; i++) {
+			if (shmsegs[i].shm_perm.mode & 0x800) {
+				lsi.l_shm_tot += shmsegs[i].shm_segsz;
+			}
+		}
+		lsi.l_shm_rss = 0;
+		lsi.l_shm_swp = 0;
+		lsi.l_swap_attempts = 0;
+		lsi.l_swap_successes = 0;
+		return copyout(&lsi, SCARG(uap, buf), sizeof lsi);
+
 	default:
+		printf("linux_sys_shmctl cmd %d\n", SCARG(uap, cmd));
 		return EINVAL;
 	}
 	return sys___shmctl13(l, &nua, retval);
Index: src/sys/compat/linux/common/linux_ipc.h
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_ipc.h,v
retrieving revision 1.6
diff -u -p -r1.6 linux_ipc.h
--- src/sys/compat/linux/common/linux_ipc.h	30 May 2001 11:37:27 -0000	1.6
+++ src/sys/compat/linux/common/linux_ipc.h	4 Nov 2005 16:27:22 -0000
@@ -72,6 +72,8 @@ struct linux_ipc_perm {
 #define LINUX_IPC_STAT	2
 #define LINUX_IPC_INFO	3
 
+#define LINUX_IPC_64	0x100
+
 #if defined (SYSVSEM) || defined(SYSVSHM) || defined(SYSVMSG)
 #ifdef _KERNEL
 __BEGIN_DECLS
Index: src/sys/compat/linux/common/linux_shm.h
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_shm.h,v
retrieving revision 1.6
diff -u -p -r1.6 linux_shm.h
--- src/sys/compat/linux/common/linux_shm.h	28 Sep 2004 19:05:19 -0000	1.6
+++ src/sys/compat/linux/common/linux_shm.h	4 Nov 2005 16:27:22 -0000
@@ -58,6 +58,27 @@ struct linux_shmid_ds {
 	void			*l_private3;
 };
 
+struct linux_shminfo64 {
+	u_long			l_shmmax;
+	u_long			l_shmmin;
+	u_long			l_shmmni;
+	u_long			l_shmseg;
+	u_long			l_shmall;
+	u_long			l___unused1;
+	u_long			l___unused2;
+	u_long			l___unused3;
+	u_long			l___unused4;
+};
+
+struct linux_shm_info {
+	int			l_used_ids;
+	u_long			l_shm_tot;
+	u_long			l_shm_rss;
+	u_long			l_shm_swp;
+	u_long			l_swap_attempts;
+	u_long			l_swap_successes;
+};
+
 #define LINUX_SHM_RDONLY	0x1000
 #define LINUX_SHM_RND		0x2000
 #define LINUX_SHM_REMAP		0x4000
Index: src/sys/kern/sysv_shm.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sysv_shm.c,v
retrieving revision 1.84
diff -u -p -r1.84 sysv_shm.c
--- src/sys/kern/sysv_shm.c	1 Apr 2005 11:59:37 -0000	1.84
+++ src/sys/kern/sysv_shm.c	4 Nov 2005 16:27:23 -0000
@@ -110,7 +110,7 @@ static MALLOC_DEFINE(M_SHM, "shm", "SVID
 #define	SHMSEG_WANTED		0x1000
 #define	SHMSEG_RMLINGER		0x2000
 
-static int	shm_last_free, shm_nused, shm_committed;
+int shm_nused;
 struct	shmid_ds *shmsegs;
 
 struct shmmap_entry {
@@ -119,6 +119,8 @@ struct shmmap_entry {
 	int shmid;
 };
 
+static int	shm_last_free, shm_committed;
+
 static POOL_INIT(shmmap_entry_pool, sizeof(struct shmmap_entry), 0, 0, 0,
     "shmmp", &pool_allocator_nointr);
 
@@ -179,6 +181,9 @@ shm_deallocate_segment(shmseg)
 	struct uvm_object *uobj = shmseg->_shm_internal;
 	size_t size = (shmseg->shm_segsz + PGOFSET) & ~PGOFSET;
 
+printf("shm freeing key 0x%lx seq 0x%x\n",
+       shmseg->shm_perm._key, shmseg->shm_perm._seq);
+
 	(*uobj->pgops->pgo_detach)(uobj);
 	shmseg->_shm_internal = NULL;
 	shm_committed -= btoc(size);
@@ -596,19 +601,27 @@ sys_shmget(l, v, retval)
 	if (SCARG(uap, shmflg) & _SHM_RMLINGER)
 		mode |= SHMSEG_RMLINGER;
 
+printf("shmget: key 0x%lx size 0x%x shmflg 0x%x mode 0x%x\n",
+       SCARG(uap, key), SCARG(uap, size), SCARG(uap, shmflg), mode);
+
 	if (SCARG(uap, key) != IPC_PRIVATE) {
-	again:
+again:
 		segnum = shm_find_segment_by_key(SCARG(uap, key));
 		if (segnum >= 0) {
 			error = shmget_existing(p, uap, mode, segnum, retval);
 			if (error == EAGAIN)
 				goto again;
+printf("shmget: error1 %d\n", error);
 			return error;
 		}
-		if ((SCARG(uap, shmflg) & IPC_CREAT) == 0)
+		if ((SCARG(uap, shmflg) & IPC_CREAT) == 0) {
+printf("shmget: error2\n");
 			return ENOENT;
+		}
 	}
-	return shmget_allocate_segment(p, uap, mode, retval);
+	error = shmget_allocate_segment(p, uap, mode, retval);
+printf("shmget: error3 %d\n", error);
+	return error;
 }
 
 void

--KsGdsel6WgEHnImy--