Subject: per-process hostid
To: None <tech-kern@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 11/30/2001 22:36:21
--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,
I've recently needed (for reasons I don't want to explain in a public
forum :) to run on the same machine different processes which need to "see"
different hostid. For this I've implemented a per-process hostid
(trivial with the proc.<pid> sysctl tree :). The attached patch is incomplete,
especially I didn't deal with a few issues:
- gethostid() call in libc
- whenever we want a new MIB for kern.sysctl, and have the old one
  return proc.$$.hostid (for binary compatibility with older programs).

I'll handle this if this change is to be commited.

Does anyone has strong objections about this being commited ?
I agree this is a special use of hostid :)

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
--

--3MwIy2ne0vdjdPXF
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff-hostid

Index: compat/common/kern_info_43.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/common/kern_info_43.c,v
retrieving revision 1.12
diff -u -r1.12 kern_info_43.c
--- kern_info_43.c	2000/06/28 15:39:25	1.12
+++ kern_info_43.c	2001/11/30 16:09:31
@@ -78,7 +78,7 @@
 	register_t *retval;
 {
 
-	*(int32_t *)retval = hostid;
+	*(int32_t *)retval = *p->p_limit->pl_hostid;
 	return (0);
 }
 
Index: compat/svr4/svr4_stat.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/svr4/svr4_stat.c,v
retrieving revision 1.42
diff -u -r1.42 svr4_stat.c
--- svr4_stat.c	2001/02/21 23:53:01	1.42
+++ svr4_stat.c	2001/11/30 16:09:32
@@ -48,6 +48,7 @@
 #include <sys/mount.h>
 #include <sys/malloc.h>
 #include <sys/unistd.h>
+#include <sys/resourcevar.h>
 
 #include <sys/time.h>
 #include <sys/ucred.h>
@@ -578,6 +599,7 @@
 	int error;
 	size_t len;
 	char buf[256];
+	char strbuf[11]; /* used for hostid (in dec, u_int) */
 
 	u_int rlen = SCARG(uap, len);
 
@@ -607,7 +629,10 @@
 		break;
 
 	case SVR4_SI_HW_SERIAL:
-		str = "0";
+		snprintf(strbuf, sizeof(strbuf),
+		    "%u", (u_int)(*p->p_limit->pl_hostid));
+		strbuf[sizeof(strbuf) - 1] = '\0';
+		str = strbuf;
 		break;
 
 	case SVR4_SI_HW_PROVIDER:
Index: compat/svr4_32/svr4_32_stat.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/svr4_32/svr4_32_stat.c,v
retrieving revision 1.3
diff -u -r1.3 svr4_32_stat.c
--- svr4_32_stat.c	2001/02/19 19:49:36	1.3
+++ svr4_32_stat.c	2001/11/30 16:09:36
@@ -48,6 +48,7 @@
 #include <sys/mount.h>
 #include <sys/malloc.h>
 #include <sys/unistd.h>
+#include <sys/resourcevar.h>
 
 #include <sys/time.h>
 #include <sys/ucred.h>
@@ -600,6 +601,7 @@
 	int error;
 	size_t len;
 	char buf[256];
+	char strbuf[11]; /* used for hostid (in dec, u_int) */
 
 	u_int rlen = SCARG(uap, len);
 
@@ -629,7 +631,10 @@
 		break;
 
 	case SVR4_SI_HW_SERIAL:
-		str = "0";
+		snprintf(strbuf, sizeof(strbuf),
+		    "%u", (u_int)*p->p_limit->pl_hostid);
+		strbuf[sizeof(strbuf) - 1] = '\0';
+		str = strbuf;
 		break;
 
 	case SVR4_SI_HW_PROVIDER:
