Changeset f35749e in mainline


Ignore:
Timestamp:
2025-02-28T23:38:26Z (4 days ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
8300c72
Parents:
4285f384
Message:

System restart via shutdown -r

Files:
3 added
22 edited

Legend:

Unmodified
Added
Removed
  • abi/include/abi/syscall.h

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2005 Martin Decky
    34 * All rights reserved.
     
    4445typedef enum {
    4546        SYS_KIO = 0,
     47        SYS_REBOOT,
    4648
    4749        SYS_THREAD_CREATE,
  • kernel/generic/include/arch.h

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2001-2004 Jakub Jermar
    34 * All rights reserved.
     
    106107extern void calibrate_delay_loop(void);
    107108
    108 extern void reboot(void);
    109109extern void arch_reboot(void);
    110110extern void *arch_construct_function(fncptr_t *, void *, void *);
  • kernel/generic/include/main/main.h

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2006 Martin Decky
    34 * All rights reserved.
     
    3637#define KERN_MAIN_H_
    3738
     39#include <proc/task.h>
    3840#include <typedefs.h>
    3941
     
    4244/* Address of the end of kernel. */
    4345extern uint8_t kdata_end[];
     46extern task_t *kernel_task;
    4447
    4548extern void main_bsp(void);
  • kernel/generic/include/proc/task.h

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2010 Jakub Jermar
    34 * All rights reserved.
     
    142143
    143144extern void task_init(void);
    144 extern void task_done(void);
     145extern void task_done(task_t *);
    145146extern task_t *task_create(as_t *, const char *);
    146147extern void task_hold(task_t *);
  • kernel/generic/src/console/cmd.c

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2005 Jakub Jermar
    34 * All rights reserved.
     
    6061#include <arch/mm/tlb.h>
    6162#include <mm/frame.h>
     63#include <main/shutdown.h>
    6264#include <main/version.h>
    6365#include <mm/slab.h>
  • kernel/generic/src/main/main.c

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2001-2004 Jakub Jermar
    34 * All rights reserved.
     
    110111CHECK_INT_TYPE(64);
    111112
     113task_t *kernel_task;
     114
    112115/** Global configuration structure. */
    113116config_t config = {
     
    273276                panic("Cannot create kernel task.");
    274277
     278        kernel_task = kernel;
     279
    275280        /*
    276281         * Create the first thread.
  • kernel/generic/src/main/shutdown.c

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2007 Martin Decky
    34 * All rights reserved.
     
    3738
    3839#include <arch.h>
    39 #include <proc/task.h>
     40#include <errno.h>
    4041#include <halt.h>
    4142#include <log.h>
     43#include <main/main.h>
     44#include <main/shutdown.h>
     45#include <proc/task.h>
     46#include <proc/thread.h>
     47
     48static thread_t *reboot_thrd = NULL;
     49SPINLOCK_INITIALIZE(reboot_lock);
    4250
    4351void reboot(void)
    4452{
    45         task_done();
     53        task_done(kernel_task);
    4654
    4755#ifdef CONFIG_DEBUG
     
    5361}
    5462
     63/** Thread procedure for rebooting the system.
     64 *
     65 * @param arg Argument (unused)
     66 */
     67static void reboot_thrd_proc(void *arg)
     68{
     69        (void)arg;
     70
     71        reboot();
     72}
     73
     74/** Reboot the system.
     75 *
     76 * @return EOK if reboot started successfully. EBUSY if reboot already
     77 *         started, ENOMEM if out of memory.
     78 */
     79sys_errno_t sys_reboot(void)
     80{
     81        thread_t *thread;
     82
     83        thread = thread_create(reboot_thrd_proc, NULL, kernel_task,
     84            THREAD_FLAG_NONE, "reboot");
     85        if (thread == NULL)
     86                return ENOMEM;
     87
     88        spinlock_lock(&reboot_lock);
     89
     90        if (reboot_thrd != NULL) {
     91                spinlock_unlock(&reboot_lock);
     92                thread_put(thread);
     93                return EBUSY;
     94        }
     95
     96        reboot_thrd = thread;
     97
     98        spinlock_unlock(&reboot_lock);
     99
     100        thread_start(thread);
     101        thread_detach(thread);
     102
     103        return EOK;
     104}
     105
    55106/** @}
    56107 */
  • kernel/generic/src/proc/task.c

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2010 Jakub Jermar
    3  * Copyright (c) 2018 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    104104 *
    105105 */
    106 void task_done(void)
     106void task_done(task_t *cur_task)
    107107{
    108108        size_t tasks_left;
     
    112112                task_t *task_0 = ipc_box_0->task;
    113113                ipc_box_0 = NULL;
     114
    114115                /*
    115116                 * The first task is held by kinit(), we need to release it or
     
    129130                task = task_first();
    130131                while (task != NULL) {
    131                         if (task != TASK) {
     132                        if (task != cur_task) {
    132133                                tasks_left++;
    133134#ifdef CONFIG_DEBUG
  • kernel/generic/src/proc/thread.c

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2010 Jakub Jermar
    3  * Copyright (c) 2018 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    338338        irq_spinlock_unlock(&thread->task->lock, false);
    339339
    340         assert((atomic_get_unordered(&thread->state) == Exiting) || (atomic_get_unordered(&thread->state) == Lingering));
     340        assert((atomic_get_unordered(&thread->state) == Entering) ||
     341            (atomic_get_unordered(&thread->state) == Exiting) ||
     342            (atomic_get_unordered(&thread->state) == Lingering));
    341343
    342344        /* Clear cpu->fpu_owner if set to this thread. */
  • kernel/generic/src/syscall/syscall.c

    r4285f384 rf35749e  
    11/*
     2 * Copyright (c) 2025 Jiri Svoboda
    23 * Copyright (c) 2005 Martin Decky
    34 * All rights reserved.
     
    4041#include <proc/task.h>
    4142#include <proc/program.h>
     43#include <main/shutdown.h>
    4244#include <mm/as.h>
    4345#include <mm/page.h>
     
    5961        /* System management syscalls. */
    6062        [SYS_KIO] = (syshandler_t) sys_kio,
     63        [SYS_REBOOT] = (syshandler_t) sys_reboot,
    6164
    6265        /* Thread and task related syscalls. */
  • uspace/app/shutdown-dlg/shutdown-dlg.c

    r4285f384 rf35749e  
    400400        }
    401401
    402         rc = system_shutdown(sddlg->system);
     402        rc = system_poweroff(sddlg->system);
    403403        if (rc != EOK) {
    404404                printf("Failed requesting system shutdown.\n");
  • uspace/app/shutdown/shutdown.c

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3939#include <fibril_synch.h>
    4040#include <nchoice.h>
     41#include <shutdown.h>
    4142#include <stdio.h>
    4243#include <stdbool.h>
     
    113114
    114115        rc = nchoice_add(nchoice, "Power off", (void *)(uintptr_t)sd_poweroff,
     116            0);
     117        if (rc != EOK) {
     118                printf(NAME ": Out of memory.\n");
     119                goto error;
     120        }
     121
     122        rc = nchoice_add(nchoice, "Restart", (void *)(uintptr_t)sd_restart,
    115123            0);
    116124        if (rc != EOK) {
     
    157165                        action = sd_poweroff;
    158166                        continue;
     167                } else if (str_cmp(*argv, "-r") == 0) {
     168                        --argc;
     169                        ++argv;
     170                        action = sd_restart;
     171                        continue;
    159172                }
    160173
     
    187200        }
    188201
    189         rc = system_shutdown(system);
     202        switch (action) {
     203        case sd_poweroff:
     204                rc = system_poweroff(system);
     205                break;
     206        case sd_restart:
     207                rc = system_restart(system);
     208                break;
     209        case sd_cancel:
     210                assert(false);
     211                rc = EINVAL;
     212                break;
     213        }
     214
    190215        if (rc != EOK) {
    191216                system_close(system);
     
    223248            "\tshutdown [<options>]\n"
    224249            "options:\n"
    225             "\t-p Power off\n");
     250            "\t-p Power off\n"
     251            "\t-r Restart off\n");
    226252}
    227253
  • uspace/app/shutdown/shutdown.h

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4343typedef enum {
    4444        sd_poweroff = 1,
     45        sd_restart,
    4546        sd_cancel
    4647} sd_action_t;
  • uspace/app/trace/syscalls.c

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2008 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4040        /* System management syscalls. */
    4141        [SYS_KIO] = { "kio", 3, V_INT_ERRNO },
     42        [SYS_REBOOT] = { "reboot", 0, V_ERRNO },
    4243
    4344        /* Thread and task related syscalls. */
  • uspace/lib/c/meson.build

    r4285f384 rf35749e  
    11#
    2 # Copyright (c) 2024 Jiri Svoboda
     2# Copyright (c) 2025 Jiri Svoboda
    33# Copyright (c) 2005 Martin Decky
    44# Copyright (c) 2007 Jakub Jermar
     
    122122        'generic/malloc.c',
    123123        'generic/rndgen.c',
     124        'generic/shutdown.c',
    124125        'generic/stdio/scanf.c',
    125126        'generic/stdio/sprintf.c',
  • uspace/lib/system/include/ipc/system.h

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4545typedef enum {
    4646        SYSTEM_CALLBACK_CREATE = IPC_FIRST_USER_METHOD,
    47         SYSTEM_SHUTDOWN
     47        SYSTEM_POWEROFF,
     48        SYSTEM_RESTART
    4849} system_request_t;
    4950
  • uspace/lib/system/include/system.h

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4343extern errno_t system_open(const char *, system_cb_t *, void *, system_t **);
    4444extern void system_close(system_t *);
    45 extern errno_t system_shutdown(system_t *);
     45extern errno_t system_poweroff(system_t *);
     46extern errno_t system_restart(system_t *);
    4647
    4748#endif
  • uspace/lib/system/include/system_srv.h

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4949
    5050struct system_ops {
    51         errno_t (*shutdown)(void *);
     51        errno_t (*poweroff)(void *);
     52        errno_t (*restart)(void *);
    5253};
    5354
  • uspace/lib/system/src/system.c

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    141141}
    142142
    143 /** Shut the system down.
     143/** Shut down and power the system off.
    144144 *
    145145 * This function is asynchronous. It returns immediately with success
     
    151151 * @return EOK on succes or an error code
    152152 */
    153 errno_t system_shutdown(system_t *system)
     153errno_t system_poweroff(system_t *system)
    154154{
    155155        async_exch_t *exch = async_exchange_begin(system->sess);
    156         errno_t rc = async_req_0_0(exch, SYSTEM_SHUTDOWN);
     156        errno_t rc = async_req_0_0(exch, SYSTEM_POWEROFF);
     157        async_exchange_end(exch);
     158
     159        return rc;
     160}
     161
     162/** Shut down and restart the system.
     163 *
     164 * This function is asynchronous. It returns immediately with success
     165 * if the system started shutting down. Once shutdown is completed,
     166 * the @c shutdown_complete callback is executed. If the shutdown fails,
     167 * the @c shutdown_fail callback is executed.
     168 *
     169 * @param system System control service
     170 * @return EOK on succes or an error code
     171 */
     172errno_t system_restart(system_t *system)
     173{
     174        async_exch_t *exch = async_exchange_begin(system->sess);
     175        errno_t rc = async_req_0_0(exch, SYSTEM_RESTART);
    157176        async_exchange_end(exch);
    158177
  • uspace/lib/system/src/system_srv.c

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    5555}
    5656
    57 static void system_shutdown_srv(system_srv_t *srv, ipc_call_t *icall)
     57static void system_poweroff_srv(system_srv_t *srv, ipc_call_t *icall)
    5858{
    5959        errno_t rc;
    6060
    61         if (srv->ops->shutdown == NULL) {
     61        if (srv->ops->poweroff == NULL) {
    6262                async_answer_0(icall, ENOTSUP);
    6363                return;
    6464        }
    6565
    66         rc = srv->ops->shutdown(srv->arg);
     66        rc = srv->ops->poweroff(srv->arg);
     67        async_answer_0(icall, rc);
     68}
     69
     70static void system_restart_srv(system_srv_t *srv, ipc_call_t *icall)
     71{
     72        errno_t rc;
     73
     74        if (srv->ops->restart == NULL) {
     75                async_answer_0(icall, ENOTSUP);
     76                return;
     77        }
     78
     79        rc = srv->ops->restart(srv->arg);
    6780        async_answer_0(icall, rc);
    6881}
     
    89102                        system_callback_create_srv(srv, &call);
    90103                        break;
    91                 case SYSTEM_SHUTDOWN:
    92                         system_shutdown_srv(srv, &call);
     104                case SYSTEM_POWEROFF:
     105                        system_poweroff_srv(srv, &call);
     106                        break;
     107                case SYSTEM_RESTART:
     108                        system_restart_srv(srv, &call);
    93109                        break;
    94110                default:
  • uspace/lib/system/test/system.c

    r4285f384 rf35749e  
    11/*
    2  * Copyright (c) 2024 Jiri Svoboda
     2 * Copyright (c) 2025 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4646void test_system_conn(ipc_call_t *, void *);
    4747
    48 static errno_t test_shutdown(void *);
     48static errno_t test_poweroff(void *);
     49static errno_t test_restart(void *);
    4950
    5051static void test_sys_shutdown_complete(void *);
     
    5253
    5354static system_ops_t test_system_srv_ops = {
    54         .shutdown = test_shutdown
     55        .poweroff = test_poweroff,
     56        .restart = test_restart
    5557};
    5658
     
    6668        errno_t rc;
    6769
    68         bool shutdown_called;
     70        bool poweroff_called;
     71        bool restart_called;
    6972        bool shutdown_complete_called;
    7073        bool shutdown_failed_called;
     
    103106}
    104107
    105 /** system_shutdown() with server returning error response works */
    106 PCUT_TEST(shutdown_failure)
     108/** system_poweroff() with server returning error response works */
     109PCUT_TEST(poweroff_failure)
    107110{
    108111        errno_t rc;
     
    126129
    127130        resp.rc = ENOMEM;
    128         resp.shutdown_called = false;
    129 
    130         rc = system_shutdown(system);
    131         PCUT_ASSERT_TRUE(resp.shutdown_called);
     131        resp.poweroff_called = false;
     132
     133        rc = system_poweroff(system);
     134        PCUT_ASSERT_TRUE(resp.poweroff_called);
    132135        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
    133136
     
    138141}
    139142
    140 /** system_shutdown() with server returning success response works */
    141 PCUT_TEST(shutdown_success)
     143/** system_poweroff() with server returning success response works */
     144PCUT_TEST(poweroff_success)
    142145{
    143146        errno_t rc;
     
    161164
    162165        resp.rc = EOK;
    163         resp.shutdown_called = false;
    164 
    165         rc = system_shutdown(system);
    166         PCUT_ASSERT_TRUE(resp.shutdown_called);
     166        resp.poweroff_called = false;
     167
     168        rc = system_poweroff(system);
     169        PCUT_ASSERT_TRUE(resp.poweroff_called);
     170        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     171
     172        system_close(system);
     173        rc = loc_service_unregister(srv, sid);
     174        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     175        loc_server_unregister(srv);
     176}
     177
     178/** system_restart() with server returning error response works */
     179PCUT_TEST(restart_failure)
     180{
     181        errno_t rc;
     182        service_id_t sid;
     183        system_t *system = NULL;
     184        test_response_t resp;
     185        loc_srv_t *srv;
     186
     187        async_set_fallback_port_handler(test_system_conn, &resp);
     188
     189        // FIXME This causes this test to be non-reentrant!
     190        rc = loc_server_register(test_system_server, &srv);
     191        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     192
     193        rc = loc_service_register(srv, test_system_svc, &sid);
     194        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     195
     196        rc = system_open(test_system_svc, NULL, NULL, &system);
     197        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     198        PCUT_ASSERT_NOT_NULL(system);
     199
     200        resp.rc = ENOMEM;
     201        resp.restart_called = false;
     202
     203        rc = system_restart(system);
     204        PCUT_ASSERT_TRUE(resp.restart_called);
     205        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     206
     207        system_close(system);
     208        rc = loc_service_unregister(srv, sid);
     209        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     210        loc_server_unregister(srv);
     211}
     212
     213/** system_restart() with server returning success response works */
     214PCUT_TEST(restart_success)
     215{
     216        errno_t rc;
     217        service_id_t sid;
     218        system_t *system = NULL;
     219        test_response_t resp;
     220        loc_srv_t *srv;
     221
     222        async_set_fallback_port_handler(test_system_conn, &resp);
     223
     224        // FIXME This causes this test to be non-reentrant!
     225        rc = loc_server_register(test_system_server, &srv);
     226        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     227
     228        rc = loc_service_register(srv, test_system_svc, &sid);
     229        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     230
     231        rc = system_open(test_system_svc, NULL, NULL, &system);
     232        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     233        PCUT_ASSERT_NOT_NULL(system);
     234
     235        resp.rc = EOK;
     236        resp.restart_called = false;
     237
     238        rc = system_restart(system);
     239        PCUT_ASSERT_TRUE(resp.restart_called);
    167240        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
    168241
     
    279352}
    280353
    281 /** Test system shutdown.
     354/** Test system poweroff.
    282355 *
    283356 * @param arg Argument (test_response_t *)
    284357 */
    285 static errno_t test_shutdown(void *arg)
     358static errno_t test_poweroff(void *arg)
    286359{
    287360        test_response_t *resp = (test_response_t *)arg;
    288361
    289         resp->shutdown_called = true;
     362        resp->poweroff_called = true;
     363        return resp->rc;
     364}
     365
     366/** Test system restart.
     367 *
     368 * @param arg Argument (test_response_t *)
     369 */
     370static errno_t test_restart(void *arg)
     371{
     372        test_response_t *resp = (test_response_t *)arg;
     373
     374        resp->restart_called = true;
    290375        return resp->rc;
    291376}
  • uspace/srv/system/system.c

    r4285f384 rf35749e  
    4848#include <str.h>
    4949#include <loc.h>
     50#include <shutdown.h>
    5051#include <str_error.h>
    5152#include <config.h>
     
    8485
    8586static void system_srv_conn(ipc_call_t *, void *);
    86 static errno_t system_srv_shutdown(void *);
     87static errno_t system_srv_poweroff(void *);
     88static errno_t system_srv_restart(void *);
    8789
    8890system_ops_t system_srv_ops = {
    89         .shutdown = system_srv_shutdown
     91        .poweroff = system_srv_poweroff,
     92        .restart = system_srv_restart
    9093};
    9194
     
    609612}
    610613
    611 /** System shutdown request.
     614/** System poweroff request.
    612615 *
    613616 * @param arg Argument (sys_srv_t *)
    614617 */
    615 static errno_t system_srv_shutdown(void *arg)
     618static errno_t system_srv_poweroff(void *arg)
    616619{
    617620        sys_srv_t *syssrv = (sys_srv_t *)arg;
    618621        errno_t rc;
    619622
    620         log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_shutdown");
     623        log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_poweroff");
    621624
    622625        rc = system_sys_shutdown();
    623626        if (rc != EOK) {
    624                 log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_shutdown failed");
     627                log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_poweroff failed");
    625628                system_srv_shutdown_failed(&syssrv->srv);
    626629        }
    627630
    628         log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_shutdown complete");
     631        log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_poweroff complete");
     632        system_srv_shutdown_complete(&syssrv->srv);
     633        return EOK;
     634}
     635
     636/** System restart request.
     637 *
     638 * @param arg Argument (sys_srv_t *)
     639 */
     640static errno_t system_srv_restart(void *arg)
     641{
     642        sys_srv_t *syssrv = (sys_srv_t *)arg;
     643        errno_t rc;
     644
     645        log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_restart");
     646
     647        rc = system_sys_shutdown();
     648        if (rc != EOK) {
     649                log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_restart failed");
     650                system_srv_shutdown_failed(&syssrv->srv);
     651        }
     652
     653        sys_reboot();
     654
     655        log_msg(LOG_DEFAULT, LVL_NOTE, "system_srv_restart complete");
    629656        system_srv_shutdown_complete(&syssrv->srv);
    630657        return EOK;
Note: See TracChangeset for help on using the changeset viewer.