Changeset 8ae8262 in mainline for uspace/srv/sysman/sm_task.c


Ignore:
Timestamp:
2019-08-07T11:08:17Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
130ba46
Parents:
5353f50
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-11-12 02:56:35)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-07 11:08:17)
Message:

sysman: Support for anonymous services

  • Daemons that only call task_retval and don't exit are recorded as anonymous services.
  • Split unit run-state and repository state.
  • Partial support for removal of units from repository (needs refcounting yet).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/sysman/sm_task.c

    r5353f50 r8ae8262  
    2828
    2929#include <adt/list.h>
     30#include <errno.h>
    3031#include <stdlib.h>
    3132#include <task.h>
     33#include <sysman/unit.h>
    3234
    3335#include "repo.h"
     
    3537#include "sysman.h"
    3638#include "sm_task.h"
     39
    3740
    3841/** Structure for boxing task event */
     
    8588}
    8689
     90static unit_svc_t *sm_task_create_service(task_id_t tid)
     91{
     92        unit_t *u_svc = unit_create(UNIT_SERVICE);
     93        bool in_repo_update = false;
     94        int rc = EOK;
     95
     96        if (u_svc == NULL) {
     97                goto fail;
     98        }
     99
     100        rc = asprintf(&u_svc->name, ANONYMOUS_SERVICE_MASK "%c%s", tid,
     101            UNIT_NAME_SEPARATOR, UNIT_SVC_TYPE_NAME);
     102        if (rc < 0) {
     103                goto fail;
     104        }
     105
     106        CAST_SVC(u_svc)->main_task_id = tid;
     107        CAST_SVC(u_svc)->anonymous = true;
     108        /* exec_start is left undefined, maybe could be hinted by kernel's task
     109         * name */
     110
     111        repo_begin_update();
     112        in_repo_update = true;
     113
     114        rc = repo_add_unit(u_svc);
     115        if (rc != EOK) {
     116                goto fail;
     117        }
     118
     119        repo_commit();
     120
     121        return CAST_SVC(u_svc);
     122       
     123fail:
     124        if (in_repo_update) {
     125                repo_rollback();
     126        }
     127
     128        unit_destroy(&u_svc);
     129        return NULL;
     130}
     131
     132static void sm_task_delete_service(unit_svc_t *u_svc)
     133{
     134        repo_begin_update();
     135        int rc = repo_remove_unit(&u_svc->unit);
     136        if (rc != EOK) {
     137                sysman_log(LVL_WARN, "Can't remove unit %s (%i).",
     138                    unit_name(&u_svc->unit), rc);
     139                repo_rollback();
     140                return;
     141        }
     142
     143        repo_commit();
     144}
     145
    87146static void sysman_event_task_event(void *data)
    88147{
     
    92151            __func__, tev->task_id, tev->flags);
    93152        unit_svc_t *u_svc = sm_task_find_service(tev->task_id);
     153
    94154        if (u_svc == NULL) {
    95                 goto finish;
     155                if (tev->flags & TASK_WAIT_EXIT) {
     156                        /* Non-service task exited, ignore. */
     157                        goto finish;
     158                }
     159
     160                u_svc = sm_task_create_service(tev->task_id);
     161                if (u_svc == NULL) {
     162                        sysman_log(LVL_WARN,
     163                            "Unable to create anonymous service for task %" PRIu64 ".",
     164                            tev->task_id);
     165                        goto finish;
     166                }
     167
     168                sysman_log(LVL_DEBUG, "Created anonymous service %s.",
     169                    unit_name(&u_svc->unit));
     170
     171                /* Inject state so that further processing makes sense */
     172                u_svc->unit.state = STATE_STARTING;
    96173        }
    97174
     
    111188                        u->state = STATE_FAILED;
    112189                }
     190
    113191        }
    114192        if (tev->flags & TASK_WAIT_RETVAL) {
     
    119197        unit_notify_state(u);
    120198
     199        if ((tev->flags & TASK_WAIT_EXIT) && u_svc->anonymous) {
     200                sysman_log(LVL_DEBUG, "Deleted anonymous service %s.",
     201                    unit_name(&u_svc->unit));
     202                sm_task_delete_service(u_svc);
     203        }
    121204finish:
    122205        free(tev);
Note: See TracChangeset for help on using the changeset viewer.