changeset 10089:3b42b78e6a26

6757037 Zone-spawned LWP needs to be able to run on a processor set
author Surya Prakki <Surya.Prakki@Sun.COM>
date Wed, 15 Jul 2009 00:07:13 -0700
parents accb636cf069
children ceea0ea38cc6
files usr/src/cmd/psrset/psrset.c usr/src/lib/libc/common/sys/_pset.s usr/src/lib/libc/port/llib-lc usr/src/lib/libc/port/mapfile-vers usr/src/lib/libc/port/sys/psetsys.c usr/src/lib/libproc/common/libproc.h usr/src/lib/libproc/common/llib-lproc usr/src/lib/libproc/common/mapfile-vers usr/src/lib/libproc/common/pr_pbind.c usr/src/uts/common/sys/pset.h usr/src/uts/common/syscall/pset.c
diffstat 11 files changed, 112 insertions(+), 210 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/psrset/psrset.c	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/cmd/psrset/psrset.c	Wed Jul 15 00:07:13 2009 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * psrset - create and manage processor sets
  */
@@ -44,7 +41,6 @@
 #include <procfs.h>
 #include <libproc.h>
 #include <stdarg.h>
-#include <priv.h>
 
 #if !defined(TEXT_DOMAIN)		/* should be defined by cc -D */
 #define	TEXT_DOMAIN 	"SYS_TEST"	/* Use this only if it wasn't */
@@ -107,14 +103,10 @@
 	exit(ERR_FAIL);
 }
 
-static prpriv_t *orig_priv;
-
 static struct ps_prochandle *
 grab_proc(id_t pid)
 {
 	int ret;
-	prpriv_t *new_priv;
-	priv_set_t *eff_set, *perm_set;
 	struct ps_prochandle *Pr;
 
 	if ((Pr = Pgrab(pid, 0, &ret)) == NULL) {
@@ -124,66 +116,6 @@
 		return (NULL);
 	}
 
-	/*
-	 * If target process does not have required PRIV_SYS_RES_CONFIG
-	 * privilege, assign it temporarily to that process' effective
-	 * and permitted sets so that it can call pset_bind(2).
-	 */
-	if ((new_priv = proc_get_priv(pid)) == NULL) {
-		warn(gettext("unable to get privileges for process %d: %s\n"),
-		    pid, strerror(errno));
-		errors = ERR_FAIL;
-		Prelease(Pr, 0);
-		return (NULL);
-	}
-
-	if (Pcreate_agent(Pr) != 0) {
-		warn(gettext("cannot control process %d\n"), (int)pid);
-		errors = ERR_FAIL;
-		Prelease(Pr, 0);
-		free(new_priv);
-		return (NULL);
-	}
-
-	eff_set = (priv_set_t *)&new_priv->pr_sets[new_priv->pr_setsize *
-	    priv_getsetbyname(PRIV_EFFECTIVE)];
-	perm_set = (priv_set_t *)&new_priv->pr_sets[new_priv->pr_setsize *
-	    priv_getsetbyname(PRIV_PERMITTED)];
-	if (!priv_ismember(eff_set, PRIV_SYS_RES_CONFIG)) {
-		/*
-		 * Save original privileges
-		 */
-		if ((orig_priv = proc_get_priv(pid)) == NULL) {
-			warn(gettext("unable to get privileges for "
-			    "process %d: %s\n"), pid, strerror(errno));
-			errors = ERR_FAIL;
-			Pdestroy_agent(Pr);
-			Prelease(Pr, 0);
-			free(new_priv);
-			return (NULL);
-		}
-		(void) priv_addset(eff_set, PRIV_SYS_RES_CONFIG);
-		(void) priv_addset(perm_set, PRIV_SYS_RES_CONFIG);
-		/*
-		 * We don't want to leave a process with elevated privileges,
-		 * so make sure the process dies if we exit unexpectedly.
-		 */
-		if (Psetflags(Pr, PR_KLC) != 0 ||
-		    Psetpriv(Pr, new_priv) != 0) {
-			warn(gettext("unable to set process privileges for "
-			    "process %d: %s\n"), pid, strerror(errno));
-			(void) Punsetflags(Pr, PR_KLC);
-			free(new_priv);
-			free(orig_priv);
-			Pdestroy_agent(Pr);
-			Prelease(Pr, 0);
-			orig_priv = NULL;
-			errors = ERR_FAIL;
-			return (NULL);
-		}
-	}
-	free(new_priv);
-
 	return (Pr);
 }
 