Index: kern/init_main.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/init_main.c,v
retrieving revision 1.196
diff -u -r1.196 init_main.c
--- init_main.c	2001/11/12 15:25:04	1.196
+++ init_main.c	2001/11/30 16:09:38
@@ -295,6 +295,7 @@
 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_max = lim;
 	limit0.pl_rlimit[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
 	limit0.pl_corename = defcorename;
+	limit0.pl_hostid = &hostid;
 	limit0.p_refcnt = 1;
 
 	/*
Index: kern/kern_resource.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_resource.c,v
retrieving revision 1.61
diff -u -r1.61 kern_resource.c
--- kern_resource.c	2001/11/12 15:25:14	1.61
+++ kern_resource.c	2001/11/30 16:09:38
@@ -482,6 +482,13 @@
 	newlim = pool_get(&plimit_pool, PR_WAITOK);
 	memcpy(newlim->pl_rlimit, lim->pl_rlimit,
 	    sizeof(struct rlimit) * RLIM_NLIMITS);
+	if (lim->pl_hostid == &hostid) {
+		newlim->pl_hostid = &hostid;
+	} else {
+		newlim->pl_hostid = malloc(sizeof(*newlim->pl_hostid),
+		    M_TEMP, M_WAITOK);
+		*newlim->pl_hostid = *lim->pl_hostid;
+	}
 	if (lim->pl_corename == defcorename) {
 		newlim->pl_corename = defcorename;
 	} else {
@@ -507,5 +514,7 @@
 #endif
 	if (lim->pl_corename != defcorename)
 		free(lim->pl_corename, M_TEMP);
+	if (lim->pl_hostid != &hostid)
+		free(lim->pl_hostid, M_TEMP);
 	pool_put(&plimit_pool, lim);
 }
Index: kern/kern_sysctl.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sysctl.c,v
retrieving revision 1.97
diff -u -r1.97 kern_sysctl.c
--- kern_sysctl.c	2001/11/12 15:25:17	1.97
+++ kern_sysctl.c	2001/11/30 16:09:39
@@ -792,6 +793,33 @@
 		if (newp)
 			error = dosetrlimit(ptmp, p->p_cred,
 			    name[2] - 1, &alim);
+		return error;
+	}
+	if (name[1] == PROC_PID_HOSTID) {
+		int inthostid;
+		long *newhostid;
+		/* XXX assumes sizeof long <= sizeof int */
+		inthostid = *ptmp->p_limit->pl_hostid;
+		error =  sysctl_int(oldp, oldlenp, newp, newlen, &inthostid);
+		if (newp && error == 0 &&
+		    inthostid != *ptmp->p_limit->pl_hostid) {
+			printf("proc %d hostid %lx new %x\n", ptmp->p_pid,
+			    *ptmp->p_limit->pl_hostid, inthostid);
+			if (ptmp->p_limit->p_refcnt > 1 &&
+			    (ptmp->p_limit->p_lflags & PL_SHAREMOD) == 0) {
+				newplim = limcopy(ptmp->p_limit);
+				limfree(ptmp->p_limit);
+				ptmp->p_limit = newplim;
+			}
+			newhostid = malloc(sizeof(*ptmp->p_limit->pl_hostid),
+			    M_TEMP, M_WAITOK);
+			if (newhostid == NULL)
+				return ENOMEM;
+			if (ptmp->p_limit->pl_hostid != &hostid)
+				free(ptmp->p_limit->pl_hostid, M_TEMP);
+			ptmp->p_limit->pl_hostid = newhostid;
+			*ptmp->p_limit->pl_hostid = inthostid;
+		}
 		return error;
 	}
 	return (EINVAL);
Index: sys/resourcevar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/resourcevar.h,v
retrieving revision 1.16
diff -u -r1.16 resourcevar.h
--- resourcevar.h	2001/04/30 01:13:21	1.16
+++ resourcevar.h	2001/11/30 16:09:50
@@ -74,6 +74,7 @@
 struct plimit {
 	struct	rlimit pl_rlimit[RLIM_NLIMITS];
 	char	*pl_corename;
+	long	*pl_hostid;
 #define	PL_SHAREMOD	0x01		/* modifications are shared */
 	int	p_lflags;
 	int	p_refcnt;		/* number of references */
Index: sys/sysctl.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/sysctl.h,v
retrieving revision 1.70
diff -u -r1.70 sysctl.h
--- sysctl.h	2001/10/05 19:05:06	1.70
+++ sysctl.h	2001/11/30 16:09:50
@@ -561,12 +561,14 @@
  */
 #define	PROC_PID_CORENAME	1
 #define	PROC_PID_LIMIT		2
-#define	PROC_PID_MAXID		3
+#define	PROC_PID_HOSTID		3
+#define	PROC_PID_MAXID		4
 
 #define	PROC_PID_NAMES { \
 	{ 0, 0 }, \
 	{ "corename", CTLTYPE_STRING }, \
 	{ "rlimit", CTLTYPE_NODE }, \
+	{ "hostid", CTLTYPE_INT }, \
 }
 
 /* Limit types from <sys/resources.h> */

--3MwIy2ne0vdjdPXF--