* stop_all_proc() purpose is to stop all process which have usermode, * except current process for obvious reasons. This makes it somewhat * unreliable when invoked from multithreaded process. The service * must not be user-callable anyway. */
| 3236 | * must not be user-callable anyway. |
| 3237 | */ |
| 3238 | void |
| 3239 | stop_all_proc(void) |
| 3240 | { |
| 3241 | struct proc *cp, *p; |
| 3242 | int r, gen; |
| 3243 | bool restart, seen_stopped, seen_exiting, stopped_some; |
| 3244 | |
| 3245 | cp = curproc; |
| 3246 | allproc_loop: |
| 3247 | sx_xlock(&allproc_lock); |
| 3248 | gen = allproc_gen; |
| 3249 | seen_exiting = seen_stopped = stopped_some = restart = false; |
| 3250 | LIST_REMOVE(cp, p_list); |
| 3251 | LIST_INSERT_HEAD(&allproc, cp, p_list); |
| 3252 | for (;;) { |
| 3253 | p = LIST_NEXT(cp, p_list); |
| 3254 | if (p == NULL) |
| 3255 | break; |
| 3256 | LIST_REMOVE(cp, p_list); |
| 3257 | LIST_INSERT_AFTER(p, cp, p_list); |
| 3258 | PROC_LOCK(p); |
| 3259 | if ((p->p_flag & (P_KPROC | P_SYSTEM | P_TOTAL_STOP)) != 0) { |
| 3260 | PROC_UNLOCK(p); |
| 3261 | continue; |
| 3262 | } |
| 3263 | if ((p->p_flag & P_WEXIT) != 0) { |
| 3264 | seen_exiting = true; |
| 3265 | PROC_UNLOCK(p); |
| 3266 | continue; |
| 3267 | } |
| 3268 | if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE) { |
| 3269 | /* |
| 3270 | * Stopped processes are tolerated when there |
| 3271 | * are no other processes which might continue |
| 3272 | * them. P_STOPPED_SINGLE but not |
| 3273 | * P_TOTAL_STOP process still has at least one |
| 3274 | * thread running. |
| 3275 | */ |
| 3276 | seen_stopped = true; |
| 3277 | PROC_UNLOCK(p); |
| 3278 | continue; |
| 3279 | } |
| 3280 | sx_xunlock(&allproc_lock); |
| 3281 | _PHOLD(p); |
| 3282 | r = thread_single(p, SINGLE_ALLPROC); |
| 3283 | if (r != 0) |
| 3284 | restart = true; |
| 3285 | else |
| 3286 | stopped_some = true; |
| 3287 | _PRELE(p); |
| 3288 | PROC_UNLOCK(p); |
| 3289 | sx_xlock(&allproc_lock); |
| 3290 | } |
| 3291 | /* Catch forked children we did not see in iteration. */ |
| 3292 | if (gen != allproc_gen) |
| 3293 | restart = true; |
| 3294 | sx_xunlock(&allproc_lock); |
| 3295 | if (restart || stopped_some || seen_exiting || seen_stopped) { |
no test coverage detected