@@ -192,28 +124,6 @@
 {
 	if (Pr == NULL)
 		return;
-	if (orig_priv != NULL) {
-		if (Psetpriv(Pr, orig_priv) != 0) {
-			/*
-			 * If this fails, we can't leave a process with
-			 * elevated privileges, so we have to release the
-			 * process from libproc, knowing that it will
-			 * be killed (since we set the PR_KLC flag).
-			 */
-			Pdestroy_agent(Pr);
-			warn(gettext("cannot relinquish privileges for "
-			    "process %d.  The process was killed\n"),
-			    Ppsinfo(Pr)->pr_pid);
-			errors = ERR_FAIL;
-		} else {
-			(void) Punsetflags(Pr, PR_KLC);
-			Pdestroy_agent(Pr);
-		}
-		free(orig_priv);
-		orig_priv = NULL;
-	} else {
-		Pdestroy_agent(Pr);
-	}
 	Prelease(Pr, 0);
 }
 
@@ -351,29 +261,30 @@
 	if (old == PS_NONE) {
 		if (new == PS_NONE)
 			(void) printf(gettext("%s id %s: was not bound, "
-				"now not bound\n"), proclwp, pidstr);
+			    "now not bound\n"), proclwp, pidstr);
 		else
 			(void) printf(gettext("%s id %s: was not bound, "
-				"now %d\n"), proclwp, pidstr, new);
+			    "now %d\n"), proclwp, pidstr, new);
 	} else {
 		if (new == PS_NONE)
 			(void) printf(gettext("%s id %s: was %d, "
-				"now not bound\n"), proclwp, pidstr, old);
+			    "now not bound\n"), proclwp, pidstr, old);
 		else
 			(void) printf(gettext("%s id %s: was %d, "
-				"now %d\n"), proclwp, pidstr, old, new);
+			    "now %d\n"), proclwp, pidstr, old, new);
 	}
 }
 
 static void
-bind_lwp(struct ps_prochandle *Pr, id_t pid, id_t lwpid, psetid_t pset)
+bind_lwp(id_t pid, id_t lwpid, psetid_t pset)
 {
 	psetid_t old_pset;
 
-	if (pr_pset_bind(Pr, pset, P_LWPID, lwpid, &old_pset) < 0) {
+	if (pset_bind_lwp(pset, lwpid, pid, &old_pset) != 0) {
 		bind_err(pset, pid, lwpid, errno);
 		errors = ERR_FAIL;
-	} else {
+	}
+	if (errors != ERR_FAIL) {
 		if (qflag)
 			query_out(pid, lwpid, old_pset);
 		else
@@ -621,22 +532,22 @@
 usage(void)
 {
 	(void) fprintf(stderr, gettext(
-		"usage: \n"
-		"\t%1$s -c [-F] [processor_id ...]\n"
-		"\t%1$s -d processor_set_id ...\n"
-		"\t%1$s -n processor_set_id\n"
-		"\t%1$s -f processor_set_id\n"
-		"\t%1$s -e processor_set_id command [argument(s)...]\n"
-		"\t%1$s -a [-F] processor_set_id processor_id ...\n"
-		"\t%1$s -r [-F] processor_id ...\n"
-		"\t%1$s -p [processorid ...]\n"
-		"\t%1$s -b processor_set_id pid[/lwpids] ...\n"
-		"\t%1$s -u pid[/lwpids] ...\n"
-		"\t%1$s -q [pid[/lwpids] ...]\n"
-		"\t%1$s -U [processor_set_id] ...\n"
-		"\t%1$s -Q [processor_set_id] ...\n"
-		"\t%1$s [-i] [processor_set_id ...]\n"),
-		progname);
+	    "usage: \n"
+	    "\t%1$s -c [-F] [processor_id ...]\n"
+	    "\t%1$s -d processor_set_id ...\n"
+	    "\t%1$s -n processor_set_id\n"
+	    "\t%1$s -f processor_set_id\n"
+	    "\t%1$s -e processor_set_id command [argument(s)...]\n"
+	    "\t%1$s -a [-F] processor_set_id processor_id ...\n"
+	    "\t%1$s -r [-F] processor_id ...\n"
+	    "\t%1$s -p [processorid ...]\n"
+	    "\t%1$s -b processor_set_id pid[/lwpids] ...\n"
+	    "\t%1$s -u pid[/lwpids] ...\n"
+	    "\t%1$s -q [pid[/lwpids] ...]\n"
+	    "\t%1$s -U [processor_set_id] ...\n"
+	    "\t%1$s -Q [processor_set_id] ...\n"
+	    "\t%1$s [-i] [processor_set_id ...]\n"),
+	    progname);
 	return (ERR_USAGE);
 }
 
@@ -699,7 +610,7 @@
 			continue;
 		found++;
 		if (bflag || uflag)
-			bind_lwp(Pr, pid, lwp->pr_lwpid, pset);
+			bind_lwp(pid, lwp->pr_lwpid, pset);
 		else if (binding != PBIND_NONE)
 			query_out(pid, lwp->pr_lwpid, binding);
 	}
