Changeset ebb1489 in mainline for uspace/srv/volsrv/volume.c


Ignore:
Timestamp:
2024-10-13T08:23:40Z (2 months ago)
Author:
GitHub <noreply@…>
Children:
0472cf17
Parents:
2a0c827c (diff), b3b79981 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
boba-buba <120932204+boba-buba@…> (2024-10-13 08:23:40)
git-committer:
GitHub <noreply@…> (2024-10-13 08:23:40)
Message:

Merge branch 'HelenOS:master' into topic/packet-capture

File:
1 edited

Legend:

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

    r2a0c827c rebb1489  
    11/*
    2  * Copyright (c) 2018 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4848#include <fibril_synch.h>
    4949#include <io/log.h>
     50#include <sif.h>
    5051#include <stdbool.h>
    5152#include <stdlib.h>
     
    6061    vol_volume_t **);
    6162static errno_t vol_volumes_load(sif_node_t *, vol_volumes_t *);
     63static errno_t vol_volumes_save(vol_volumes_t *, sif_node_t *);
    6264
    6365/** Allocate new volume structure.
     
    113115{
    114116        vol_volumes_t *volumes;
    115         sif_sess_t *repo = NULL;
    116         sif_trans_t *trans = NULL;
     117        sif_doc_t *doc = NULL;
    117118        sif_node_t *node;
     119        sif_node_t *nvolumes;
    118120        const char *ntype;
    119121        errno_t rc;
     
    123125                return ENOMEM;
    124126
     127        volumes->cfg_path = str_dup(cfg_path);
     128        if (volumes->cfg_path == NULL) {
     129                rc = ENOMEM;
     130                goto error;
     131        }
     132
    125133        fibril_mutex_initialize(&volumes->lock);
    126134        list_initialize(&volumes->volumes);
     
    128136
    129137        /* Try opening existing repository */
    130         rc = sif_open(cfg_path, &repo);
     138        rc = sif_load(cfg_path, &doc);
    131139        if (rc != EOK) {
    132140                /* Failed to open existing, create new repository */
    133                 rc = sif_create(cfg_path, &repo);
     141                rc = sif_new(&doc);
    134142                if (rc != EOK)
    135143                        goto error;
    136144
    137                 rc = sif_trans_begin(repo, &trans);
     145                /* Create 'volumes' node. */
     146                rc = sif_node_append_child(sif_get_root(doc), "volumes",
     147                    &nvolumes);
    138148                if (rc != EOK)
    139149                        goto error;
    140150
    141                 /* Create 'volumes' node. */
    142                 rc = sif_node_append_child(trans, sif_get_root(repo),
    143                     "volumes", &volumes->nvolumes);
     151                rc = sif_save(doc, cfg_path);
    144152                if (rc != EOK)
    145153                        goto error;
    146154
    147                 rc = sif_trans_end(trans);
    148                 if (rc != EOK)
    149                         goto error;
    150 
    151                 trans = NULL;
     155                sif_delete(doc);
    152156        } else {
    153157                /*
    154                  * Opened existing repo. Find 'volumes' node, should be
    155                  * the first child of the root node.
     158                 * Loaded existing configuration. Find 'volumes' node, should
     159                 * be the first child of the root node.
    156160                 */
    157                 node = sif_node_first_child(sif_get_root(repo));
     161                node = sif_node_first_child(sif_get_root(doc));
    158162
    159163                /* Verify it's the correct node type */
     
    167171                if (rc != EOK)
    168172                        goto error;
    169         }
    170 
    171         volumes->repo = repo;
     173
     174                sif_delete(doc);
     175        }
     176
    172177        *rvolumes = volumes;
    173 
    174178        return EOK;
    175179error:
    176         if (trans != NULL)
    177                 sif_trans_abort(trans);
    178         if (repo != NULL)
    179                 (void) sif_close(repo);
     180        if (doc != NULL)
     181                (void) sif_delete(doc);
     182        if (volumes != NULL && volumes->cfg_path != NULL)
     183                free(volumes->cfg_path);
    180184        if (volumes != NULL)
    181185                free(volumes);
    182186
     187        return rc;
     188}
     189
     190/** Merge list of volumes into new file.
     191 *
     192 * @param volumes List of volumes
     193 * @param cfg_path Path to file containing configuration repository in SIF
     194 * @return EOK on success, ENOMEM if out of memory
     195 */
     196errno_t vol_volumes_merge_to(vol_volumes_t *volumes, const char *cfg_path)
     197{
     198        sif_doc_t *doc = NULL;
     199        sif_node_t *node;
     200        const char *ntype;
     201        char *dcfg_path;
     202        errno_t rc;
     203
     204        dcfg_path = str_dup(cfg_path);
     205        if (dcfg_path == NULL) {
     206                rc = ENOMEM;
     207                goto error;
     208        }
     209
     210        free(volumes->cfg_path);
     211        volumes->cfg_path = dcfg_path;
     212
     213        /* Try opening existing repository */
     214        rc = sif_load(cfg_path, &doc);
     215        if (rc != EOK) {
     216                /* Failed to open existing, create new repository */
     217                rc = vol_volumes_sync(volumes);
     218                if (rc != EOK)
     219                        goto error;
     220        } else {
     221                /*
     222                 * Loaded existing configuration. Find 'volumes' node, should
     223                 * be the first child of the root node.
     224                 */
     225                node = sif_node_first_child(sif_get_root(doc));
     226
     227                /* Verify it's the correct node type */
     228                ntype = sif_node_get_type(node);
     229                if (str_cmp(ntype, "volumes") != 0) {
     230                        rc = EIO;
     231                        goto error;
     232                }
     233
     234                rc = vol_volumes_load(node, volumes);
     235                if (rc != EOK)
     236                        goto error;
     237
     238                sif_delete(doc);
     239        }
     240
     241        return EOK;
     242error:
     243        if (doc != NULL)
     244                (void) sif_delete(doc);
     245        return rc;
     246}
     247
     248/** Sync volume configuration to config file.
     249 *
     250 * @param volumes List of volumes
     251 * @return EOK on success, ENOMEM if out of memory
     252 */
     253errno_t vol_volumes_sync(vol_volumes_t *volumes)
     254{
     255        sif_doc_t *doc = NULL;
     256        errno_t rc;
     257
     258        rc = sif_new(&doc);
     259        if (rc != EOK)
     260                goto error;
     261
     262        rc = vol_volumes_save(volumes, sif_get_root(doc));
     263        if (rc != EOK)
     264                goto error;
     265
     266        rc = sif_save(doc, volumes->cfg_path);
     267        if (rc != EOK)
     268                goto error;
     269
     270        sif_delete(doc);
     271        return EOK;
     272error:
     273        if (doc != NULL)
     274                (void) sif_delete(doc);
    183275        return rc;
    184276}
     
    206298        }
    207299
    208         (void) sif_close(volumes->repo);
     300        free(volumes->cfg_path);
    209301        free(volumes);
    210302}
     
    383475        char *mp;
    384476        char *old_mp;
    385         errno_t rc;
    386         sif_trans_t *trans = NULL;
    387         sif_node_t *nvolume;
     477        bool was_persist;
    388478
    389479        mp = str_dup(mountp);
     
    391481                return ENOMEM;
    392482
     483        was_persist = vol_volume_is_persist(volume);
     484
    393485        old_mp = volume->mountp;
    394486        volume->mountp = mp;
    395487
    396488        if (vol_volume_is_persist(volume)) {
    397                 /* Volume is now persistent */
    398                 if (volume->nvolume == NULL) {
    399                         /* Prevent volume from being freed */
     489                if (!was_persist) {
     490                        /*
     491                         * Volume is now persistent. Prevent it from being
     492                         * freed.
     493                         */
    400494                        refcount_up(&volume->refcnt);
    401 
    402                         /* Create volume node */
    403                         rc = sif_trans_begin(volume->volumes->repo, &trans);
    404                         if (rc != EOK)
    405                                 goto error;
    406 
    407                         rc = sif_node_append_child(trans,
    408                             volume->volumes->nvolumes, "volume", &nvolume);
    409                         if (rc != EOK)
    410                                 goto error;
    411 
    412                         rc = sif_node_set_attr(trans, nvolume, "label",
    413                             volume->label);
    414                         if (rc != EOK)
    415                                 goto error;
    416 
    417                         rc = sif_node_set_attr(trans, nvolume, "mountp",
    418                             volume->mountp);
    419                         if (rc != EOK)
    420                                 goto error;
    421 
    422                         rc = sif_trans_end(trans);
    423                         if (rc != EOK)
    424                                 goto error;
    425 
    426                         trans = NULL;
    427                         volume->nvolume = nvolume;
    428                 } else {
    429                         /* Allow volume to be freed */
     495                }
     496        } else {
     497                if (was_persist) {
     498                        /*
     499                         * Volume is now non-persistent
     500                         * Allow volume to be freed.
     501                         */
    430502                        vol_volume_del_ref(volume);
    431 
    432                         /* Update volume node */
    433                         rc = sif_trans_begin(volume->volumes->repo, &trans);
    434                         if (rc != EOK)
    435                                 goto error;
    436 
    437                         rc = sif_node_set_attr(trans, volume->nvolume,
    438                             "mountp", volume->mountp);
    439                         if (rc != EOK)
    440                                 goto error;
    441 
    442                         rc = sif_trans_end(trans);
    443                         if (rc != EOK)
    444                                 goto error;
    445 
    446                         trans = NULL;
    447                 }
    448         } else {
    449                 /* Volume is now non-persistent */
    450                 if (volume->nvolume != NULL) {
    451                         /* Delete volume node */
    452                         rc = sif_trans_begin(volume->volumes->repo, &trans);
    453                         if (rc != EOK)
    454                                 goto error;
    455 
    456                         sif_node_destroy(trans, volume->nvolume);
    457 
    458                         rc = sif_trans_end(trans);
    459                         if (rc != EOK)
    460                                 goto error;
    461 
    462                         volume->nvolume = NULL;
    463                 }
    464         }
    465 
     503                }
     504        }
     505
     506        vol_volumes_sync(volume->volumes);
    466507        free(old_mp);
    467508        return EOK;
    468 error:
    469         free(mp);
    470         volume->mountp = old_mp;
    471 
    472         if (trans != NULL)
    473                 sif_trans_abort(trans);
    474         return rc;
    475509}
    476510
     
    521555}
    522556
    523 /** Load volumes from SIF repository.
     557/** Load volumes from SIF document.
    524558 *
    525559 * @param nvolumes Volumes node
     
    536570        errno_t rc;
    537571
    538         volumes->nvolumes = nvolumes;
    539 
    540572        nvolume = sif_node_first_child(nvolumes);
    541573        while (nvolume != NULL) {
     
    565597                volume->mountp = str_dup(mountp);
    566598
    567                 volume->nvolume = nvolume;
    568599                fibril_mutex_lock(&volumes->lock);
    569600                vol_volume_add_locked(volumes, volume);
     
    579610}
    580611
     612/** Save volumes to SIF document.
     613 *
     614 * @param volumes List of volumes
     615 * @param rnode Configuration root node
     616 * @return EOK on success, ENOMEM if out of memory
     617 */
     618errno_t vol_volumes_save(vol_volumes_t *volumes, sif_node_t *rnode)
     619{
     620        sif_node_t *nvolumes;
     621        sif_node_t *node;
     622        link_t *link;
     623        vol_volume_t *volume;
     624        errno_t rc;
     625
     626        /* Create 'volumes' node. */
     627        rc = sif_node_append_child(rnode, "volumes", &nvolumes);
     628        if (rc != EOK)
     629                goto error;
     630
     631        link = list_first(&volumes->volumes);
     632        while (link != NULL) {
     633                volume = list_get_instance(link, vol_volume_t, lvolumes);
     634
     635                if (vol_volume_is_persist(volume)) {
     636                        /* Create 'volume' node. */
     637                        rc = sif_node_append_child(nvolumes, "volume", &node);
     638                        if (rc != EOK)
     639                                goto error;
     640
     641                        rc = sif_node_set_attr(node, "label", volume->label);
     642                        if (rc != EOK)
     643                                goto error;
     644
     645                        rc = sif_node_set_attr(node, "mountp", volume->mountp);
     646                        if (rc != EOK)
     647                                goto error;
     648                }
     649
     650                link = list_next(&volume->lvolumes, &volumes->volumes);
     651        }
     652
     653        return EOK;
     654error:
     655        return rc;
     656}
     657
    581658/** Get volume information.
    582659 *
Note: See TracChangeset for help on using the changeset viewer.