Changeset b55f62a in mainline


Ignore:
Timestamp:
2019-08-07T09:29:33Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
918ac9b
Parents:
2df7d824
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-11-02 00:50:02)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-07 09:29:33)
Message:

sysman: Create control utility sysctl

  • can list units and their states (starts to feel like systemctl :-)
  • helluva boilerplate to get some IPC between sysctl and sysman :-/

Conflicts:

boot/Makefile.common
uspace/Makefile

Location:
uspace
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • uspace/Makefile

    r2df7d824 rb55f62a  
    7272        app/sportdmp \
    7373        app/stats \
     74        app/sysctl \
    7475        app/taskdump \
    7576        app/tester \
  • uspace/lib/c/include/ipc/sysman.h

    r2df7d824 rb55f62a  
    4444        SYSMAN_BROKER_EXP_ADDED,
    4545        SYSMAN_BROKER_EXP_REMOVED,
    46         SYSMAN_CTL_UNIT_START
     46        SYSMAN_CTL_UNIT_START,
     47        SYSMAN_CTL_GET_UNITS,
     48        SYSMAN_CTL_UNIT_GET_NAME,
     49        SYSMAN_CTL_UNIT_GET_STATE
    4750} sysman_ipc_method_t;
    4851
     
    5356} sysman_interface_t;
    5457
     58typedef sysarg_t unit_handle_t;
     59
     60typedef enum {
     61        UNIT_TYPE_INVALID = -1,
     62        UNIT_CONFIGURATION = 0,
     63        UNIT_MOUNT,
     64        UNIT_SERVICE,
     65        UNIT_TARGET
     66} unit_type_t;
     67
     68typedef enum {
     69        STATE_EMBRYO = 0,
     70        STATE_STARTING,
     71        STATE_STARTED,
     72        STATE_STOPPED,
     73        STATE_FAILED
     74} unit_state_t;
     75
    5576#endif
    5677
  • uspace/lib/sysman/include/sysman/ctl.h

    r2df7d824 rb55f62a  
    3030#define _SYSMAN_CTL_H
    3131
     32#include <ipc/sysman.h>
    3233#include <sysman/unit.h>
    3334
    3435int sysman_unit_start(const char *, int);
    3536
     37int sysman_get_units(unit_handle_t **, size_t *);
     38
     39int sysman_unit_get_name(unit_handle_t, char *, size_t);
     40int sysman_unit_get_state(unit_handle_t, unit_state_t *);
    3641#endif
  • uspace/lib/sysman/src/ctl.c

    r2df7d824 rb55f62a  
    2929#include <async.h>
    3030#include <errno.h>
     31#include <stdlib.h>
    3132#include <str.h>
    3233#include <sysman/ctl.h>
     
    5758        return rc;
    5859}
     60
     61static int sysman_get_units_once(sysarg_t *buf, size_t buf_size,
     62    size_t *act_size)
     63{
     64        async_exch_t *exch = sysman_exchange_begin(SYSMAN_PORT_CTL);
     65
     66        ipc_call_t answer;
     67        aid_t req = async_send_0(exch, SYSMAN_CTL_GET_UNITS, &answer);
     68        int rc = async_data_read_start(exch, buf, buf_size);
     69
     70        sysman_exchange_end(exch);
     71
     72        if (rc != EOK) {
     73                async_forget(req);
     74                return rc;
     75        }
     76
     77        sysarg_t retval;
     78        async_wait_for(req, &retval);
     79
     80        if (retval != EOK) {
     81                return retval;
     82        }
     83
     84        *act_size = IPC_GET_ARG1(answer);
     85        return EOK;
     86}
     87
     88int sysman_get_units(unit_handle_t **units_ptr, size_t *cnt_ptr)
     89{
     90        *units_ptr = NULL;
     91        *cnt_ptr = 0;
     92
     93        unit_handle_t *units = NULL;
     94        size_t alloc_size = 0;
     95        size_t act_size = 0;
     96
     97        while (true) {
     98                int rc = sysman_get_units_once(units, alloc_size, &act_size);
     99                if (rc != EOK) {
     100                        return rc;
     101                }
     102
     103                if (act_size <= alloc_size) {
     104                        break;
     105                }
     106
     107                alloc_size = act_size;
     108                units = realloc(units, alloc_size);
     109                if (units == NULL) {
     110                        return ENOMEM;
     111                }
     112        }
     113
     114        *units_ptr = units;
     115        *cnt_ptr = act_size / sizeof(unit_handle_t);
     116        return EOK;
     117}
     118
     119int sysman_unit_get_name(unit_handle_t handle, char *buf, size_t buf_size)
     120{
     121        async_exch_t *exch = sysman_exchange_begin(SYSMAN_PORT_CTL);
     122
     123        ipc_call_t answer;
     124        aid_t req = async_send_1(exch, SYSMAN_CTL_UNIT_GET_NAME, handle, &answer);
     125        int rc = async_data_read_start(exch, buf, buf_size);
     126
     127        sysman_exchange_end(exch);
     128
     129        if (rc != EOK) {
     130                async_forget(req);
     131                return rc;
     132        }
     133
     134        sysarg_t retval;
     135        async_wait_for(req, &retval);
     136
     137        if (retval != EOK) {
     138                return retval;
     139        }
     140
     141        return EOK;
     142}
     143
     144int sysman_unit_get_state(unit_handle_t handle, unit_state_t *state)
     145{
     146        async_exch_t *exch = sysman_exchange_begin(SYSMAN_PORT_CTL);
     147        int rc = async_req_1_1(exch, SYSMAN_CTL_UNIT_GET_STATE, handle, state);
     148        sysman_exchange_end(exch);
     149
     150        return rc;
     151}
  • uspace/srv/sysman/configuration.c

    r2df7d824 rb55f62a  
    4343
    4444static hash_table_t units_by_name;
     45static hash_table_t units_by_handle;
    4546
    4647/* Hash table functions */
     48static size_t units_by_handle_ht_hash(const ht_link_t *item)
     49{
     50        unit_t *unit =
     51            hash_table_get_inst(item, unit_t, units_by_handle);
     52        return unit->handle;
     53}
     54
     55static size_t units_by_handle_ht_key_hash(void *key)
     56{
     57        return *(unit_handle_t *)key;
     58}
     59
     60static bool units_by_handle_ht_equal(const ht_link_t *item1, const ht_link_t *item2)
     61{
     62        return
     63            hash_table_get_inst(item1, unit_t, units_by_handle) ==
     64            hash_table_get_inst(item2, unit_t, units_by_handle);
     65}
     66
     67static bool units_by_handle_ht_key_equal(void *key, const ht_link_t *item)
     68{
     69        return *(unit_handle_t *)key ==
     70            hash_table_get_inst(item, unit_t, units_by_handle)->handle;
     71}
     72
     73static hash_table_ops_t units_by_handle_ht_ops = {
     74        .hash            = &units_by_handle_ht_hash,
     75        .key_hash        = &units_by_handle_ht_key_hash,
     76        .equal           = &units_by_handle_ht_equal,
     77        .key_equal       = &units_by_handle_ht_key_equal,
     78        .remove_callback = NULL // TODO realy unneeded?
     79};
     80
    4781static size_t units_by_name_ht_hash(const ht_link_t *item)
    4882{
     
    5993static bool units_by_name_ht_equal(const ht_link_t *item1, const ht_link_t *item2)
    6094{
    61         return str_cmp(
    62             hash_table_get_inst(item1, unit_t, units_by_name)->name,
    63             hash_table_get_inst(item2, unit_t, units_by_name)->name) == 0;
     95        return
     96            hash_table_get_inst(item1, unit_t, units_by_handle) ==
     97            hash_table_get_inst(item2, unit_t, units_by_handle);
    6498}
    6599
     
    84118{
    85119        hash_table_create(&units_by_name, 0, 0, &units_by_name_ht_ops);
     120        hash_table_create(&units_by_handle, 0, 0, &units_by_handle_ht_ops);
    86121}
    87122
     
    90125        assert(unit);
    91126        assert(unit->state == STATE_EMBRYO);
     127        assert(unit->handle == 0);
    92128        assert(unit->name != NULL);
    93129        sysman_log(LVL_DEBUG2, "%s('%s')", __func__, unit_name(unit));
    94130
    95131        if (hash_table_insert_unique(&units_by_name, &unit->units_by_name)) {
     132                /* Pointers are same size as unit_handle_t both on 32b and 64b */
     133                unit->handle = (unit_handle_t)unit;
     134
     135                hash_table_insert(&units_by_handle, &unit->units_by_handle);
    96136                list_append(&unit->units, &units);
    97137                return EOK;
     
    218258}
    219259
     260unit_t *configuration_find_unit_by_handle(unit_handle_t handle)
     261{
     262        ht_link_t *ht_link = hash_table_find(&units_by_handle, &handle);
     263        if (ht_link != NULL) {
     264                return hash_table_get_inst(ht_link, unit_t, units_by_handle);
     265        } else {
     266                return NULL;
     267        }
     268}
     269
  • uspace/srv/sysman/configuration.h

    r2df7d824 rb55f62a  
    3131
    3232#include <adt/list.h>
     33#include <ipc/sysman.h>
    3334
    3435#include "unit.h"
     
    4950
    5051extern unit_t *configuration_find_unit_by_name(const char *);
     52extern unit_t *configuration_find_unit_by_handle(unit_handle_t);
    5153
    5254
  • uspace/srv/sysman/connection_ctl.c

    r2df7d824 rb55f62a  
    2929#include <errno.h>
    3030#include <ipc/sysman.h>
     31#include <macros.h>
    3132#include <stdlib.h>
     33#include <str.h>
    3234
    3335#include "configuration.h"
     
    6163        job_del_ref(&job);
    6264}
    63 
    6465static void sysman_unit_start(ipc_callid_t iid, ipc_call_t *icall)
    6566{
     
    7778        sysman_log(LVL_DEBUG2, "%s(%s, %x)", __func__, unit_name, flags);
    7879
     80        // TODO this is connection fibril, UNSYNCHRONIZED access to units!
    7981        unit_t *unit = configuration_find_unit_by_name(unit_name);
    8082        if (unit == NULL) {
     
    109111}
    110112
     113static int fill_handles_buffer(unit_handle_t *buffer, size_t size,
     114    size_t *act_size)
     115{
     116        if (size % sizeof(unit_handle_t) != 0) {
     117                return EINVAL;
     118        }
     119
     120        size_t filled = 0;
     121        size_t to_fill = size / sizeof(unit_handle_t);
     122        size_t total = 0;
     123        list_foreach(units, units, unit_t, u) {
     124                if (filled < to_fill) {
     125                        buffer[filled++] = u->handle;
     126                }
     127                ++total;
     128        }
     129        *act_size = total * sizeof(unit_handle_t);
     130        return EOK;
     131}
     132
     133static void sysman_get_units(ipc_callid_t iid, ipc_call_t *icall)
     134{
     135        ipc_callid_t callid;
     136        size_t size;
     137        size_t act_size;
     138        int rc;
     139       
     140        if (!async_data_read_receive(&callid, &size)) {
     141                async_answer_0(callid, EREFUSED);
     142                async_answer_0(iid, EREFUSED);
     143                return;
     144        }
     145       
     146       
     147        unit_handle_t *handles = malloc(size);
     148        if (handles == NULL && size > 0) {
     149                async_answer_0(callid, ENOMEM);
     150                async_answer_0(iid, ENOMEM);
     151                return;
     152        }
     153       
     154       
     155        // TODO UNSYNCHRONIZED access to units!
     156        rc = fill_handles_buffer(handles, size, &act_size);
     157        if (rc != EOK) {
     158                async_answer_0(callid, rc);
     159                async_answer_0(iid, rc);
     160                return;
     161        }
     162       
     163        size_t real_size = min(act_size, size);
     164        sysarg_t retval = async_data_read_finalize(callid, handles, real_size);
     165        free(handles);
     166       
     167        async_answer_1(iid, retval, act_size);
     168}
     169
     170static void sysman_unit_get_name(ipc_callid_t iid, ipc_call_t *icall)
     171{
     172        ipc_callid_t callid;
     173        size_t size;
     174       
     175        if (!async_data_read_receive(&callid, &size)) {
     176                async_answer_0(callid, EREFUSED);
     177                async_answer_0(iid, EREFUSED);
     178                return;
     179        }
     180       
     181        // TODO UNSYNCHRONIZED access to units!
     182        unit_t *u = configuration_find_unit_by_handle(IPC_GET_ARG1(*icall));
     183        if (u == NULL) {
     184                async_answer_0(callid, ENOENT);
     185                async_answer_0(iid, ENOENT);
     186                return;
     187        }
     188       
     189        size_t real_size = min(str_size(u->name) + 1, size);
     190        sysarg_t retval = async_data_read_finalize(callid, u->name, real_size);
     191       
     192        async_answer_0(iid, retval);
     193}
     194
     195static void sysman_unit_get_state(ipc_callid_t iid, ipc_call_t *icall)
     196{
     197        // TODO UNSYNCHRONIZED access to units!
     198        unit_t *u = configuration_find_unit_by_handle(IPC_GET_ARG1(*icall));
     199        if (u == NULL) {
     200                async_answer_0(iid, ENOENT);
     201        } else {
     202                async_answer_1(iid, EOK, u->state);
     203        }
     204}
     205
    111206void sysman_connection_ctl(ipc_callid_t iid, ipc_call_t *icall)
    112207{
     
    128223                        sysman_unit_start(callid, &call);
    129224                        break;
     225                case SYSMAN_CTL_GET_UNITS:
     226                        sysman_get_units(callid, &call);
     227                        break;
     228                case SYSMAN_CTL_UNIT_GET_NAME:
     229                        sysman_unit_get_name(callid, &call);
     230                        break;
     231                case SYSMAN_CTL_UNIT_GET_STATE:
     232                        sysman_unit_get_state(callid, &call);
     233                        break;
    130234                default:
    131235                        async_answer_0(callid, ENOENT);
  • uspace/srv/sysman/sm_task.c

    r2df7d824 rb55f62a  
    8989        sm_task_event_t *tev = data;
    9090
     91        sysman_log(LVL_DEBUG2, "%s, %" PRIu64 " %i",
     92            __func__, tev->task_id, tev->flags);
    9193        unit_svc_t *u_svc = sm_task_find_service(tev->task_id);
    9294        if (u_svc == NULL) {
  • uspace/srv/sysman/unit.h

    r2df7d824 rb55f62a  
    3939#include <conf/text_parse.h>
    4040#include <fibril_synch.h>
    41 
    42 typedef enum {
    43         UNIT_TYPE_INVALID = -1,
    44         UNIT_CONFIGURATION = 0,
    45         UNIT_MOUNT,
    46         UNIT_SERVICE,
    47         UNIT_TARGET
    48 } unit_type_t;
    49 
    50 typedef enum {
    51         STATE_EMBRYO = 0,
    52         STATE_STARTING,
    53         STATE_STARTED,
    54         STATE_STOPPED,
    55         STATE_FAILED
    56 } unit_state_t;
     41#include <ipc/sysman.h>
    5742
    5843/* Forward declarations */
     
    6651        /** Link to name-to-unit hash table */
    6752        ht_link_t units_by_name;
     53
     54        /** Link to handle-to-unit hash table */
     55        ht_link_t units_by_handle;
    6856
    6957        /** Link to list of all units */
     
    8068        job_t *job;
    8169
     70        unit_handle_t handle;
    8271        unit_type_t type;
    8372        char *name;
Note: See TracChangeset for help on using the changeset viewer.