@@ -960,7 +871,7 @@
 			pid = (id_t)strtol(*argv, &errptr, 10);
 			if (errno != 0 ||
 			    (errptr != NULL && *errptr != '\0' &&
-				*errptr != '/')) {
+			    *errptr != '/')) {
 				warn(gettext("invalid process ID: %s\n"),
 				    *argv);
 				continue;
--- a/usr/src/lib/libc/common/sys/_pset.s	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/lib/libc/common/sys/_pset.s	Wed Jul 15 00:07:13 2009 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -32,7 +32,7 @@
  * _pset(int subcode, long arg1, long arg2, long arg3, long arg4)
  *
  * Syscall entry point for pset_create, pset_assign, pset_destroy,
- * pset_bind, and pset_info.
+ * pset_bind, pset_bind_lwp and pset_info.
  */
 	SYSCALL2_RVAL1(_pset,pset)
 	RETC
--- a/usr/src/lib/libc/port/llib-lc	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/lib/libc/port/llib-lc	Wed Jul 15 00:07:13 2009 -0700
@@ -1347,6 +1347,8 @@
 int pset_assign_forced(psetid_t pset, processorid_t cpu, psetid_t *opset);
 int pset_info(psetid_t pset, int *type, u_int *numcpus, processorid_t *cpulist);
 int pset_bind(psetid_t pset, idtype_t idtype, id_t id, psetid_t *opset);
+int pset_bind_lwp(psetid_t pset, id_t id, pid_t, psetid_t *opset);
+  
 
 /* rctlsys.c */
 int getrctl(const char *name, rctlblk_t *old_rblk, rctlblk_t *new_rblk,
--- a/usr/src/lib/libc/port/mapfile-vers	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/lib/libc/port/mapfile-vers	Wed Jul 15 00:07:13 2009 -0700
@@ -1605,6 +1605,7 @@
 	__priv_bracket;
 	__priv_relinquish;
 	pset_assign_forced;
+	pset_bind_lwp;
 	_psignal;
 	_pthread_setcleanupinit;
 	__putwchar_xpg5;
--- a/usr/src/lib/libc/port/sys/psetsys.c	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/lib/libc/port/sys/psetsys.c	Wed Jul 15 00:07:13 2009 -0700
@@ -20,22 +20,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#pragma weak _pset_create = pset_create
-#pragma weak _pset_destroy = pset_destroy
-#pragma weak _pset_assign = pset_assign
-#pragma weak _pset_info = pset_info
-#pragma weak _pset_bind = pset_bind
-#pragma weak _pset_getloadavg = pset_getloadavg
-#pragma weak _pset_list = pset_list
-#pragma weak _pset_setattr = pset_setattr
-#pragma weak _pset_getattr = pset_getattr
-
 #include "lint.h"
 #include <sys/types.h>
 #include <sys/procset.h>
@@ -84,6 +72,12 @@
 	return (_pset(PSET_BIND, pset, idtype, id, opset));
 }
 
+int
+pset_bind_lwp(psetid_t pset, id_t id, pid_t pid, psetid_t *opset)
+{
+	return (_pset(PSET_BIND_LWP, pset, id, pid, opset));
+}
+
 /*
  * Get the per-processor-set load average.
  */
--- a/usr/src/lib/libproc/common/libproc.h	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/lib/libproc/common/libproc.h	Wed Jul 15 00:07:13 2009 -0700
@@ -354,8 +354,6 @@
 			int, int, int, void *, int *);
 extern	int	pr_processor_bind(struct ps_prochandle *,
 			idtype_t, id_t, int, int *);
