Changeset 1dcba91 in mainline for uspace/srv/volsrv/volume.c


Ignore:
Timestamp:
2018-08-08T10:08:53Z (7 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
44428bb
Parents:
7ab7075f
git-author:
Jiri Svoboda <jiri@…> (2018-08-07 17:07:59)
git-committer:
Jiri Svoboda <jiri@…> (2018-08-08 10:08:53)
Message:

Configuration repository for volume server.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/volsrv/volume.c

    r7ab7075f r1dcba91  
    5959static errno_t vol_volume_lookup_ref_locked(vol_volumes_t *, const char *,
    6060    vol_volume_t **);
     61static errno_t vol_volumes_load(sif_node_t *, vol_volumes_t *);
    6162
    6263/** Allocate new volume structure.
     
    104105/** Create list of volumes.
    105106 *
     107 * @param cfg_path Path to file containing configuration repository in SIF
    106108 * @param rvolumes Place to store pointer to list of volumes.
    107109 * @return EOK on success, ENOMEM if out of memory
    108110 */
    109 errno_t vol_volumes_create(vol_volumes_t **rvolumes)
     111errno_t vol_volumes_create(const char *cfg_path,
     112    vol_volumes_t **rvolumes)
    110113{
    111114        vol_volumes_t *volumes;
     115        sif_sess_t *repo = NULL;
     116        sif_trans_t *trans = NULL;
     117        sif_node_t *node;
     118        const char *ntype;
     119        errno_t rc;
    112120
    113121        volumes = calloc(1, sizeof(vol_volumes_t));
     
    118126        list_initialize(&volumes->volumes);
    119127
     128        /* Try opening existing repository */
     129        rc = sif_open(cfg_path, &repo);
     130        if (rc != EOK) {
     131                /* Failed to open existing, create new repository */
     132                rc = sif_create(cfg_path, &repo);
     133                if (rc != EOK)
     134                        goto error;
     135
     136                rc = sif_trans_begin(repo, &trans);
     137                if (rc != EOK)
     138                        goto error;
     139
     140                /* Create 'volumes' node. */
     141                rc = sif_node_append_child(trans, sif_get_root(repo),
     142                    "volumes", &volumes->nvolumes);
     143                if (rc != EOK)
     144                        goto error;
     145
     146                rc = sif_trans_end(trans);
     147                if (rc != EOK)
     148                        goto error;
     149
     150                trans = NULL;
     151        } else {
     152                /*
     153                 * Opened existing repo. Find 'volumes' node, should be
     154                 * the first child of the root node.
     155                 */
     156                node = sif_node_first_child(sif_get_root(repo));
     157
     158                /* Verify it's the correct node type */
     159                ntype = sif_node_get_type(node);
     160                if (str_cmp(ntype, "volumes") != 0) {
     161                        rc = EIO;
     162                        goto error;
     163                }
     164
     165                rc = vol_volumes_load(node, volumes);
     166                if (rc != EOK)
     167                        goto error;
     168        }
     169
     170        volumes->repo = repo;
    120171        *rvolumes = volumes;
     172
    121173        return EOK;
     174error:
     175        if (trans != NULL)
     176                sif_trans_abort(trans);
     177        if (repo != NULL)
     178                (void) sif_close(repo);
     179        if (volumes != NULL)
     180                free(volumes);
     181
     182        return rc;
    122183}
    123184
     
    195256                return ENOMEM;
    196257
     258        free(volume->label);
    197259        volume->label = str_dup(label);
     260
     261        if (volume->label == NULL) {
     262                vol_volume_delete(volume);
     263                return ENOMEM;
     264        }
     265
    198266        vol_volume_add_locked(volumes, volume);
    199267
     
    260328{
    261329        char *mp;
     330        char *old_mp;
     331        errno_t rc;
     332        sif_trans_t *trans = NULL;
     333        sif_node_t *nvolume;
    262334
    263335        mp = str_dup(mountp);
     
    265337                return ENOMEM;
    266338
    267         free(volume->mountp);
     339        old_mp = volume->mountp;
    268340        volume->mountp = mp;
    269341
     342        if (vol_volume_is_persist(volume)) {
     343                /* Volume is now persistent */
     344                if (volume->nvolume == NULL) {
     345                        /* Create volume node */
     346                        rc = sif_trans_begin(volume->volumes->repo, &trans);
     347                        if (rc != EOK)
     348                                goto error;
     349
     350                        rc = sif_node_append_child(trans,
     351                            volume->volumes->nvolumes, "volume", &nvolume);
     352                        if (rc != EOK)
     353                                goto error;
     354
     355                        rc = sif_node_set_attr(trans, nvolume, "label",
     356                            volume->label);
     357                        if (rc != EOK)
     358                                goto error;
     359
     360                        rc = sif_node_set_attr(trans, nvolume, "mountp",
     361                            volume->mountp);
     362                        if (rc != EOK)
     363                                goto error;
     364
     365                        rc = sif_trans_end(trans);
     366                        if (rc != EOK)
     367                                goto error;
     368
     369                        trans = NULL;
     370                        volume->nvolume = nvolume;
     371                } else {
     372                        /* Update volume node */
     373                        rc = sif_trans_begin(volume->volumes->repo, &trans);
     374                        if (rc != EOK)
     375                                goto error;
     376
     377                        rc = sif_node_set_attr(trans, volume->nvolume,
     378                            "mountp", volume->mountp);
     379                        if (rc != EOK)
     380                                goto error;
     381
     382                        rc = sif_trans_end(trans);
     383                        if (rc != EOK)
     384                                goto error;
     385
     386                        trans = NULL;
     387                }
     388        } else {
     389                /* Volume is now non-persistent */
     390                if (volume->nvolume != NULL) {
     391                        /* Delete volume node */
     392                        rc = sif_trans_begin(volume->volumes->repo, &trans);
     393                        if (rc != EOK)
     394                                goto error;
     395
     396                        sif_node_destroy(trans, volume->nvolume);
     397
     398                        rc = sif_trans_end(trans);
     399                        if (rc != EOK)
     400                                goto error;
     401
     402                        volume->nvolume = NULL;
     403                }
     404        }
     405
     406        free(old_mp);
    270407        return EOK;
     408error:
     409        free(mp);
     410        volume->mountp = old_mp;
     411
     412        if (trans != NULL)
     413                sif_trans_abort(trans);
     414        return rc;
     415}
     416
     417/** Load volumes from SIF repository.
     418 *
     419 * @param nvolumes Volumes node
     420 * @param volumes Volumes object
     421 *
     422 * @return EOK on success or error code
     423 */
     424static errno_t vol_volumes_load(sif_node_t *nvolumes, vol_volumes_t *volumes)
     425{
     426        sif_node_t *nvolume;
     427        vol_volume_t *volume = NULL;
     428        const char *label;
     429        const char *mountp;
     430        errno_t rc;
     431
     432        volumes->nvolumes = nvolumes;
     433
     434        nvolume = sif_node_first_child(nvolumes);
     435        while (nvolume != NULL) {
     436                if (str_cmp(sif_node_get_type(nvolume), "volume") != 0) {
     437                        rc = EIO;
     438                        goto error;
     439                }
     440
     441                volume = vol_volume_new();
     442                if (volume == NULL) {
     443                        rc = ENOMEM;
     444                        goto error;
     445                }
     446
     447                label = sif_node_get_attr(nvolume, "label");
     448                mountp = sif_node_get_attr(nvolume, "mountp");
     449
     450                if (label == NULL || mountp == NULL) {
     451                        rc = EIO;
     452                        goto error;
     453                }
     454
     455                free(volume->label);
     456                free(volume->mountp);
     457
     458                volume->label = str_dup(label);
     459                volume->mountp = str_dup(mountp);
     460
     461                volume->nvolume = nvolume;
     462                fibril_mutex_lock(&volumes->lock);
     463                vol_volume_add_locked(volumes, volume);
     464                fibril_mutex_unlock(&volumes->lock);
     465                nvolume = sif_node_next_child(nvolume);
     466        }
     467
     468        return EOK;
     469error:
     470        if (volume != NULL)
     471                vol_volume_delete(volume);
     472        return rc;
    271473}
    272474
Note: See TracChangeset for help on using the changeset viewer.