xref: /netbsd-src/sys/ddb/db_proc.c (revision 127563b6bc037f6d17d9053be957dc48fabf3111)
1*127563b6Sskrll /*	$NetBSD: db_proc.c,v 1.16 2024/04/15 06:48:06 skrll Exp $	*/
2cd6b1c8fSad 
3cd6b1c8fSad /*-
482002773Sad  * Copyright (c) 2009, 2020 The NetBSD Foundation, Inc.
5cd6b1c8fSad  * All rights reserved.
6cd6b1c8fSad  *
7cd6b1c8fSad  * This code is derived from software contributed to The NetBSD Foundation
8cd6b1c8fSad  * by Andrew Doran.
9cd6b1c8fSad  *
10cd6b1c8fSad  * Redistribution and use in source and binary forms, with or without
11cd6b1c8fSad  * modification, are permitted provided that the following conditions
12cd6b1c8fSad  * are met:
13cd6b1c8fSad  * 1. Redistributions of source code must retain the above copyright
14cd6b1c8fSad  *    notice, this list of conditions and the following disclaimer.
15cd6b1c8fSad  * 2. Redistributions in binary form must reproduce the above copyright
16cd6b1c8fSad  *    notice, this list of conditions and the following disclaimer in the
17cd6b1c8fSad  *    documentation and/or other materials provided with the distribution.
18cd6b1c8fSad  *
19cd6b1c8fSad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20cd6b1c8fSad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21cd6b1c8fSad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22cd6b1c8fSad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23cd6b1c8fSad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24cd6b1c8fSad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25cd6b1c8fSad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26cd6b1c8fSad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27cd6b1c8fSad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28cd6b1c8fSad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29cd6b1c8fSad  * POSSIBILITY OF SUCH DAMAGE.
30cd6b1c8fSad  */
31cd6b1c8fSad 
32cd6b1c8fSad /*
33cd6b1c8fSad  * Copyright (c) 1982, 1986, 1989, 1991, 1993
34cd6b1c8fSad  *	The Regents of the University of California.  All rights reserved.
35cd6b1c8fSad  *
36cd6b1c8fSad  * Redistribution and use in source and binary forms, with or without
37cd6b1c8fSad  * modification, are permitted provided that the following conditions
38cd6b1c8fSad  * are met:
39cd6b1c8fSad  * 1. Redistributions of source code must retain the above copyright
40cd6b1c8fSad  *    notice, this list of conditions and the following disclaimer.
41cd6b1c8fSad  * 2. Redistributions in binary form must reproduce the above copyright
42cd6b1c8fSad  *    notice, this list of conditions and the following disclaimer in the
43cd6b1c8fSad  *    documentation and/or other materials provided with the distribution.
44cd6b1c8fSad  * 3. Neither the name of the University nor the names of its contributors
45cd6b1c8fSad  *    may be used to endorse or promote products derived from this software
46cd6b1c8fSad  *    without specific prior written permission.
47cd6b1c8fSad  *
48cd6b1c8fSad  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49cd6b1c8fSad  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50cd6b1c8fSad  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51cd6b1c8fSad  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52cd6b1c8fSad  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53cd6b1c8fSad  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54cd6b1c8fSad  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55cd6b1c8fSad  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56cd6b1c8fSad  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57cd6b1c8fSad  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58cd6b1c8fSad  * SUCH DAMAGE.
59cd6b1c8fSad  *
60cd6b1c8fSad  *	from: kern_proc.c	8.4 (Berkeley) 1/4/94
61cd6b1c8fSad  */
62cd6b1c8fSad 
63cd6b1c8fSad #include <sys/cdefs.h>
64*127563b6Sskrll __KERNEL_RCSID(0, "$NetBSD: db_proc.c,v 1.16 2024/04/15 06:48:06 skrll Exp $");
65d2ea53a0Smrg 
66d2ea53a0Smrg #ifndef _KERNEL
67d2ea53a0Smrg #include <stdbool.h>
68d2ea53a0Smrg #endif
69cd6b1c8fSad 
70cd6b1c8fSad #include <sys/param.h>
71cd6b1c8fSad #include <sys/cpu.h>
72cd6b1c8fSad #include <sys/proc.h>
73d2ea53a0Smrg #ifdef _KERNEL	/* XXX */
74cd6b1c8fSad #include <sys/kauth.h>
75d2ea53a0Smrg #endif
76cd6b1c8fSad 
774540375fSmrg #include <ddb/ddb.h>
784540375fSmrg 
79cd6b1c8fSad proc_t *
db_proc_first(void)80cd6b1c8fSad db_proc_first(void)
81cd6b1c8fSad {
82cd6b1c8fSad 
83cd6b1c8fSad 	return db_read_ptr("allproc");
84cd6b1c8fSad }
85cd6b1c8fSad 
86cd6b1c8fSad proc_t *
db_proc_next(proc_t * p)87cd6b1c8fSad db_proc_next(proc_t *p)
88cd6b1c8fSad {
89cd6b1c8fSad 
90cd6b1c8fSad 	db_read_bytes((db_addr_t)&p->p_list.le_next, sizeof(p), (char *)&p);
91cd6b1c8fSad 	return p;
92cd6b1c8fSad }
93cd6b1c8fSad 
94cd6b1c8fSad proc_t *
db_proc_find(pid_t pid)95cd6b1c8fSad db_proc_find(pid_t pid)
96cd6b1c8fSad {
97cd6b1c8fSad 	proc_t *p;
98cd6b1c8fSad 	pid_t tp;
99cd6b1c8fSad 
100cd6b1c8fSad 	for (p = db_proc_first(); p != NULL; p = db_proc_next(p)) {
101cd6b1c8fSad 		db_read_bytes((db_addr_t)&p->p_pid, sizeof(tp),
102cd6b1c8fSad 		    (char *)&tp);
103cd6b1c8fSad 		if (tp == pid) {
104cd6b1c8fSad 			return p;
105cd6b1c8fSad 		}
106cd6b1c8fSad 	}
107cd6b1c8fSad 	return NULL;
108cd6b1c8fSad }
109cd6b1c8fSad 
1107c827ea2Smaxv static void
db_read_string(const char * src,size_t len,char * dst)1117c827ea2Smaxv db_read_string(const char *src, size_t len, char *dst)
1127c827ea2Smaxv {
1137c827ea2Smaxv 	size_t i;
1147c827ea2Smaxv 
1157c827ea2Smaxv 	for (i = 0; i < len; i++) {
1167c827ea2Smaxv 		db_read_bytes((db_addr_t)&src[i], 1, &dst[i]);
117038a8e9aSmaxv 		if (dst[i] == '\0')
1187c827ea2Smaxv 			break;
1197c827ea2Smaxv 	}
1207c827ea2Smaxv }
1217c827ea2Smaxv 
122cd6b1c8fSad void
db_show_all_procs(db_expr_t addr,bool haddr,db_expr_t count,const char * modif)123cd6b1c8fSad db_show_all_procs(db_expr_t addr, bool haddr, db_expr_t count,
124cd6b1c8fSad 		  const char *modif)
125cd6b1c8fSad {
126cd6b1c8fSad 	static struct pgrp pgrp;
127cd6b1c8fSad 	static proc_t p;
128cd6b1c8fSad 	static lwp_t l;
129cd6b1c8fSad 	const char *mode, *ename;
130cd6b1c8fSad 	proc_t *pp;
131cd6b1c8fSad 	lwp_t *lp;
132cd6b1c8fSad 	char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1];
133cd6b1c8fSad 	bool run;
134cd6b1c8fSad 	int cpuno;
135cd6b1c8fSad 
136cd6b1c8fSad 	if (modif[0] == 0)
137cd6b1c8fSad 		mode = "l";			/* default == lwp mode */
138cd6b1c8fSad 	else
139cd6b1c8fSad 		mode = strchr("mawln", modif[0]);
140cd6b1c8fSad 
141cd6b1c8fSad 	if (mode == NULL || *mode == 'm') {
142cd6b1c8fSad 		db_printf("usage: show all procs [/a] [/l] [/n] [/w]\n");
143cd6b1c8fSad 		db_printf("\t/a == show process address info\n");
1442a672d40Schristos 		db_printf("\t/l == show LWP info [default]\n");
1452a672d40Schristos 		db_printf("\t/n == show normal process info\n");
146cd6b1c8fSad 		db_printf("\t/w == show process wait/emul info\n");
147cd6b1c8fSad 		return;
148cd6b1c8fSad 	}
149cd6b1c8fSad 
150cd6b1c8fSad 	switch (*mode) {
151cd6b1c8fSad 	case 'a':
1520df87276Ssimonb 		db_printf("PID   %-16s %18s %18s %18s\n",
153cd6b1c8fSad 		    "COMMAND", "STRUCT PROC *", "UAREA *", "VMSPACE/VM_MAP");
154cd6b1c8fSad 		break;
155cd6b1c8fSad 	case 'l':
156*127563b6Sskrll 		db_printf("PID   %5s S %3s %9s %18s %18s %-8s\n",
157cd6b1c8fSad 		    "LID", "CPU", "FLAGS", "STRUCT LWP *", "NAME", "WAIT");
158cd6b1c8fSad 		break;
159cd6b1c8fSad 	case 'n':
160cd6b1c8fSad 		db_printf("PID  %8s %8s %10s S %7s %4s %16s %7s\n",
161cd6b1c8fSad 		    "PPID", "PGRP", "UID", "FLAGS", "LWPS", "COMMAND", "WAIT");
162cd6b1c8fSad 		break;
163cd6b1c8fSad 	case 'w':
164*127563b6Sskrll 		db_printf("PID   %5s %16s %8s %4s %-16s %s\n",
165cd6b1c8fSad 		    "LID", "COMMAND", "EMUL", "PRI", "WAIT-MSG",
166cd6b1c8fSad 		    "WAIT-CHANNEL");
167cd6b1c8fSad 		break;
168cd6b1c8fSad 	}
169cd6b1c8fSad 
170cd6b1c8fSad 	for (pp = db_proc_first(); pp != NULL; pp = db_proc_next(pp)) {
171cd6b1c8fSad 		db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p);
172cd6b1c8fSad 		if (p.p_stat == 0) {
173cd6b1c8fSad 			continue;
174cd6b1c8fSad 		}
175cd6b1c8fSad 		lp = p.p_lwps.lh_first;
176cd6b1c8fSad 		if (lp != NULL) {
177cd6b1c8fSad 			db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
178cd6b1c8fSad 		}
179cd6b1c8fSad 		db_printf("%-5d", p.p_pid);
180cd6b1c8fSad 
181cd6b1c8fSad 		switch (*mode) {
182cd6b1c8fSad 		case 'a':
1830df87276Ssimonb 			db_printf(" %-16.16s %18lx %18lx %18lx\n",
184cd6b1c8fSad 			    p.p_comm, (long)pp,
185cd6b1c8fSad 			    (long)(lp != NULL ? l.l_addr : 0),
186cd6b1c8fSad 			    (long)p.p_vmspace);
187cd6b1c8fSad 			break;
188cd6b1c8fSad 		case 'l':
189cd6b1c8fSad 			 while (lp != NULL) {
190cd6b1c8fSad 			 	if (l.l_name != NULL) {
1917c827ea2Smaxv 					db_read_string(l.l_name,
192cd6b1c8fSad 					    MAXCOMLEN, db_nbuf);
1937c827ea2Smaxv 					db_nbuf[MAXCOMLEN] = '\0';
194cd6b1c8fSad 				} else {
195cd6b1c8fSad 					strlcpy(db_nbuf, p.p_comm,
196cd6b1c8fSad 					    sizeof(db_nbuf));
197cd6b1c8fSad 				}
198cd6b1c8fSad 				run = (l.l_stat == LSONPROC ||
19982002773Sad 				    (l.l_pflag & LP_RUNNING) != 0);
200cd6b1c8fSad 				if (l.l_cpu != NULL) {
201cd6b1c8fSad 					db_read_bytes((db_addr_t)
202cd6b1c8fSad 					    &l.l_cpu->ci_data.cpu_index,
203cd6b1c8fSad 					    sizeof(cpuno), (char *)&cpuno);
204cd6b1c8fSad 				} else
205cd6b1c8fSad 					cpuno = -1;
206cd6b1c8fSad 				if (l.l_wchan && l.l_wmesg) {
2077c827ea2Smaxv 					db_read_string(l.l_wmesg,
2087c827ea2Smaxv 					    sizeof(wbuf), wbuf);
2097c827ea2Smaxv 					wbuf[MAXCOMLEN] = '\0';
210cd6b1c8fSad 				} else {
211cd6b1c8fSad 					wbuf[0] = '\0';
212cd6b1c8fSad 				}
213*127563b6Sskrll 				db_printf("%c%5d %d %3d %9x %18lx %18s %-8s\n",
214cd6b1c8fSad 				    (run ? '>' : ' '), l.l_lid,
215cd6b1c8fSad 				    l.l_stat, cpuno, l.l_flag, (long)lp,
216cd6b1c8fSad 				    db_nbuf, wbuf);
217cd6b1c8fSad 				lp = LIST_NEXT((&l), l_sibling);
218cd6b1c8fSad 				if (lp != NULL) {
219cd6b1c8fSad 					db_printf("%-5d", p.p_pid);
220cd6b1c8fSad 					db_read_bytes((db_addr_t)lp, sizeof(l),
221cd6b1c8fSad 					    (char *)&l);
222cd6b1c8fSad 				}
223cd6b1c8fSad 			}
224cd6b1c8fSad 			break;
225cd6b1c8fSad 		case 'n':
226cd6b1c8fSad 			db_read_bytes((db_addr_t)p.p_pgrp, sizeof(pgrp),
227cd6b1c8fSad 			    (char *)&pgrp);
228cd6b1c8fSad 			if (lp != NULL && l.l_wchan && l.l_wmesg) {
2297c827ea2Smaxv 				db_read_string(l.l_wmesg,
2307c827ea2Smaxv 				    sizeof(wbuf), wbuf);
2317c827ea2Smaxv 				wbuf[MAXCOMLEN] = '\0';
232cd6b1c8fSad 			} else {
233cd6b1c8fSad 				wbuf[0] = '\0';
234cd6b1c8fSad 			}
235cd6b1c8fSad 			db_printf("%8d %8d %10d %d %#7x %4d %16s %7.7s\n",
2365a05c3b8Shikaru 			    p.p_pptr != NULL ? p.p_pptr->p_pid : -1, pgrp.pg_id,
237cd6b1c8fSad #ifdef _KERNEL
238cd6b1c8fSad 			    kauth_cred_getuid(p.p_cred),
239cd6b1c8fSad #else
240cd6b1c8fSad 			    /* XXX CRASH(8) */ 666,
241cd6b1c8fSad #endif
242cd6b1c8fSad 			    p.p_stat, p.p_flag,
243cd6b1c8fSad 			    p.p_nlwps, p.p_comm,
244cd6b1c8fSad 			    (p.p_nlwps != 1) ? "*" : wbuf);
245cd6b1c8fSad 			break;
246cd6b1c8fSad 
247cd6b1c8fSad 		case 'w':
248cd6b1c8fSad 			 while (lp != NULL) {
249cd6b1c8fSad 				if (l.l_wchan && l.l_wmesg) {
2507c827ea2Smaxv 					db_read_string(l.l_wmesg,
2517c827ea2Smaxv 					    sizeof(wbuf), wbuf);
2527c827ea2Smaxv 					wbuf[MAXCOMLEN] = '\0';
253cd6b1c8fSad 				} else {
254cd6b1c8fSad 					wbuf[0] = '\0';
255cd6b1c8fSad 				}
2560f329bf7Sjym 				run = (l.l_stat == LSONPROC ||
25782002773Sad 				    (l.l_pflag & LP_RUNNING) != 0);
258cd6b1c8fSad 				db_read_bytes((db_addr_t)&p.p_emul->e_name,
259cd6b1c8fSad 				    sizeof(ename), (char *)&ename);
2607c827ea2Smaxv 
2617c827ea2Smaxv 				db_read_string(ename, sizeof(db_nbuf), db_nbuf);
2627c827ea2Smaxv 				db_nbuf[MAXCOMLEN] = '\0';
2637c827ea2Smaxv 
264cd6b1c8fSad 				db_printf(
265*127563b6Sskrll 				    "%c%5d %16s %8s %4d %-16s %-18lx\n",
2660f329bf7Sjym 				    (run ? '>' : ' '), l.l_lid,
2670f329bf7Sjym 				    p.p_comm, db_nbuf,
268cd6b1c8fSad 				    l.l_priority, wbuf, (long)l.l_wchan);
269cd6b1c8fSad 				lp = LIST_NEXT((&l), l_sibling);
270cd6b1c8fSad 				if (lp != NULL) {
271cd6b1c8fSad 					db_printf("%-5d", p.p_pid);
272cd6b1c8fSad 					db_read_bytes((db_addr_t)lp, sizeof(l),
273cd6b1c8fSad 					    (char *)&l);
274cd6b1c8fSad 				}
275cd6b1c8fSad 			}
276cd6b1c8fSad 			break;
277cd6b1c8fSad 		}
278cd6b1c8fSad 	}
279cd6b1c8fSad }
280cd6b1c8fSad 
2812a672d40Schristos void
db_show_proc(db_expr_t addr,bool haddr,db_expr_t count,const char * modif)2822a672d40Schristos db_show_proc(db_expr_t addr, bool haddr, db_expr_t count, const char *modif)
2832a672d40Schristos {
2842a672d40Schristos 	static proc_t p;
2852a672d40Schristos 	static lwp_t l;
2862a672d40Schristos 	const char *mode;
2872a672d40Schristos 	proc_t *pp;
2882a672d40Schristos 	lwp_t *lp;
2892a672d40Schristos 	char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1];
2902a672d40Schristos 	bool run;
2912a672d40Schristos 	int cpuno;
2922a672d40Schristos 
2932a672d40Schristos 	if (modif[0] == 0)
2942a672d40Schristos 		mode = "p";			/* default == by pid */
2952a672d40Schristos 	else
2962a672d40Schristos 		mode = strchr("ap", modif[0]);
2972a672d40Schristos 
2982a672d40Schristos 	if (mode == NULL || !haddr) {
2992a672d40Schristos 		db_printf("usage: show proc [/a] [/p] address|pid\n");
3002a672d40Schristos 		db_printf("\t/a == argument is an address of any lwp\n");
3012a672d40Schristos 		db_printf("\t/p == argument is a pid [default]\n");
3022a672d40Schristos 		return;
3032a672d40Schristos 	}
3042a672d40Schristos 
3052a672d40Schristos 	switch (*mode) {
3062a672d40Schristos 	case 'a':
30720cb9e7fSnakayama 		lp = (lwp_t *)(uintptr_t)addr;
3082a672d40Schristos 		db_printf("lwp_t %lx\n", (long)lp);
3092a672d40Schristos 		db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
3102a672d40Schristos 		pp = l.l_proc;
3112a672d40Schristos 		break;
3122a672d40Schristos 	default:
3132a672d40Schristos 	case 'p':
3142a672d40Schristos 		pp = db_proc_find((pid_t)addr);
3152a672d40Schristos 		lp = NULL;
3162a672d40Schristos 		break;
3172a672d40Schristos 	}
3182a672d40Schristos 
3192a672d40Schristos 	if (pp == NULL) {
3202a672d40Schristos 		db_printf("bad address\n");
3212a672d40Schristos 		return;
3222a672d40Schristos 	}
3232a672d40Schristos 
3242a672d40Schristos 	db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p);
3252a672d40Schristos 	if (lp == NULL)
3262a672d40Schristos 		lp = p.p_lwps.lh_first;
3272a672d40Schristos 
3282a672d40Schristos 	db_printf("%s: pid %d proc %lx vmspace/map %lx flags %x\n",
3292a672d40Schristos 	    p.p_comm, p.p_pid, (long)pp, (long)p.p_vmspace, p.p_flag);
3302a672d40Schristos 
3312a672d40Schristos 	while (lp != NULL) {
3322a672d40Schristos 		db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
3332a672d40Schristos 
3342a672d40Schristos 		run = (l.l_stat == LSONPROC ||
33582002773Sad 		    (l.l_pflag & LP_RUNNING) != 0);
3362a672d40Schristos 
3372a672d40Schristos 		db_printf("%slwp %d", (run ? "> " : "  "), l.l_lid);
3382a672d40Schristos 		if (l.l_name != NULL) {
3397c827ea2Smaxv 			db_read_string(l.l_name, MAXCOMLEN, db_nbuf);
3407c827ea2Smaxv 			db_nbuf[MAXCOMLEN] = '\0';
3412a672d40Schristos 			db_printf(" [%s]", db_nbuf);
3422a672d40Schristos 		}
3432a672d40Schristos 		db_printf(" %lx pcb %lx\n", (long)lp, (long)l.l_addr);
3442a672d40Schristos 
3452a672d40Schristos 		if (l.l_cpu != NULL) {
3462a672d40Schristos 			db_read_bytes((db_addr_t)
3472a672d40Schristos 			    &l.l_cpu->ci_data.cpu_index,
3482a672d40Schristos 			    sizeof(cpuno), (char *)&cpuno);
3492a672d40Schristos 		} else
3502a672d40Schristos 			cpuno = -1;
35106d11bb0Smlelstv 		db_printf("    stat %d flags %x cpu %d pri %d ref %d\n",
35206d11bb0Smlelstv 		    l.l_stat, l.l_flag, cpuno, l.l_priority, l.l_refcnt);
3532a672d40Schristos 
3542a672d40Schristos 		if (l.l_wchan && l.l_wmesg) {
3557c827ea2Smaxv 			db_read_string(l.l_wmesg, MAXCOMLEN, wbuf);
3567c827ea2Smaxv 			wbuf[MAXCOMLEN] = '\0';
3572a672d40Schristos 			db_printf("    wmesg %s wchan %lx\n",
3582a672d40Schristos 			    wbuf, (long)l.l_wchan);
3592a672d40Schristos 		}
3602a672d40Schristos 
3612a672d40Schristos 		lp = LIST_NEXT(&l, l_sibling);
3622a672d40Schristos 	}
3632a672d40Schristos }
364