-extern	int	pr_pset_bind(struct ps_prochandle *,
-			int, idtype_t, id_t, int *);
 
 /*
  * Function prototypes for accessing per-LWP register information.
--- a/usr/src/lib/libproc/common/llib-lproc	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/lib/libproc/common/llib-lproc	Wed Jul 15 00:07:13 2009 -0700
@@ -22,7 +22,7 @@
 /* PROTOLIB1 */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 #include "libproc.h"
@@ -304,7 +304,6 @@
 
 /* pr_pbind.c */
 int	pr_processor_bind(struct ps_prochandle *Pr, idtype_t, id_t, int, int *);
-int	pr_pset_bind(struct ps_prochandle *Pr, int, idtype_t, id_t, int *);
 
 /* pr_rename.c */
 int	pr_rename(struct ps_prochandle *Pr, const char *old, const char *new);
--- a/usr/src/lib/libproc/common/mapfile-vers	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/lib/libproc/common/mapfile-vers	Wed Jul 15 00:07:13 2009 -0700
@@ -220,7 +220,6 @@
 	proc_walk;
 	pr_open;
 	pr_processor_bind;
-	pr_pset_bind;
 	pr_rename;
 	pr_setitimer;
 	pr_setprojrctl;
--- a/usr/src/lib/libproc/common/pr_pbind.c	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/lib/libproc/common/pr_pbind.c	Wed Jul 15 00:07:13 2009 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/procset.h>
 #include <sys/processor.h>
@@ -90,66 +87,3 @@
 	}
 	return (rval.sys_rval1);
 }
-
-int
-pr_pset_bind(struct ps_prochandle *Pr, int pset, idtype_t idtype, id_t id,
-    int *opset)
-{
-	sysret_t rval;			/* return value */
-	argdes_t argd[5];		/* arg descriptors */
-	argdes_t *adp = &argd[0];	/* first argument */
-	int error;
-
-	if (Pr == NULL)		/* no subject process */
-		return (pset_bind(pset, idtype, id, opset));
-
-	adp->arg_value = PSET_BIND;	/* PSET_BIND */
-	adp->arg_object = NULL;
-	adp->arg_type = AT_BYVAL;
-	adp->arg_inout = AI_INPUT;
-	adp->arg_size = 0;
-	adp++;
-
-	adp->arg_value = pset;		/* pset */
-	adp->arg_object = NULL;
-	adp->arg_type = AT_BYVAL;
-	adp->arg_inout = AI_INPUT;
-	adp->arg_size = 0;
-	adp++;
-
-	adp->arg_value = idtype;	/* idtype */
-	adp->arg_object = NULL;
-	adp->arg_type = AT_BYVAL;
-	adp->arg_inout = AI_INPUT;
-	adp->arg_size = 0;
-	adp++;
-
-	adp->arg_value = id;		/* id */
-	adp->arg_object = NULL;
-	adp->arg_type = AT_BYVAL;
-	adp->arg_inout = AI_INPUT;
-	adp->arg_size = 0;
-	adp++;
-
-	if (opset == NULL) {
-		adp->arg_value = 0;	/* opset */
-		adp->arg_object = NULL;
-		adp->arg_type = AT_BYVAL;
-		adp->arg_inout = AI_INPUT;
-		adp->arg_size = 0;
-	} else {
-		adp->arg_value = 0;
-		adp->arg_object = opset;
-		adp->arg_type = AT_BYREF;
-		adp->arg_inout = AI_INOUT;
-		adp->arg_size = sizeof (int);
-	}
-
-	error = Psyscall(Pr, &rval, SYS_pset, 5, &argd[0]);
-
-	if (error) {
-		errno = (error < 0)? ENOSYS : error;
-		return (-1);
-	}
-	return (rval.sys_rval1);
-}
--- a/usr/src/uts/common/sys/pset.h	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/uts/common/sys/pset.h	Wed Jul 15 00:07:13 2009 -0700
@@ -19,15 +19,13 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef	_SYS_PSET_H
 #define	_SYS_PSET_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -60,6 +58,7 @@
 extern int	pset_assign(psetid_t, processorid_t, psetid_t *);
 extern int	pset_info(psetid_t, int *, uint_t *, processorid_t *);
 extern int	pset_bind(psetid_t, idtype_t, id_t, psetid_t *);
