Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 63c1dd5 in mainline


Ignore:
Timestamp:
2018-10-09T08:40:53Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
63a045c
Parents:
ee9c703
git-author:
Jiri Svoboda <jiri@…> (2018-10-08 18:38:16)
git-committer:
Jiri Svoboda <jiri@…> (2018-10-09 08:40:53)
Message:

Persistence of Tetris highscore table. Detect live mode and create directory structure in init task. Reading volume configuration, vol -c.

Location:
uspace
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/init/init.c

    ree9c703 r63c1dd5  
    4747#include <config.h>
    4848#include <io/logctl.h>
     49#include <vol.h>
    4950#include "untar.h"
    5051#include "init.h"
     
    7071#define srv_start(path, ...) \
    7172        srv_startl(path, path, ##__VA_ARGS__, NULL)
     73
     74static const char *sys_dirs[] = {
     75        "/w/cfg",
     76        "/w/data"
     77};
    7278
    7379/** Print banner */
     
    320326}
    321327
     328/** Init system volume.
     329 *
     330 * See if system volume is configured. If so, try to wait for it to become
     331 * available. If not, create basic directories for live image omde.
     332 */
     333static errno_t init_sysvol(void)
     334{
     335        vol_t *vol = NULL;
     336        vol_info_t vinfo;
     337        volume_id_t *volume_ids = NULL;
     338        size_t nvols;
     339        size_t i;
     340        errno_t rc;
     341        bool found_cfg;
     342        const char **cp;
     343
     344        rc = vol_create(&vol);
     345        if (rc != EOK) {
     346                printf("Error contacting volume service.\n");
     347                goto error;
     348        }
     349
     350        rc = vol_get_volumes(vol, &volume_ids, &nvols);
     351        if (rc != EOK) {
     352                printf("Error getting list of volumes.\n");
     353                goto error;
     354        }
     355
     356        /* XXX This could be handled more efficiently by volsrv itself */
     357        found_cfg = false;
     358        for (i = 0; i < nvols; i++) {
     359                rc = vol_info(vol, volume_ids[i], &vinfo);
     360                if (rc != EOK) {
     361                        printf("Error getting volume information.\n");
     362                        rc = EIO;
     363                        goto error;
     364                }
     365
     366                if (str_cmp(vinfo.path, "/w") == 0) {
     367                        found_cfg = true;
     368                        break;
     369                }
     370        }
     371
     372        vol_destroy(vol);
     373        free(volume_ids);
     374
     375        if (!found_cfg) {
     376                /* Prepare directory structure for live image mode */
     377                printf("%s: Creating live image directory structure.\n", NAME);
     378                cp = sys_dirs;
     379                while (*cp != NULL) {
     380                        rc = vfs_link_path(*cp, KIND_DIRECTORY, NULL);
     381                        if (rc != EOK) {
     382                                printf("%s: Error creating directory '%s'.\n",
     383                                    NAME, *cp);
     384                                return rc;
     385                        }
     386
     387                        ++cp;
     388                }
     389        } else {
     390                printf("%s: System volume is configured.\n", NAME);
     391        }
     392
     393        return EOK;
     394error:
     395        vol_destroy(vol);
     396        if (volume_ids != NULL)
     397                free(volume_ids);
     398
     399        return rc;
     400}
     401
    322402int main(int argc, char *argv[])
    323403{
     
    375455        srv_start("/srv/hound");
    376456
     457        init_sysvol();
     458
    377459        if (!config_key_exists("console")) {
    378460                rc = compositor(HID_INPUT, HID_COMPOSITOR_SERVER);
  • uspace/app/sysinst/sysinst.c

    ree9c703 r63c1dd5  
    7979#define BOOT_BLOCK_IDX 0 /* MBR */
    8080
     81static const char *sys_dirs[] = {
     82        "/cfg",
     83        "/data"
     84};
     85
    8186/** Label the destination device.
    8287 *
     
    160165        *psvc_id = pinfo.svc_id;
    161166        return EOK;
     167}
     168
     169/** Set up system volume structure.
     170 *
     171 * @return EOK on success or an error code
     172 */
     173static errno_t sysinst_setup_sysvol(void)
     174{
     175        errno_t rc;
     176        char *path = NULL;
     177        const char **cp;
     178        int rv;
     179
     180        cp = sys_dirs;
     181        while (*cp != NULL) {
     182                rv = asprintf(&path, "%s%s", MOUNT_POINT, *cp);
     183                if (rv < 0) {
     184                        rc = ENOMEM;
     185                        goto error;
     186                }
     187
     188                rc = vfs_link_path(path, KIND_DIRECTORY, NULL);
     189                if (rc != EOK) {
     190                        printf("Error creating directory '%s'.\n", path);
     191                        goto error;
     192                }
     193
     194                free(path);
     195                path = NULL;
     196                ++cp;
     197        }
     198
     199        free(path);
     200        path = NULL;
     201
     202        return EOK;
     203error:
     204        if (path != NULL)
     205                free(path);
     206        return rc;
    162207}
    163208
     
    415460                return rc;
    416461
    417         printf("FS created and mounted. Copying boot files.\n");
     462        printf("FS created and mounted. Creating system directory structure.\n");
     463        rc = sysinst_setup_sysvol();
     464        if (rc != EOK)
     465                return rc;
     466
     467        printf("Directories created. Copying boot files.\n");
    418468        rc = sysinst_copy_boot_files();
    419469        if (rc != EOK)
  • uspace/app/tetris/scores.c

    ree9c703 r63c1dd5  
    212212        int rc;
    213213
    214         f = fopen("/data/tetris.sco", "rb");
     214        f = fopen("/w/data/tetris.sco", "rb");
    215215        if (f == NULL)
    216216                return ENOENT;
     
    231231        int rc;
    232232
    233         f = fopen("/data/tetris.sco", "wb");
     233        f = fopen("/w/data/tetris.sco", "wb");
    234234        if (f == NULL) {
    235235                printf("Error creating table\n");
  • uspace/app/vol/vol.c

    ree9c703 r63c1dd5  
    4949        vcmd_help,
    5050        vcmd_list,
     51        vcmd_cfglist,
    5152} vol_cmd_t;
    5253
     
    239240}
    240241
     242/** List volume configuration entries.
     243 *
     244 * @return EOK on success or an error code
     245 */
     246static errno_t vol_cmd_cfglist(void)
     247{
     248        vol_t *vol = NULL;
     249        vol_info_t vinfo;
     250        volume_id_t *volume_ids = NULL;
     251        size_t nvols;
     252        size_t i;
     253        table_t *table = NULL;
     254        errno_t rc;
     255
     256        rc = vol_create(&vol);
     257        if (rc != EOK) {
     258                printf("Error contacting volume service.\n");
     259                goto out;
     260        }
     261
     262        rc = vol_get_volumes(vol, &volume_ids, &nvols);
     263        if (rc != EOK) {
     264                printf("Error getting list of volumes.\n");
     265                goto out;
     266        }
     267
     268        rc = table_create(&table);
     269        if (rc != EOK) {
     270                printf("Out of memory.\n");
     271                goto out;
     272        }
     273
     274        table_header_row(table);
     275        table_printf(table, "Volume Name\t" "Path\n");
     276
     277        for (i = 0; i < nvols; i++) {
     278                rc = vol_info(vol, volume_ids[i], &vinfo);
     279                if (rc != EOK) {
     280                        printf("Error getting volume information.\n");
     281                        return EIO;
     282                }
     283
     284                table_printf(table, "%s\t" "%s\n", vinfo.label, vinfo.path);
     285        }
     286
     287        rc = table_print_out(table, stdout);
     288        if (rc != EOK)
     289                printf("Error printing table.\n");
     290out:
     291        table_destroy(table);
     292        vol_destroy(vol);
     293        free(volume_ids);
     294
     295        return rc;
     296}
     297
    241298static void print_syntax(void)
    242299{
    243300        printf("Syntax:\n");
    244         printf("  %s                List volumes\n", NAME);
     301        printf("  %s                List present volumes\n", NAME);
     302        printf("  %s -c             List volume configuration entries\n", NAME);
    245303        printf("  %s -h             Print help\n", NAME);
    246304        printf("  %s eject <mp>     Eject volume mounted in a directory\n", NAME);
     
    264322                if (str_cmp(cmd, "-h") == 0) {
    265323                        vcmd = vcmd_help;
     324                } else if (str_cmp(cmd, "-c") == 0) {
     325                        vcmd = vcmd_cfglist;
    266326                } else if (str_cmp(cmd, "eject") == 0) {
    267327                        vcmd = vcmd_eject;
     
    303363                rc = vol_cmd_list();
    304364                break;
     365        case vcmd_cfglist:
     366                rc = vol_cmd_cfglist();
     367                break;
    305368        }
    306369
  • uspace/lib/c/generic/vol.c

    ree9c703 r63c1dd5  
    528528}
    529529
     530/** Get list of volumes as array of volume IDs.
     531 *
     532 * @param vol Volume service
     533 * @param data Place to store pointer to array
     534 * @param count Place to store length of array (number of entries)
     535 *
     536 * @return EOK on success or an error code
     537 */
     538errno_t vol_get_volumes(vol_t *vol, volume_id_t **data, size_t *count)
     539{
     540        return vol_get_ids_internal(vol, VOL_GET_VOLUMES, 0,
     541            (sysarg_t **) data, count);
     542}
     543
     544/** Get volume configuration information.
     545 *
     546 * @param vol Volume service
     547 * @param vid Volume ID
     548 * @param vinfo Place to sore volume configuration information
     549 * @return EOK on success or an error code
     550 */
     551errno_t vol_info(vol_t *vol, volume_id_t vid, vol_info_t *vinfo)
     552{
     553        async_exch_t *exch;
     554        errno_t retval;
     555        ipc_call_t answer;
     556
     557        exch = async_exchange_begin(vol->sess);
     558        aid_t req = async_send_1(exch, VOL_INFO, vid.id, &answer);
     559
     560        errno_t rc = async_data_read_start(exch, vinfo, sizeof(vol_info_t));
     561        async_exchange_end(exch);
     562        if (rc != EOK) {
     563                async_forget(req);
     564                return EIO;
     565        }
     566
     567        async_wait_for(req, &retval);
     568        if (retval != EOK)
     569                return EIO;
     570
     571        return EOK;
     572}
     573
    530574/** @}
    531575 */
  • uspace/lib/c/include/ipc/vol.h

    ree9c703 r63c1dd5  
    4848        VOL_PART_LSUPP,
    4949        VOL_PART_MKFS,
    50         VOL_PART_SET_MOUNTP
     50        VOL_PART_SET_MOUNTP,
     51        VOL_GET_VOLUMES,
     52        VOL_INFO
    5153} vol_request_t;
    5254
  • uspace/lib/c/include/types/vol.h

    ree9c703 r63c1dd5  
    4141#include <stdbool.h>
    4242
     43typedef struct {
     44        sysarg_t id;
     45} volume_id_t;
     46
    4347typedef enum {
    4448        /** Partition is empty */
     
    8286} vol_part_info_t;
    8387
     88/** Volume configuration information */
     89typedef struct {
     90        /** Volume identifier */
     91        volume_id_t id;
     92        /** Volume label */
     93        char label[VOL_LABEL_MAXLEN + 1];
     94        /** Mount path */
     95        char path[MAX_PATH_LEN + 1]; /* XXX too big */
     96} vol_info_t;
     97
    8498/** Volume label support */
    8599typedef struct {
  • uspace/lib/c/include/vol.h

    ree9c703 r63c1dd5  
    5555    const char *);
    5656extern errno_t vol_part_set_mountp(vol_t *, service_id_t, const char *);
    57 
     57extern errno_t vol_get_volumes(vol_t *, volume_id_t **, size_t *);
     58extern errno_t vol_info(vol_t *, volume_id_t, vol_info_t *);
    5859extern errno_t vol_fstype_format(vol_fstype_t, char **);
    5960extern errno_t vol_pcnt_fs_format(vol_part_cnt_t, vol_fstype_t, char **);
  • uspace/srv/volsrv/types/volume.h

    ree9c703 r63c1dd5  
    4949        /** Link to vol_volumes */
    5050        link_t lvolumes;
     51        /** ID used by clients to refer to the volume */
     52        volume_id_t id;
    5153        /** Reference count */
    5254        atomic_refcount_t refcnt;
     
    6971        /** Volumes SIF node */
    7072        sif_node_t *nvolumes;
     73        /** Next ID */
     74        sysarg_t next_id;
    7175} vol_volumes_t;
    7276
  • uspace/srv/volsrv/volsrv.c

    ree9c703 r63c1dd5  
    419419}
    420420
     421static void vol_get_volumes_srv(vol_parts_t *parts, ipc_call_t *icall)
     422{
     423        ipc_call_t call;
     424        size_t size;
     425        size_t act_size;
     426        errno_t rc;
     427
     428        log_msg(LOG_DEFAULT, LVL_NOTE, "vol_get_volumes_srv()");
     429
     430        if (!async_data_read_receive(&call, &size)) {
     431                async_answer_0(&call, EREFUSED);
     432                async_answer_0(icall, EREFUSED);
     433                return;
     434        }
     435
     436        volume_id_t *id_buf = (volume_id_t *) malloc(size);
     437        if (id_buf == NULL) {
     438                async_answer_0(&call, ENOMEM);
     439                async_answer_0(icall, ENOMEM);
     440                return;
     441        }
     442
     443        rc = vol_get_ids(parts->volumes, id_buf, size, &act_size);
     444        if (rc != EOK) {
     445                async_answer_0(&call, rc);
     446                async_answer_0(icall, rc);
     447                return;
     448        }
     449
     450        errno_t retval = async_data_read_finalize(&call, id_buf, size);
     451        free(id_buf);
     452
     453        async_answer_1(icall, retval, act_size);
     454}
     455
     456static void vol_info_srv(vol_parts_t *parts, ipc_call_t *icall)
     457{
     458        volume_id_t vid;
     459        vol_volume_t *volume;
     460        vol_info_t vinfo;
     461        errno_t rc;
     462
     463        vid.id = IPC_GET_ARG1(*icall);
     464        log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_info_srv(%zu)", vid.id);
     465
     466        rc = vol_volume_find_by_id_ref(parts->volumes, vid, &volume);
     467        if (rc != EOK) {
     468                log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_info_srv: volume %zu not found",
     469                    vid.id);
     470                async_answer_0(icall, ENOENT);
     471                return;
     472        }
     473
     474        log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_info_srv: vol_volume_get_info");
     475        rc = vol_volume_get_info(volume, &vinfo);
     476        if (rc != EOK) {
     477                async_answer_0(icall, EIO);
     478                goto error;
     479        }
     480
     481        ipc_call_t call;
     482        size_t size;
     483        if (!async_data_read_receive(&call, &size)) {
     484                async_answer_0(&call, EREFUSED);
     485                async_answer_0(icall, EREFUSED);
     486                goto error;
     487        }
     488
     489        if (size != sizeof(vol_info_t)) {
     490                async_answer_0(&call, EINVAL);
     491                async_answer_0(icall, EINVAL);
     492                goto error;
     493        }
     494
     495        rc = async_data_read_finalize(&call, &vinfo,
     496            min(size, sizeof(vinfo)));
     497        if (rc != EOK) {
     498                async_answer_0(&call, rc);
     499                async_answer_0(icall, rc);
     500                goto error;
     501        }
     502
     503        async_answer_0(icall, EOK);
     504error:
     505        vol_volume_del_ref(volume);
     506}
     507
    421508static void vol_client_conn(ipc_call_t *icall, void *arg)
    422509{
     
    467554                        vol_part_set_mountp_srv(parts, &call);
    468555                        break;
     556                case VOL_GET_VOLUMES:
     557                        vol_get_volumes_srv(parts, &call);
     558                        break;
     559                case VOL_INFO:
     560                        vol_info_srv(parts, &call);
     561                        break;
    469562                default:
    470563                        async_answer_0(&call, EINVAL);
  • uspace/srv/volsrv/volume.c

    ree9c703 r63c1dd5  
    125125        fibril_mutex_initialize(&volumes->lock);
    126126        list_initialize(&volumes->volumes);
     127        volumes->next_id = 1;
    127128
    128129        /* Try opening existing repository */
     
    222223        volume->volumes = volumes;
    223224        list_append(&volume->lvolumes, &volumes->volumes);
     225        volume->id.id = volumes->next_id;
     226        ++volumes->next_id;
    224227}
    225228
     
    294297}
    295298
     299/** Find volume structure by ID with locked volumes lock.
     300 * *
     301 * @param volumes List of volumes
     302 * @param vid Volume ID
     303 * @param rvolume Place to store pointer to volume structure (existing or new)
     304 *
     305 * @return EOK on success, ENOENT if not found
     306 */
     307static errno_t vol_volume_find_by_id_ref_locked(vol_volumes_t *volumes,
     308    volume_id_t vid, vol_volume_t **rvolume)
     309{
     310        assert(fibril_mutex_is_locked(&volumes->lock));
     311
     312        list_foreach(volumes->volumes, lvolumes, vol_volume_t, volume) {
     313                log_msg(LOG_DEFAULT, LVL_DEBUG2,
     314                    "vol_volume_find_by_id_ref_locked(%zu==%zu)?",
     315                    volume->id.id, vid.id);
     316                if (volume->id.id == vid.id) {
     317                        log_msg(LOG_DEFAULT, LVL_DEBUG2,
     318                            "vol_volume_find_by_id_ref_locked: found");
     319                        /* Add reference */
     320                        refcount_up(&volume->refcnt);
     321                        *rvolume = volume;
     322                        return EOK;
     323                }
     324        }
     325
     326        log_msg(LOG_DEFAULT, LVL_DEBUG2,
     327            "vol_volume_find_by_id_ref_locked: not found");
     328        return ENOENT;
     329}
     330
     331/** Find volume by ID.
     332 *
     333 * @param volumes Volumes
     334 * @param vid Volume ID
     335 * @param rvolume Place to store pointer to volume, with reference count
     336 *                increased.
     337 * @return EOK on success or an error code
     338 */
     339errno_t vol_volume_find_by_id_ref(vol_volumes_t *volumes, volume_id_t vid,
     340    vol_volume_t **rvolume)
     341{
     342        errno_t rc;
     343
     344        fibril_mutex_lock(&volumes->lock);
     345        rc = vol_volume_find_by_id_ref_locked(volumes, vid, rvolume);
     346        fibril_mutex_unlock(&volumes->lock);
     347
     348        return rc;
     349}
     350
    296351/** Determine if volume has non-default settings that need to persist.
    297352 *
     
    416471}
    417472
     473/** Get list of volume IDs.
     474 *
     475 * Get the list of IDs of all persistent volumes (volume configuration
     476 * entries).
     477 *
     478 * @param volumes Volumes
     479 * @param id_buf Buffer to hold the IDs
     480 * @param buf_size Buffer size in bytes
     481 * @param act_size Place to store actual number bytes needed
     482 * @return EOK on success or an error code
     483 */
     484errno_t vol_get_ids(vol_volumes_t *volumes, volume_id_t *id_buf,
     485    size_t buf_size, size_t *act_size)
     486{
     487        size_t act_cnt;
     488        size_t buf_cnt;
     489
     490        fibril_mutex_lock(&volumes->lock);
     491
     492        buf_cnt = buf_size / sizeof(volume_id_t);
     493
     494        act_cnt = 0;
     495        list_foreach(volumes->volumes, lvolumes, vol_volume_t, volume) {
     496                if (vol_volume_is_persist(volume))
     497                        ++act_cnt;
     498        }
     499        *act_size = act_cnt * sizeof(volume_id_t);
     500
     501        if (buf_size % sizeof(volume_id_t) != 0) {
     502                fibril_mutex_unlock(&volumes->lock);
     503                return EINVAL;
     504        }
     505
     506        size_t pos = 0;
     507        list_foreach(volumes->volumes, lvolumes, vol_volume_t, volume) {
     508                if (vol_volume_is_persist(volume)) {
     509                        if (pos < buf_cnt)
     510                                id_buf[pos].id = volume->id.id;
     511                        pos++;
     512                }
     513        }
     514
     515        fibril_mutex_unlock(&volumes->lock);
     516        return EOK;
     517}
     518
    418519/** Load volumes from SIF repository.
    419520 *
     
    474575}
    475576
     577/** Get volume information.
     578 *
     579 * @param volume Volume
     580 * @param vinfo Volume information structure to safe info to
     581 * @return EOK on success or an error code
     582 */
     583errno_t vol_volume_get_info(vol_volume_t *volume, vol_info_t *vinfo)
     584{
     585        vinfo->id = volume->id;
     586        str_cpy(vinfo->label, sizeof(vinfo->label), volume->label);
     587        str_cpy(vinfo->path, sizeof(vinfo->path), volume->mountp);
     588        return EOK;
     589}
     590
    476591/** @}
    477592 */
  • uspace/srv/volsrv/volume.h

    ree9c703 r63c1dd5  
    3838#define VOLUME_H_
    3939
     40#include "types/vol.h"
    4041#include "types/volume.h"
    4142
     
    4445extern errno_t vol_volume_lookup_ref(vol_volumes_t *, const char *,
    4546    vol_volume_t **);
     47extern errno_t vol_volume_find_by_id_ref(vol_volumes_t *, volume_id_t,
     48    vol_volume_t **);
    4649extern void vol_volume_del_ref(vol_volume_t *);
    4750extern errno_t vol_volume_set_mountp(vol_volume_t *, const char *);
     51extern errno_t vol_get_ids(vol_volumes_t *, volume_id_t *, size_t,
     52    size_t *);
     53extern errno_t vol_volume_get_info(vol_volume_t *, vol_info_t *);
    4854
    4955#endif
Note: See TracChangeset for help on using the changeset viewer.