1 1.5 thorpej /* $NetBSD: kern_reboot.c,v 1.5 2024/03/05 14:15:36 thorpej Exp $ */ 2 1.1 mrg 3 1.1 mrg /* 4 1.1 mrg * Copyright (c) 1982, 1986, 1989, 1993 5 1.1 mrg * The Regents of the University of California. All rights reserved. 6 1.1 mrg * 7 1.1 mrg * Redistribution and use in source and binary forms, with or without 8 1.1 mrg * modification, are permitted provided that the following conditions 9 1.1 mrg * are met: 10 1.1 mrg * 1. Redistributions of source code must retain the above copyright 11 1.1 mrg * notice, this list of conditions and the following disclaimer. 12 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 mrg * notice, this list of conditions and the following disclaimer in the 14 1.1 mrg * documentation and/or other materials provided with the distribution. 15 1.1 mrg * 3. Neither the name of the University nor the names of its contributors 16 1.1 mrg * may be used to endorse or promote products derived from this software 17 1.1 mrg * without specific prior written permission. 18 1.1 mrg * 19 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 mrg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 mrg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 mrg * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 mrg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 mrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 mrg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 mrg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 mrg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 mrg * SUCH DAMAGE. 30 1.1 mrg * 31 1.1 mrg * @(#)kern_xxx.c 8.3 (Berkeley) 2/14/95 32 1.1 mrg * from: NetBSD: kern_xxx.c,v 1.74 2017/10/28 00:37:11 pgoyette Exp 33 1.1 mrg */ 34 1.1 mrg 35 1.1 mrg #include <sys/cdefs.h> 36 1.5 thorpej __KERNEL_RCSID(0, "$NetBSD: kern_reboot.c,v 1.5 2024/03/05 14:15:36 thorpej Exp $"); 37 1.1 mrg 38 1.3 ad #include <sys/atomic.h> 39 1.1 mrg #include <sys/param.h> 40 1.1 mrg #include <sys/systm.h> 41 1.1 mrg #include <sys/proc.h> 42 1.1 mrg #include <sys/reboot.h> 43 1.1 mrg #include <sys/syscall.h> 44 1.1 mrg #include <sys/syscallargs.h> 45 1.2 thorpej #include <sys/kernel.h> 46 1.1 mrg #include <sys/kauth.h> 47 1.5 thorpej #include <sys/timevar.h> 48 1.1 mrg 49 1.2 thorpej /* 50 1.2 thorpej * Reboot / shutdown the system. 51 1.2 thorpej */ 52 1.2 thorpej void 53 1.2 thorpej kern_reboot(int howto, char *bootstr) 54 1.2 thorpej { 55 1.4 ad static lwp_t *rebooter; 56 1.4 ad lwp_t *l; 57 1.2 thorpej 58 1.3 ad /* 59 1.3 ad * If already rebooting then just hang out. Allow reentry for the 60 1.3 ad * benfit of ddb, even if questionable. It would be better to call 61 1.3 ad * exit1(), but this is called from all sorts of places. 62 1.3 ad */ 63 1.3 ad l = atomic_cas_ptr(&rebooter, NULL, curlwp); 64 1.3 ad while (l != NULL && l != curlwp) { 65 1.3 ad (void)kpause("reboot", true, 0, NULL); 66 1.3 ad } 67 1.2 thorpej shutting_down = 1; 68 1.2 thorpej 69 1.5 thorpej /* Just cut to the chase if cold. */ 70 1.5 thorpej if (cold) { 71 1.5 thorpej goto do_cpu_reboot; 72 1.5 thorpej } 73 1.5 thorpej 74 1.5 thorpej if ((boothowto & RB_NOSYNC) == 0 && panicstr == NULL) { 75 1.5 thorpej /* 76 1.5 thorpej * If we've been adjusting the clock, the todr 77 1.5 thorpej * will be out of synch; adjust it now. 78 1.5 thorpej */ 79 1.5 thorpej if (time_adjusted != 0) { 80 1.5 thorpej time_adjusted = 0; 81 1.5 thorpej resettodr(); 82 1.5 thorpej } 83 1.5 thorpej } 84 1.5 thorpej 85 1.2 thorpej /* 86 1.2 thorpej * XXX We should re-factor out all of the common stuff 87 1.2 thorpej * that each and every cpu_reboot() does and put it here. 88 1.2 thorpej */ 89 1.2 thorpej 90 1.5 thorpej do_cpu_reboot: 91 1.2 thorpej cpu_reboot(howto, bootstr); 92 1.2 thorpej } 93 1.2 thorpej 94 1.1 mrg /* ARGSUSED */ 95 1.1 mrg int 96 1.1 mrg sys_reboot(struct lwp *l, const struct sys_reboot_args *uap, register_t *retval) 97 1.1 mrg { 98 1.1 mrg /* { 99 1.1 mrg syscallarg(int) opt; 100 1.1 mrg syscallarg(char *) bootstr; 101 1.1 mrg } */ 102 1.1 mrg int error; 103 1.1 mrg char *bootstr, bs[128]; 104 1.1 mrg 105 1.1 mrg if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_REBOOT, 106 1.1 mrg 0, NULL, NULL, NULL)) != 0) 107 1.1 mrg return (error); 108 1.1 mrg 109 1.1 mrg /* 110 1.1 mrg * Only use the boot string if RB_STRING is set. 111 1.1 mrg */ 112 1.1 mrg if ((SCARG(uap, opt) & RB_STRING) && 113 1.1 mrg (error = copyinstr(SCARG(uap, bootstr), bs, sizeof(bs), 0)) == 0) 114 1.1 mrg bootstr = bs; 115 1.1 mrg else 116 1.1 mrg bootstr = NULL; 117 1.1 mrg /* 118 1.1 mrg * Not all ports use the bootstr currently. 119 1.1 mrg */ 120 1.2 thorpej kern_reboot(SCARG(uap, opt), bootstr); 121 1.1 mrg return (0); 122 1.1 mrg } 123