+extern int	pset_bind_lwp(psetid_t, id_t, pid_t, psetid_t *);
 extern int	pset_getloadavg(psetid_t, double [], int);
 extern int	pset_list(psetid_t *, uint_t *);
 extern int	pset_setattr(psetid_t, uint_t);
@@ -72,6 +71,7 @@
 extern int	pset_assign();
 extern int	pset_info();
 extern int	pset_bind();
+extern int	pset_bind_lwp();
 extern int	pset_getloadavg();
 extern int	pset_list();
 extern int	pset_setattr();
@@ -93,6 +93,7 @@
 #define	PSET_SETATTR		7
 #define	PSET_GETATTR		8
 #define	PSET_ASSIGN_FORCED	9
+#define	PSET_BIND_LWP		10
 
 /* attribute bits */
 #define	PSET_NOESCAPE	0x0001
--- a/usr/src/uts/common/syscall/pset.c	Wed Jul 15 12:37:47 2009 +0800
+++ b/usr/src/uts/common/syscall/pset.c	Wed Jul 15 00:07:13 2009 -0700
@@ -470,6 +470,66 @@
 	return (error);
 }
 
+/*
+ * Bind the lwp:id of process:pid to processor set: pset
+ */
+static int
+pset_bind_lwp(psetid_t pset, id_t id, pid_t pid, psetid_t *opset)
+{
+	kthread_t	*tp;
+	proc_t		*pp;
+	psetid_t	oldpset;
+	void		*projbuf, *zonebuf;
+	int		error = 0;
+
+	pool_lock();
+	mutex_enter(&cpu_lock);
+	projbuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_PROJ);
+	zonebuf = fss_allocbuf(FSS_NPROJ_BUF, FSS_ALLOC_ZONE);
+
+	mutex_enter(&pidlock);
+	if ((pid == P_MYID && id == P_MYID) ||
+	    (pid == curproc->p_pid && id == P_MYID)) {
+		pp = curproc;
+		tp = curthread;
+		mutex_enter(&pp->p_lock);
+	} else {
+		if (pid == P_MYID) {
+			pp = curproc;
+		} else if ((pp = prfind(pid)) == NULL) {
+			error = ESRCH;
+			goto err;
+		}
+		if (pp != curproc && id == P_MYID) {
+			error = EINVAL;
+			goto err;
+		}
+		mutex_enter(&pp->p_lock);
+		if ((tp = idtot(pp, id)) == NULL) {
+			mutex_exit(&pp->p_lock);
+			error = ESRCH;
+			goto err;
+		}
+	}
+
+	error = pset_bind_thread(tp, pset, &oldpset, projbuf, zonebuf);
+	mutex_exit(&pp->p_lock);
+err:
+	mutex_exit(&pidlock);
+
+	fss_freebuf(projbuf, FSS_ALLOC_PROJ);
+	fss_freebuf(zonebuf, FSS_ALLOC_ZONE);
+	mutex_exit(&cpu_lock);
+	pool_unlock();
+	if (opset != NULL) {
+		if (copyout(&oldpset, opset, sizeof (psetid_t)) != 0)
+			return (set_errno(EFAULT));
+	}
+	if (error != 0)
+		return (set_errno(error));
+	return (0);
+}
+
 static int
 pset_bind(psetid_t pset, idtype_t idtype, id_t id, psetid_t *opset)
 {
@@ -797,6 +857,9 @@
 	case PSET_BIND:
 		return (pset_bind((psetid_t)arg1, (idtype_t)arg2,
 		    (id_t)arg3, (psetid_t *)arg4));
+	case PSET_BIND_LWP:
+		return (pset_bind_lwp((psetid_t)arg1, (id_t)arg2,
+		    (pid_t)arg3, (psetid_t *)arg4));
 	case PSET_GETLOADAVG:
 		return (pset_getloadavg((psetid_t)arg1, (int *)arg2,
 		    (int)arg3));