我想了解FreeBSD内核如何分配pids?
我找到了following code:
186 static int randompid = 0;
187
188 static int
189 sysctl_kern_randompid(SYSCTL_HANDLER_ARGS)
190 {
191 int error, pid;
192
193 error = sysctl_wire_old_buffer(req, sizeof(int));
194 if (error != 0)
195 return(error);
196 sx_xlock(&allproc_lock);
197 pid = randompid;
198 error = sysctl_handle_int(oidp, &pid, 0, req);
199 if (error == 0 && req->newptr != NULL) {
200 if (pid < 0 || pid > pid_max - 100) /* out of range */
201 pid = pid_max - 100;
202 else if (pid < 2) /* NOP */
203 pid = 0;
204 else if (pid < 100) /* Make it reasonable */
205 pid = 100;
206 randompid = pid;
207 }
208 sx_xunlock(&allproc_lock);
209 return (error);
210 }
211
212 SYSCTL_PROC(_kern, OID_AUTO, randompid, CTLTYPE_INT|CTLFLAG_RW,
213 0, 0, sysctl_kern_randompid, "I", "Random PID modulus");
214
215 static int
216 fork_findpid(int flags)
217 {
218 struct proc *p;
219 int trypid;
220 static int pidchecked = 0;
221
222 /*
223 * Requires allproc_lock in order to iterate over the list
224 * of processes, and proctree_lock to access p_pgrp.
225 */
226 sx_assert(&allproc_lock, SX_LOCKED);
227 sx_assert(&proctree_lock, SX_LOCKED);
228
229 /*
230 * Find an unused process ID. We remember a range of unused IDs
231 * ready to use (from lastpid+1 through pidchecked-1).
232 *
233 * If RFHIGHPID is set (used during system boot), do not allocate
234 * low-numbered pids.
235 */
236 trypid = lastpid + 1;
237 if (flags & RFHIGHPID) {
238 if (trypid < 10)
239 trypid = 10;
240 } else {
241 if (randompid)
242 trypid += arc4random() % randompid;
243 }
244 retry:
245 /*
246 * If the process ID prototype has wrapped around,
247 * restart somewhat above 0, as the low-numbered procs
248 * tend to include daemons that don't exit.
249 */
250 if (trypid >= pid_max) {
251 trypid = trypid % pid_max;
252 if (trypid < 100)
253 trypid += 100;
254 pidchecked = 0;
255 }
256 if (trypid >= pidchecked) {
257 int doingzomb = 0;
258
259 pidchecked = PID_MAX;
260 /*
261 * Scan the active and zombie procs to check whether this pid
262 * is in use. Remember the lowest pid that's greater
263 * than trypid, so we can avoid checking for a while.
264 */
265 p = LIST_FIRST(&allproc);
266 again:
267 for (; p != NULL; p = LIST_NEXT(p, p_list)) {
268 while (p->p_pid == trypid ||
269 (p->p_pgrp != NULL &&
270 (p->p_pgrp->pg_id == trypid ||
271 (p->p_session != NULL &&
272 p->p_session->s_sid == trypid)))) {
273 trypid++;
274 if (trypid >= pidchecked)
275 goto retry;
276 }
277 if (p->p_pid > trypid && pidchecked > p->p_pid)
278 pidchecked = p->p_pid;
279 if (p->p_pgrp != NULL) {
280 if (p->p_pgrp->pg_id > trypid &&
281 pidchecked > p->p_pgrp->pg_id)
282 pidchecked = p->p_pgrp->pg_id;
283 if (p->p_session != NULL &&
284 p->p_session->s_sid > trypid &&
285 pidchecked > p->p_session->s_sid)
286 pidchecked = p->p_session->s_sid;
287 }
288 }
289 if (!doingzomb) {
290 doingzomb = 1;
291 p = LIST_FIRST(&zombproc);
292 goto again;
293 }
294
296 /*
297 * RFHIGHPID does not mess with the lastpid counter during boot.
298 */
299 if (flags & RFHIGHPID)
300 pidchecked = 0;
301 else
302 lastpid = trypid;
303
304 return (trypid);
305 }
306
但我有一些问题:
答案 0 :(得分:1)
为什么会出现随机性?这实际上增加了安全性吗?或者这只是为了帮助创建碎片?
随机PID不会增加太多安全性。随机PID的重点是使PID更有可能在空间中可用,以减少冲突的可能性。
为什么此代码必须尝试&#39;一个pid?这段代码有点活泼吗?如果多个进程同时尝试获取pid会发生什么?
仔细观察,整个事物都有锁定。 &#39;尝试&#39;部分是它扫描僵尸列表和其他列表。
是否可以使用特定的pid启动进程?
没有