Subject: Re: /etc/rc.d/ runs slowsly
To: None <tech-userlevel@netbsd.org>
From: Simon Burge <simonb@netbsd.org>
List: tech-userlevel
Date: 04/10/2000 01:49:43
[ redirected to tech-userlevel, bcc'd to current-users and dropped
  from port-mips, port-pmax - it's not port specific ]

Simon Burge wrote:

> Manuel Bouyer wrote:
> 
> > On Sat, Apr 08, 2000 at 11:37:31PM -0400, Greg A. Woods wrote:
> > > [...]
> > > WARNING: this patch uses 'fgrep' even though it isn't in /usr/bin.  I
> > > can get away with this because I keep /usr on my root filesystem (where
> > > it belongs! :-).  If it's not appropriate to move 'grep' to /bin for the
> > 
> > Maybe the functionality you're looking for should just be intergrated into
> > ps ?
> 
> How about "ps -n <procname>", modified by -c to pick p_comm instead?
> I'm nearly finished some other ps(1) changes and can easily add this...

How does the following look for just the p_comm comparison, sans man
page info?  Note that the diff might not patch cleanly as I deleted some
non-process name stuff I was working on by hand.  There turned out to
be a bit of work for checking against argv, and I haven't enough time
tonight for that.  I think that the argv work is necessary - look at the
following line from "ps ax":

	816 ??  Is     0:02.84 /usr/pkg/sbin/sshd (sshd1)

Just using p_comm means that a /etc/rc.d/sshd wouldn't find itself,
unless /etc/rc.d/sshd were version aware.  This may crop up with other
things as well, hence my feeling that argv checking is necessary too.

If no one has a problem with this concept, I'll flesh out the argv
stuff when I get a chance.

Simon.
--
Index: extern.h
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/extern.h,v
retrieving revision 1.16
diff -p -u -r1.16 extern.h
--- extern.h	1999/12/03 02:26:36	1.16
+++ extern.h	2000/04/09 15:38:20
@@ -71,7 +71,7 @@ void	 pmem __P((KINFO *, VARENT *));
 void	 pnice __P((KINFO *, VARENT *));
 void	 pri __P((KINFO *, VARENT *));
 void	 printheader __P((void));
-KINFO	*getkinfo_procfs __P((int, int, int*));
+KINFO	*getkinfo_procfs __P((int, int, int *, char *));
 char	**procfs_getargv __P((const struct kinfo_proc *, int));
 void	 pvar __P((KINFO *, VARENT *));
 void	 rssize __P((KINFO *, VARENT *));
Index: procfs_ops.c
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/procfs_ops.c,v
retrieving revision 1.8
diff -p -u -r1.8 procfs_ops.c
--- procfs_ops.c	2000/04/07 18:04:05	1.8
+++ procfs_ops.c	2000/04/09 15:38:20
@@ -201,9 +201,10 @@ parsekinfo(path, ki)
 }
 
 KINFO *
-getkinfo_procfs(op, arg, cnt)
+getkinfo_procfs(op, arg, cnt, procname)
 	int     op, arg;
 	int    *cnt;
+	char   *procname;
 {
 	struct stat statbuf;
 	int     procdirfd, nbytes, knum = 0, maxknum = 0;
@@ -287,6 +288,10 @@ getkinfo_procfs(op, arg, cnt)
 				continue;
 			ki[knum].ki_p = &kp[knum];
 			if (parsekinfo(dp->d_name, &ki[knum]) != 0)
+				continue;
+
+			if (procname != NULL &&
+			    strcmp(procname, kp[knum].kp_proc.p_comm) != 0)
 				continue;
 			/*
 			 * Now check some of the flags.  If the newest entry
Index: ps.c
===================================================================
RCS file: /cvsroot/basesrc/bin/ps/ps.c,v
retrieving revision 1.34
diff -p -u -r1.34 ps.c
--- ps.c	1999/12/04 01:23:09	1.34
+++ ps.c	2000/04/09 15:38:20
@@ -91,7 +91,7 @@ uid_t	myuid;
 
 enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT;
 
-static KINFO	*getkinfo_kvm __P((kvm_t *, int, int, int *, int));
+static KINFO	*getkinfo_kvm __P((kvm_t *, int, int, int *, int, char *));
 static char	*kludge_oldps_options __P((char *));
 static int	 pscomp __P((const void *, const void *));
 static void	 saveuser __P((KINFO *));
@@ -120,7 +120,7 @@ main(argc, argv)
 	int ch, flag, i, fmt, lineno, nentries;
 	int prtheader, wflag, what, xflg;
 	char *nlistf, *memf, *swapf, errbuf[_POSIX2_LINE_MAX];
-	char *ttname;
+	char *ttname, *procname;
 
 	(void)setegid(getgid());
 	if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&ws) == -1 &&
@@ -137,9 +137,9 @@ main(argc, argv)
 	fmt = prtheader = wflag = xflg = 0;
 	what = KERN_PROC_UID;
 	flag = myuid = getuid();
-	memf = nlistf = swapf = NULL;
+	memf = nlistf = swapf = procname = NULL;
 	while ((ch = getopt(argc, argv,
-	    "acCeghjKLlM:mN:O:o:p:rSTt:U:uvW:wx")) != -1)
+	    "acCeghjKLlM:mN:n:O:o:p:rSTt:U:uvW:wx")) != -1)
 		switch((char)ch) {
 		case 'a':
 			what = KERN_PROC_ALL;
@@ -185,6 +185,9 @@ main(argc, argv)
 		case 'N':
 			nlistf = optarg;
 			break;
+		case 'n':
+			procname = optarg;
+			break;
 		case 'O':
 			parsefmt(o1);
 			parsefmt(optarg);
@@ -330,8 +340,8 @@ main(argc, argv)
 	/*
 	 * select procs
 	 */
-	if (!kd || !(kinfo = getkinfo_kvm(kd, what, flag, &nentries, needuser)))
-	{
+	if (!kd || !(kinfo = getkinfo_kvm(kd, what, flag, &nentries, needuser,
+	    procname))) {
 		/*  If/when the /proc-based code is ripped out
 		 *  again, make sure all references to the -K
 		 *  option are also pulled (getopt(), usage(),
@@ -354,7 +364,7 @@ main(argc, argv)
 		}
 		/*  procfs_getprocs supports all but the
 		 *  KERN_PROC_RUID flag.  */
-		kinfo = getkinfo_procfs(what, flag, &nentries);
+		kinfo = getkinfo_procfs(what, flag, &nentries, procname);
 		if (kinfo == 0) {
 		  errx(1, "fallback /proc-based lookup also failed.  %s",
 				  "Giving up...");
@@ -401,23 +411,29 @@ main(argc, argv)
 }
 
 static KINFO *
-getkinfo_kvm(kd, what, flag, nentriesp, needuser)
+getkinfo_kvm(kd, what, flag, nentriesp, needuser, procname)
 	kvm_t *kd;
 	int what, flag, *nentriesp, needuser;
+	char *procname;
 {
 	struct kinfo_proc *kp;
-	KINFO *kinfo=NULL;
-	size_t i;
+	KINFO *kinfo = NULL;
+	int i, total;
 
-	if ((kp = kvm_getprocs(kd, what, flag, nentriesp)) != 0)
-	{
+	if ((kp = kvm_getprocs(kd, what, flag, nentriesp)) != 0) {
+		total = 0;
 		if ((kinfo = malloc((*nentriesp) * sizeof(*kinfo))) == NULL)
 			err(1, NULL);
 		for (i = (*nentriesp); i-- > 0; kp++) {
-			kinfo[i].ki_p = kp;
-			if (needuser)
-				saveuser(&kinfo[i]);
+			if (procname == NULL ||
+			    strcmp(procname, kp->kp_proc.p_comm) == 0) {
+				kinfo[total].ki_p = kp;
+				if (needuser)
+					saveuser(&kinfo[total]);
+				total++;
+			}
 		}
+		*nentriesp = total;
 	}
 
 	return (kinfo);