Changeset bff8619 in mainline


Ignore:
Timestamp:
2024-08-20T22:07:31Z (4 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
ac9b4f2
Parents:
a3ba37d
Message:

Simplify SIF interface, remove contacts

Remove transactions, move to a load/save model. Remove contacts
application as it was never finished and not useful at all.

Location:
uspace
Files:
3 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/meson.build

    ra3ba37d rbff8619  
    3434        'blkdump',
    3535        'calculator',
    36         'contacts',
    3736        'corecfg',
    3837        'cpptest',
  • uspace/app/taskbar-cfg/smeedit.c

    ra3ba37d rbff8619  
    403403
    404404                startmenu_repaint(smee->startmenu);
     405                (void)tbarcfg_sync(smee->startmenu->tbarcfg->tbarcfg);
    405406                (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    406407        } else {
     
    418419                        return;
    419420
    420                 (void)smenu_entry_save(smee->smentry->entry);
     421                (void)tbarcfg_sync(smee->startmenu->tbarcfg->tbarcfg);
    421422                startmenu_entry_update(smee->smentry);
     423                (void)tbarcfg_sync(smee->startmenu->tbarcfg->tbarcfg);
    422424                (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    423425        }
  • uspace/app/taskbar-cfg/startmenu.c

    ra3ba37d rbff8619  
    515515
    516516        (void)smee;
     517        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    517518        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    518519}
     
    534535        (void)startmenu_insert(smenu, entry, &smentry);
    535536        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     537        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    536538        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    537539}
     
    620622        startmenu_t *smenu = (startmenu_t *)arg;
    621623        startmenu_entry_t *smentry;
    622         errno_t rc;
    623624
    624625        (void)pbutton;
     
    628629                return;
    629630
    630         rc = smenu_entry_destroy(smentry->entry);
    631         if (rc != EOK)
    632                 return;
    633 
     631        smenu_entry_destroy(smentry->entry);
    634632        ui_list_entry_delete(smentry->lentry);
    635633        free(smentry);
     634
    636635        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     636        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    637637        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    638638}
     
    673673        startmenu_t *smenu = (startmenu_t *)arg;
    674674        startmenu_entry_t *smentry;
    675         errno_t rc;
    676675
    677676        (void)pbutton;
     
    681680                return;
    682681
    683         rc = smenu_entry_move_up(smentry->entry);
    684         if (rc != EOK)
    685                 return;
    686 
     682        smenu_entry_move_up(smentry->entry);
    687683        ui_list_entry_move_up(smentry->lentry);
    688684
    689685        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     686        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    690687        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    691688}
     
    700697        startmenu_t *smenu = (startmenu_t *)arg;
    701698        startmenu_entry_t *smentry;
    702         errno_t rc;
    703699
    704700        (void)pbutton;
     
    708704                return;
    709705
    710         rc = smenu_entry_move_down(smentry->entry);
    711         if (rc != EOK)
    712                 return;
    713 
     706        smenu_entry_move_down(smentry->entry);
    714707        ui_list_entry_move_down(smentry->lentry);
    715708
    716709        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     710        (void)tbarcfg_sync(smenu->tbarcfg->tbarcfg);
    717711        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    718712}
  • uspace/lib/sif/include/sif.h

    ra3ba37d rbff8619  
    11/*
    2  * Copyright (c) 2018 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141
    4242struct sif_sess;
    43 typedef struct sif_sess sif_sess_t;
    44 
    45 struct sif_trans;
    46 typedef struct sif_trans sif_trans_t;
     43typedef struct sif_sess sif_doc_t;
    4744
    4845struct sif_node;
    4946typedef struct sif_node sif_node_t;
    5047
    51 errno_t sif_create(const char *, sif_sess_t **);
    52 errno_t sif_open(const char *, sif_sess_t **);
    53 errno_t sif_close(sif_sess_t *);
    54 sif_node_t *sif_get_root(sif_sess_t *);
     48errno_t sif_new(sif_doc_t **);
     49errno_t sif_load(const char *, sif_doc_t **);
     50errno_t sif_save(sif_doc_t *, const char *);
     51void sif_delete(sif_doc_t *);
     52sif_node_t *sif_get_root(sif_doc_t *);
    5553
    5654sif_node_t *sif_node_first_child(sif_node_t *);
     
    5957const char *sif_node_get_attr(sif_node_t *, const char *);
    6058
    61 errno_t sif_trans_begin(sif_sess_t *, sif_trans_t **);
    62 void sif_trans_abort(sif_trans_t *);
    63 errno_t sif_trans_end(sif_trans_t *);
    64 
    65 errno_t sif_node_prepend_child(sif_trans_t *, sif_node_t *, const char *,
    66     sif_node_t **);
    67 errno_t sif_node_append_child(sif_trans_t *, sif_node_t *, const char *,
    68     sif_node_t **);
    69 errno_t sif_node_insert_before(sif_trans_t *, sif_node_t *, const char *,
    70     sif_node_t **);
    71 errno_t sif_node_insert_after(sif_trans_t *, sif_node_t *, const char *,
    72     sif_node_t **);
    73 void sif_node_destroy(sif_trans_t *, sif_node_t *);
    74 errno_t sif_node_set_attr(sif_trans_t *, sif_node_t *, const char *,
     59errno_t sif_node_prepend_child(sif_node_t *, const char *, sif_node_t **);
     60errno_t sif_node_append_child(sif_node_t *, const char *, sif_node_t **);
     61errno_t sif_node_insert_before(sif_node_t *, const char *, sif_node_t **);
     62errno_t sif_node_insert_after(sif_node_t *, const char *, sif_node_t **);
     63void sif_node_destroy(sif_node_t *);
     64errno_t sif_node_set_attr(sif_node_t *, const char *,
    7565    const char *);
    76 void sif_node_unset_attr(sif_trans_t *, sif_node_t *, const char *);
     66void sif_node_unset_attr(sif_node_t *, const char *);
    7767
    7868#endif
  • uspace/lib/sif/src/sif.c

    ra3ba37d rbff8619  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3333 *
    3434 * Structured Information Format (SIF) is an API that allows an application
    35  * to maintain data in a persistent repository in a format that
    36  *
    37  *  - is structured (and hence extensible)
    38  *  - allows atomic (transactional) updates
    39  *  - allows efficient updates
     35 * to maintain data in a persistent repository in a format that is
     36 * structured (and hence extensible).
    4037 *
    4138 * SIF is meant to be used as the basis for the storage backend used to
     
    4441 * similar to an XML document that contains just tags with attributes
    4542 * (but no text).
    46  *
    47  * SIF can thus naturally express ordered lists (unlike a relational database).
    48  * When contrasted to a (relational) database, SIF is much more primitive.
    49  *
    50  * In particular, SIF
    51  *
    52  *  - does not run on a separate server
    53  *  - des not handle concurrency
    54  *  - does not have a notion of types or data validation
    55  *  - does not understand relations
    56  *  - does not implement any kind of search/queries
    57  *  - does not deal with data sets large enough not to fit in primary memory
    58  *
    59  * any kind of structure data validation is left up to the application.
    6043 */
    6144
     
    172155}
    173156
    174 /** Create and open a SIF repository.
    175  *
    176  * @param fname File name
    177  * @param rsess Place to store pointer to new session.
     157/** Create SIF document.
     158 *
     159 * @param rdoc Place to store pointer to new document.
    178160 *
    179161 * @return EOK on success or error code
    180162 */
    181 errno_t sif_create(const char *fname, sif_sess_t **rsess)
    182 {
    183         sif_sess_t *sess;
     163errno_t sif_new(sif_doc_t **rdoc)
     164{
     165        sif_doc_t *doc;
    184166        sif_node_t *root = NULL;
    185         sif_trans_t *trans = NULL;
    186167        errno_t rc;
    187         FILE *f;
    188 
    189         sess = calloc(1, sizeof(sif_sess_t));
    190         if (sess == NULL)
    191                 return ENOMEM;
    192 
    193         sess->fname = str_dup(fname);
    194         if (sess->fname == NULL) {
    195                 rc = ENOMEM;
    196                 goto error;
    197         }
     168
     169        doc = calloc(1, sizeof(sif_doc_t));
     170        if (doc == NULL)
     171                return ENOMEM;
    198172
    199173        root = sif_node_new(NULL);
     
    209183        }
    210184
    211         f = fopen(fname, "wx");
    212         if (f == NULL) {
    213                 rc = EIO;
    214                 goto error;
    215         }
    216 
    217         sess->f = f;
    218         sess->root = root;
    219 
    220         /* Run a dummy trasaction to marshall initial repo state to file */
    221         rc = sif_trans_begin(sess, &trans);
    222         if (rc != EOK)
    223                 goto error;
    224 
    225         rc = sif_trans_end(trans);
    226         if (rc != EOK)
    227                 goto error;
    228 
    229         *rsess = sess;
     185        doc->root = root;
     186
     187        *rdoc = doc;
    230188        return EOK;
    231189error:
    232         if (trans != NULL)
    233                 sif_trans_abort(trans);
    234190        sif_node_delete(root);
    235         if (sess->fname != NULL)
    236                 free(sess->fname);
    237         free(sess);
     191        free(doc);
    238192        return rc;
    239193}
    240194
    241 /** Open an existing SIF repository.
     195/** Load SIF document.
    242196 *
    243197 * @param fname File name
    244  * @param rsess Place to store pointer to new session.
     198 * @param rdoc Place to store pointer to new document.
    245199 *
    246200 * @return EOK on success or error code
    247201 */
    248 errno_t sif_open(const char *fname, sif_sess_t **rsess)
    249 {
    250         sif_sess_t *sess;
     202errno_t sif_load(const char *fname, sif_doc_t **rdoc)
     203{
     204        sif_doc_t *doc;
    251205        sif_node_t *root = NULL;
    252206        errno_t rc;
    253207        FILE *f;
    254208
    255         sess = calloc(1, sizeof(sif_sess_t));
    256         if (sess == NULL)
    257                 return ENOMEM;
    258 
    259         sess->fname = str_dup(fname);
    260         if (sess->fname == NULL) {
     209        doc = calloc(1, sizeof(sif_doc_t));
     210        if (doc == NULL)
     211                return ENOMEM;
     212
     213        doc->fname = str_dup(fname);
     214        if (doc->fname == NULL) {
    261215                rc = ENOMEM;
    262216                goto error;
     
    278232        }
    279233
    280         sess->root = root;
    281 
    282         sess->f = f;
    283         sess->root = root;
    284         *rsess = sess;
     234        doc->root = root;
     235        *rdoc = doc;
    285236        return EOK;
    286237error:
    287238        sif_node_delete(root);
    288         if (sess->fname != NULL)
    289                 free(sess->fname);
    290         free(sess);
     239        free(doc);
    291240        return rc;
    292241}
    293242
    294 /** Close SIF session.
    295  *
    296  * @param sess SIF session
     243/** Delete SIF document.
     244 *
     245 * @param doc SIF document
    297246 * @return EOK on success or error code
    298247 */
    299 errno_t sif_close(sif_sess_t *sess)
    300 {
    301         sif_node_delete(sess->root);
    302 
    303         if (fclose(sess->f) < 0) {
    304                 free(sess);
    305                 return EIO;
    306         }
    307 
    308         if (sess->fname != NULL)
    309                 free(sess->fname);
    310         free(sess);
    311         return EOK;
     248void sif_delete(sif_doc_t *doc)
     249{
     250        sif_node_delete(doc->root);
     251        free(doc);
    312252}
    313253
    314254/** Return root node.
    315255 *
    316  * @param sess SIF session
    317  */
    318 sif_node_t *sif_get_root(sif_sess_t *sess)
    319 {
    320         return sess->root;
     256 * @param doc SIF document
     257 */
     258sif_node_t *sif_get_root(sif_doc_t *doc)
     259{
     260        return doc->root;
    321261}
    322262
     
    383323}
    384324
    385 /** Begin SIF transaction.
    386  *
    387  * @param trans Transaction
     325/** Save SIF document to file.
     326 * *
     327 * @param doc SIF document
     328 * @param fname File name
    388329 * @return EOK on success or error code
    389330 */
    390 errno_t sif_trans_begin(sif_sess_t *sess, sif_trans_t **rtrans)
    391 {
    392         sif_trans_t *trans;
    393 
    394         trans = calloc(1, sizeof(sif_trans_t));
    395         if (trans == NULL)
    396                 return ENOMEM;
    397 
    398         trans->sess = sess;
    399         *rtrans = trans;
    400         return EOK;
    401 }
    402 
    403 /** Commit SIF transaction.
    404  *
    405  * Commit and free the transaction. If an error is returned, that means
    406  * the transaction has not been freed (and sif_trans_abort() must be used).
    407  *
    408  * @param trans Transaction
    409  * @return EOK on success or error code
    410  */
    411 errno_t sif_trans_end(sif_trans_t *trans)
    412 {
     331errno_t sif_save(sif_doc_t *doc, const char *fname)
     332{
     333        FILE *f = NULL;
    413334        errno_t rc;
    414335
    415         (void) fclose(trans->sess->f);
    416 
    417         trans->sess->f = fopen(trans->sess->fname, "w");
    418         if (trans->sess->f == NULL)
    419                 return EIO;
    420 
    421         rc = sif_export_node(trans->sess->root, trans->sess->f);
     336        f = fopen(fname, "w");
     337        if (f == NULL) {
     338                rc = EIO;
     339                goto error;
     340        }
     341
     342        rc = sif_export_node(doc->root, f);
    422343        if (rc != EOK)
    423                 return rc;
    424 
    425         if (fputc('\n', trans->sess->f) == EOF)
    426                 return EIO;
    427 
    428         if (fflush(trans->sess->f) == EOF)
    429                 return EIO;
    430 
    431         free(trans);
    432         return EOK;
    433 }
    434 
    435 /** Abort SIF transaction.
    436  *
    437  * @param trans Transaction
    438  */
    439 void sif_trans_abort(sif_trans_t *trans)
    440 {
    441         free(trans);
     344                goto error;
     345
     346        if (fputc('\n', f) == EOF) {
     347                rc = EIO;
     348                goto error;
     349        }
     350
     351        if (fflush(f) == EOF) {
     352                rc = EIO;
     353                goto error;
     354        }
     355
     356        return EOK;
     357error:
     358        if (f != NULL)
     359                fclose(f);
     360        return rc;
    442361}
    443362
     
    447366 * @a parent.
    448367 *
    449  * @param trans Transaction
    450368 * @param parent Parent node
    451369 * @param ctype Child type
     
    454372 * @return EOK on success or ENOMEM if out of memory
    455373 */
    456 errno_t sif_node_prepend_child(sif_trans_t *trans, sif_node_t *parent,
    457     const char *ctype, sif_node_t **rchild)
     374errno_t sif_node_prepend_child(sif_node_t *parent, const char *ctype,
     375    sif_node_t **rchild)
    458376{
    459377        sif_node_t *child;
     
    479397 * Create a new child and append it at the end of children list of @a parent.
    480398 *
    481  * @param trans Transaction
    482399 * @param parent Parent node
    483400 * @param ctype Child type
     
    486403 * @return EOK on success or ENOMEM if out of memory
    487404 */
    488 errno_t sif_node_append_child(sif_trans_t *trans, sif_node_t *parent,
    489     const char *ctype, sif_node_t **rchild)
     405errno_t sif_node_append_child(sif_node_t *parent, const char *ctype,
     406    sif_node_t **rchild)
    490407{
    491408        sif_node_t *child;
     
    511428 * Create a new child and insert it before an existing child.
    512429 *
    513  * @param trans Transaction
    514430 * @param sibling Sibling before which to insert
    515431 * @param ctype Child type
     
    518434 * @return EOK on success or ENOMEM if out of memory
    519435 */
    520 errno_t sif_node_insert_before(sif_trans_t *trans, sif_node_t *sibling,
    521     const char *ctype, sif_node_t **rchild)
     436errno_t sif_node_insert_before(sif_node_t *sibling, const char *ctype,
     437    sif_node_t **rchild)
    522438{
    523439        sif_node_t *child;
     
    543459 * Create a new child and insert it after an existing child.
    544460 *
    545  * @param trans Transaction
    546461 * @param sibling Sibling after which to insert
    547462 * @param ctype Child type
     
    550465 * @return EOK on success or ENOMEM if out of memory
    551466 */
    552 errno_t sif_node_insert_after(sif_trans_t *trans, sif_node_t *sibling,
    553     const char *ctype, sif_node_t **rchild)
     467errno_t sif_node_insert_after(sif_node_t *sibling, const char *ctype,
     468    sif_node_t **rchild)
    554469{
    555470        sif_node_t *child;
     
    573488/** Destroy SIF node.
    574489 *
    575  * This function does not return an error, but the transaction may still
    576  * fail to complete.
    577  *
    578  * @param trans Transaction
    579490 * @param node Node to destroy
    580491 */
    581 void sif_node_destroy(sif_trans_t *trans, sif_node_t *node)
     492void sif_node_destroy(sif_node_t *node)
    582493{
    583494        list_remove(&node->lparent);
     
    587498/** Set node attribute.
    588499 *
    589  * @param trans Transaction
    590500 * @param node SIF node
    591501 * @param aname Attribute name
     
    594504 * @return EOK on success, ENOMEM if out of memory
    595505 */
    596 errno_t sif_node_set_attr(sif_trans_t *trans, sif_node_t *node,
    597     const char *aname, const char *avalue)
     506errno_t sif_node_set_attr(sif_node_t *node, const char *aname,
     507    const char *avalue)
    598508{
    599509        odlink_t *link;
     
    636546/** Unset node attribute.
    637547 *
    638  * This function does not return an error, but the transaction may still
    639  * fail to complete.
    640  *
    641  * @param trans Transaction
    642548 * @param node Node
    643549 * @param aname Attribute name
    644550 */
    645 void sif_node_unset_attr(sif_trans_t *trans, sif_node_t *node,
    646     const char *aname)
     551void sif_node_unset_attr(sif_node_t *node, const char *aname)
    647552{
    648553        odlink_t *link;
  • uspace/lib/sif/test/sif.c

    ra3ba37d rbff8619  
    11/*
    2  * Copyright (c) 2018 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3636
    3737PCUT_TEST_SUITE(sif);
    38 
    39 /** Test sif_create. */
     38#if 0
     39/** Test sif_new and sif_delete. */
    4040PCUT_TEST(sif_create)
    4141{
    42         sif_sess_t *sess;
    43         errno_t rc;
    44         int rv;
    45         char *fname;
    46         char *p;
    47 
    48         fname = calloc(L_tmpnam, 1);
    49         PCUT_ASSERT_NOT_NULL(fname);
    50 
    51         p = tmpnam(fname);
    52         PCUT_ASSERT_TRUE(p == fname);
    53 
    54         rc = sif_create(fname, &sess);
    55         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    56 
    57         rc = sif_close(sess);
    58         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    59 
    60         rv = remove(fname);
    61         PCUT_ASSERT_INT_EQUALS(0, rv);
    62 }
    63 
    64 /** Test sif_open. */
    65 PCUT_TEST(sif_open)
     42        sif_doc_t *doc;
     43        errno_t rc;
     44
     45        rc = sif_new(&doc);
     46        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     47
     48        sif_delete(doc);
     49}
     50
     51/** Test sif_load. */
     52PCUT_TEST(sif_load)
    6653{
    6754        sif_sess_t *sess;
     
    601588        PCUT_ASSERT_INT_EQUALS(0, rv);
    602589}
    603 
     590#endif
    604591PCUT_EXPORT(sif);
  • uspace/lib/tbarcfg/include/tbarcfg/tbarcfg.h

    ra3ba37d rbff8619  
    4747extern errno_t tbarcfg_open(const char *, tbarcfg_t **);
    4848extern void tbarcfg_close(tbarcfg_t *);
     49extern errno_t tbarcfg_sync(tbarcfg_t *);
    4950extern smenu_entry_t *tbarcfg_smenu_first(tbarcfg_t *);
    5051extern smenu_entry_t *tbarcfg_smenu_next(smenu_entry_t *);
     
    5859extern errno_t smenu_entry_set_cmd(smenu_entry_t *, const char *);
    5960extern void smenu_entry_set_terminal(smenu_entry_t *, bool);
    60 extern errno_t smenu_entry_save(smenu_entry_t *);
    6161extern errno_t smenu_entry_create(tbarcfg_t *, const char *, const char *,
    6262    bool, smenu_entry_t **);
    6363extern errno_t smenu_entry_sep_create(tbarcfg_t *, smenu_entry_t **);
    64 extern errno_t smenu_entry_destroy(smenu_entry_t *);
    65 extern errno_t smenu_entry_move_up(smenu_entry_t *);
    66 extern errno_t smenu_entry_move_down(smenu_entry_t *);
     64extern void smenu_entry_destroy(smenu_entry_t *);
     65extern void smenu_entry_move_up(smenu_entry_t *);
     66extern void smenu_entry_move_down(smenu_entry_t *);
    6767extern errno_t tbarcfg_listener_create(const char *, void (*)(void *),
    6868    void *, tbarcfg_listener_t **);
  • uspace/lib/tbarcfg/private/tbarcfg.h

    ra3ba37d rbff8619  
    3939
    4040#include <adt/list.h>
    41 #include <sif.h>
    4241#include <stdbool.h>
    4342#include <types/tbarcfg/tbarcfg.h>
     
    4544/** Taskbar configuration */
    4645struct tbarcfg {
    47         /** Repository session */
    48         sif_sess_t *repo;
     46        /** Configuration file path */
     47        char *cfgpath;
    4948        /** List of start menu entries (smenu_entry_t) */
    5049        list_t entries;
    51         /** Entries SIF node */
    52         sif_node_t *nentries;
    5350};
    5451
     
    5956        /** Link to @c smenu->entries */
    6057        link_t lentries;
    61         /** SIF node (persistent storage) */
    62         sif_node_t *nentry;
    6358        /** Is this a separator entry */
    6459        bool separator;
     
    7974} tbarcfg_listener_t;
    8075
    81 extern errno_t smenu_entry_new(tbarcfg_t *, sif_node_t *, const char *,
    82     const char *, bool, smenu_entry_t **);
    83 extern errno_t smenu_entry_sep_new(tbarcfg_t *, sif_node_t *, smenu_entry_t **);
    84 extern void smenu_entry_delete(smenu_entry_t *);
    85 
    8676#endif
    8777
  • uspace/lib/tbarcfg/src/tbarcfg.c

    ra3ba37d rbff8619  
    4747
    4848static void tbarcfg_notify_conn(ipc_call_t *, void *);
     49static errno_t smenu_entry_save(smenu_entry_t *, sif_node_t *);
    4950
    5051/** Create taskbar configuration.
     
    5758{
    5859        tbarcfg_t *tbcfg;
    59         sif_sess_t *repo = NULL;
     60        sif_doc_t *doc = NULL;
    6061        sif_node_t *rnode;
    61         errno_t rc;
    62         sif_trans_t *trans = NULL;
     62        sif_node_t *nentries;
     63        errno_t rc;
    6364
    6465        tbcfg = calloc(1, sizeof(tbarcfg_t));
     
    6970
    7071        list_initialize(&tbcfg->entries);
    71 
    72         rc = sif_create(repopath, &repo);
    73         if (rc != EOK)
    74                 goto error;
    75 
    76         tbcfg->repo = repo;
    77 
    78         rnode = sif_get_root(repo);
    79 
    80         rc = sif_trans_begin(repo, &trans);
    81         if (rc != EOK)
    82                 goto error;
    83 
    84         rc = sif_node_append_child(trans, rnode, "entries", &tbcfg->nentries);
    85         if (rc != EOK)
    86                 goto error;
    87 
    88         rc = sif_trans_end(trans);
    89         if (rc != EOK)
    90                 goto error;
     72        tbcfg->cfgpath = str_dup(repopath);
     73        if (tbcfg->cfgpath == NULL) {
     74                rc = ENOMEM;
     75                goto error;
     76        }
     77
     78        rc = sif_new(&doc);
     79        if (rc != EOK)
     80                goto error;
     81
     82        rnode = sif_get_root(doc);
     83
     84        rc = sif_node_append_child(rnode, "entries", &nentries);
     85        if (rc != EOK)
     86                goto error;
     87
     88        (void)nentries;
     89
     90        rc = sif_save(doc, repopath);
     91        if (rc != EOK)
     92                goto error;
     93
     94        sif_delete(doc);
    9195
    9296        *rtbcfg = tbcfg;
    9397        return EOK;
    9498error:
    95         if (trans != NULL)
    96                 sif_trans_abort(trans);
    97         if (repo != NULL)
    98                 sif_close(repo);
     99        if (doc != NULL)
     100                sif_delete(doc);
     101        if (tbcfg != NULL && tbcfg->cfgpath != NULL)
     102                free(tbcfg->cfgpath);
    99103        if (tbcfg != NULL)
    100104                free(tbcfg);
     
    111115{
    112116        tbarcfg_t *tbcfg;
    113         sif_sess_t *repo = NULL;
     117        sif_doc_t *doc = NULL;
     118        sif_node_t *nentries;
    114119        sif_node_t *rnode;
    115120        sif_node_t *nentry;
     
    128133
    129134        list_initialize(&tbcfg->entries);
    130 
    131         rc = sif_open(repopath, &repo);
    132         if (rc != EOK)
    133                 goto error;
    134 
    135         tbcfg->repo = repo;
    136 
    137         rnode = sif_get_root(repo);
    138         tbcfg->nentries = sif_node_first_child(rnode);
    139         ntype = sif_node_get_type(tbcfg->nentries);
     135        tbcfg->cfgpath = str_dup(repopath);
     136        if (tbcfg->cfgpath == NULL) {
     137                rc = ENOMEM;
     138                goto error;
     139        }
     140
     141        rc = sif_load(repopath, &doc);
     142        if (rc != EOK)
     143                goto error;
     144
     145        rnode = sif_get_root(doc);
     146        nentries = sif_node_first_child(rnode);
     147        ntype = sif_node_get_type(nentries);
    140148        if (str_cmp(ntype, "entries") != 0) {
    141149                rc = EIO;
     
    143151        }
    144152
    145         nentry = sif_node_first_child(tbcfg->nentries);
     153        nentry = sif_node_first_child(nentries);
    146154        while (nentry != NULL) {
    147155                ntype = sif_node_get_type(nentry);
     
    174182                                terminal = "n";
    175183
    176                         rc = smenu_entry_new(tbcfg, nentry, caption, cmd,
     184                        rc = smenu_entry_create(tbcfg, caption, cmd,
    177185                            str_cmp(terminal, "y") == 0, NULL);
    178186                        if (rc != EOK)
    179187                                goto error;
    180188                } else {
    181                         rc = smenu_entry_sep_new(tbcfg, nentry, NULL);
     189                        rc = smenu_entry_sep_create(tbcfg, NULL);
    182190                        if (rc != EOK)
    183191                                goto error;
     
    187195        }
    188196
     197        sif_delete(doc);
    189198        *rtbcfg = tbcfg;
    190199        return EOK;
    191200error:
    192         if (repo != NULL)
    193                 sif_close(repo);
     201        if (doc != NULL)
     202                sif_delete(doc);
     203        if (tbcfg != NULL && tbcfg->cfgpath != NULL)
     204                free(tbcfg->cfgpath);
    194205        if (tbcfg != NULL)
    195206                free(tbcfg);
     
    207218        entry = tbarcfg_smenu_first(tbcfg);
    208219        while (entry != NULL) {
    209                 smenu_entry_delete(entry);
     220                smenu_entry_destroy(entry);
    210221                entry = tbarcfg_smenu_first(tbcfg);
    211222        }
    212223
    213         (void)sif_close(tbcfg->repo);
     224        free(tbcfg->cfgpath);
    214225        free(tbcfg);
     226}
     227
     228/** Synchronize taskbar configuration to config file.
     229 *
     230 * @param repopath Pathname of the menu repository
     231 * @param rtbcfg Place to store pointer to taskbar configuration
     232 * @return EOK on success or an error code
     233 */
     234errno_t tbarcfg_sync(tbarcfg_t *tbcfg)
     235{
     236        sif_doc_t *doc = NULL;
     237        sif_node_t *nentries;
     238        sif_node_t *rnode;
     239        smenu_entry_t *entry;
     240        errno_t rc;
     241
     242        rc = sif_new(&doc);
     243        if (rc != EOK)
     244                goto error;
     245
     246        rnode = sif_get_root(doc);
     247
     248        rc = sif_node_append_child(rnode, "entries", &nentries);
     249        if (rc != EOK)
     250                goto error;
     251
     252        entry = tbarcfg_smenu_first(tbcfg);
     253        while (entry != NULL) {
     254                rc = smenu_entry_save(entry, nentries);
     255                if (rc != EOK)
     256                        goto error;
     257
     258                entry = tbarcfg_smenu_next(entry);
     259        }
     260
     261        rc = sif_save(doc, tbcfg->cfgpath);
     262        if (rc != EOK)
     263                goto error;
     264
     265        sif_delete(doc);
     266        return EOK;
     267error:
     268        if (doc != NULL)
     269                sif_delete(doc);
     270        if (tbcfg != NULL && tbcfg->cfgpath != NULL)
     271                free(tbcfg->cfgpath);
     272        if (tbcfg != NULL)
     273                free(tbcfg);
     274        return rc;
    215275}
    216276
     
    325385 *
    326386 * Note: To make the change visible to others and persistent,
    327  * you must call @c smenu_entry_save()
     387 * you must call @c tbarcfg_sync()
    328388 *
    329389 * @param entry Start menu entry
     
    349409 *
    350410 * Note: To make the change visible to others and persistent,
    351  * you must call @c smenu_entry_save()
     411 * you must call @c tbarcfg_sync()
    352412 *
    353413 * @param entry Start menu entry
     
    373433 *
    374434 * Note: To make the change visible to others and persistent,
    375  * you must call @c smenu_entry_save()
     435 * you must call @c tbarcfg_sync()
    376436 *
    377437 * @param entry Start menu entry
     
    387447 *
    388448 * @param entry Start menu entry
    389  * @param trans Transaction
    390  */
    391 static errno_t smenu_entry_save_trans(smenu_entry_t *entry, sif_trans_t *trans)
    392 {
    393         errno_t rc;
     449 * @param nentries Entries node
     450 */
     451static errno_t smenu_entry_save(smenu_entry_t *entry, sif_node_t *nentries)
     452{
     453        sif_node_t *nentry = NULL;
     454        errno_t rc;
     455
     456        rc = sif_node_append_child(nentries, "entry", &nentry);
     457        if (rc != EOK)
     458                goto error;
    394459
    395460        if (entry->separator) {
    396                 rc = sif_node_set_attr(trans, entry->nentry, "separator", "y");
     461                rc = sif_node_set_attr(nentry, "separator", "y");
    397462                if (rc != EOK)
    398463                        goto error;
    399464        } else {
    400                 sif_node_unset_attr(trans, entry->nentry, "separator");
    401 
    402                 rc = sif_node_set_attr(trans, entry->nentry, "cmd", entry->cmd);
     465                rc = sif_node_set_attr(nentry, "cmd", entry->cmd);
    403466                if (rc != EOK)
    404467                        goto error;
    405468
    406                 rc = sif_node_set_attr(trans, entry->nentry, "caption",
     469                rc = sif_node_set_attr(nentry, "caption",
    407470                    entry->caption);
    408471                if (rc != EOK)
    409472                        goto error;
    410473
    411                 rc = sif_node_set_attr(trans, entry->nentry, "terminal",
     474                rc = sif_node_set_attr(nentry, "terminal",
    412475                    entry->terminal ? "y" : "n");
    413476                if (rc != EOK)
     
    417480        return EOK;
    418481error:
     482        if (nentry != NULL)
     483                sif_node_destroy(nentry);
    419484        return rc;
    420485}
    421486
    422 /** Save any changes to start menu entry.
    423  *
    424  * @param entry Start menu entry
    425  */
    426 errno_t smenu_entry_save(smenu_entry_t *entry)
    427 {
    428         sif_trans_t *trans = NULL;
    429         errno_t rc;
    430 
    431         rc = sif_trans_begin(entry->smenu->repo, &trans);
    432         if (rc != EOK)
    433                 goto error;
    434 
    435         rc = smenu_entry_save_trans(entry, trans);
    436         if (rc != EOK)
    437                 goto error;
    438 
    439         rc = sif_trans_end(trans);
    440         if (rc != EOK)
    441                 goto error;
    442 
    443         return EOK;
    444 error:
    445         if (trans != NULL)
    446                 sif_trans_abort(trans);
    447         return rc;
    448 }
    449 
    450 /** Allocate a start menu entry and append it to the start menu (internal).
     487/** Create new start menu entry and append it to the start menu (internal).
    451488 *
    452489 * This only creates the entry in memory, but does not update the repository.
    453490 *
    454491 * @param smenu Start menu
    455  * @param nentry Backing SIF node
    456492 * @param caption Caption
    457493 * @param cmd Command to run
     
    459495 * @param rentry Place to store pointer to new entry or @c NULL
    460496 */
    461 errno_t smenu_entry_new(tbarcfg_t *smenu, sif_node_t *nentry,
    462     const char *caption, const char *cmd, bool terminal, smenu_entry_t **rentry)
     497errno_t smenu_entry_create(tbarcfg_t *smenu, const char *caption,
     498    const char *cmd, bool terminal, smenu_entry_t **rentry)
    463499{
    464500        smenu_entry_t *entry;
     
    470506                goto error;
    471507        }
    472 
    473         entry->nentry = nentry;
    474508
    475509        entry->caption = str_dup(caption);
     
    504538}
    505539
    506 /** Allocate a start menu separator entry and append it to the start menu
     540/** Create new start menu separator entry and append it to the start menu
    507541 * (internal).
    508542 *
     
    510544 *
    511545 * @param smenu Start menu
    512  * @param nentry Backing SIF node
    513546 * @param rentry Place to store pointer to new entry or @c NULL
    514547 */
    515 errno_t smenu_entry_sep_new(tbarcfg_t *smenu, sif_node_t *nentry,
    516     smenu_entry_t **rentry)
     548errno_t smenu_entry_sep_create(tbarcfg_t *smenu, smenu_entry_t **rentry)
    517549{
    518550        smenu_entry_t *entry;
     
    525557        }
    526558
    527         entry->nentry = nentry;
    528559        entry->separator = true;
    529560
     
    538569}
    539570
    540 /** Delete start menu entry.
     571/** Destroy start menu entry.
    541572 *
    542573 * This only deletes the entry from, but does not update the
     
    545576 * @param entry Start menu entry
    546577 */
    547 void smenu_entry_delete(smenu_entry_t *entry)
     578void smenu_entry_destroy(smenu_entry_t *entry)
    548579{
    549580        list_remove(&entry->lentries);
     
    555586}
    556587
    557 /** Create new start menu entry.
    558  *
    559  * @param smenu Start menu
    560  * @param nentry Backing SIF node
    561  * @param caption Caption
    562  * @param cmd Command to run
    563  * @param terminal Start in terminal
    564  * @param rentry Place to store pointer to new entry or @c NULL
    565  */
    566 errno_t smenu_entry_create(tbarcfg_t *smenu, const char *caption,
    567     const char *cmd, bool terminal, smenu_entry_t **rentry)
    568 {
    569         sif_node_t *nentry;
    570         smenu_entry_t *entry;
    571         errno_t rc;
    572         sif_trans_t *trans = NULL;
    573 
    574         rc = sif_trans_begin(smenu->repo, &trans);
    575         if (rc != EOK)
    576                 goto error;
    577 
    578         rc = sif_node_append_child(trans, smenu->nentries, "entry",
    579             &nentry);
    580         if (rc != EOK)
    581                 goto error;
    582 
    583         rc = sif_node_set_attr(trans, nentry, "cmd", cmd);
    584         if (rc != EOK)
    585                 goto error;
    586 
    587         rc = sif_node_set_attr(trans, nentry, "caption", caption);
    588         if (rc != EOK)
    589                 goto error;
    590 
    591         rc = sif_node_set_attr(trans, nentry, "terminal", terminal ? "y" : "n");
    592         if (rc != EOK)
    593                 goto error;
    594 
    595         rc = smenu_entry_new(smenu, nentry, caption, cmd, terminal, &entry);
    596         if (rc != EOK)
    597                 goto error;
    598 
    599         rc = sif_trans_end(trans);
    600         if (rc != EOK)
    601                 goto error;
    602 
    603         if (rentry != NULL)
    604                 *rentry = entry;
    605         return EOK;
    606 error:
    607         if (trans != NULL)
    608                 sif_trans_abort(trans);
    609         return rc;
    610 }
    611 
    612 /** Create new start menu separator entry.
    613  *
    614  * @param smenu Start menu
    615  * @param nentry Backing SIF node
    616  * @param rentry Place to store pointer to new entry or @c NULL
    617  */
    618 errno_t smenu_entry_sep_create(tbarcfg_t *smenu, smenu_entry_t **rentry)
    619 {
    620         sif_node_t *nentry;
    621         smenu_entry_t *entry;
    622         errno_t rc;
    623         sif_trans_t *trans = NULL;
    624 
    625         rc = sif_trans_begin(smenu->repo, &trans);
    626         if (rc != EOK)
    627                 goto error;
    628 
    629         rc = sif_node_append_child(trans, smenu->nentries, "entry",
    630             &nentry);
    631         if (rc != EOK)
    632                 goto error;
    633 
    634         rc = sif_node_set_attr(trans, nentry, "separator", "y");
    635         if (rc != EOK)
    636                 goto error;
    637 
    638         rc = smenu_entry_sep_new(smenu, nentry, &entry);
    639         if (rc != EOK)
    640                 goto error;
    641 
    642         rc = sif_trans_end(trans);
    643         if (rc != EOK)
    644                 goto error;
    645 
    646         if (rentry != NULL)
    647                 *rentry = entry;
    648         return EOK;
    649 error:
    650         if (trans != NULL)
    651                 sif_trans_abort(trans);
    652         return rc;
    653 }
    654 
    655 /** Destroy start menu entry.
    656  *
    657  * @param entry Start menu entry
    658  * @return EOK on success or an error code
    659  */
    660 errno_t smenu_entry_destroy(smenu_entry_t *entry)
    661 {
    662         errno_t rc;
    663         sif_trans_t *trans = NULL;
    664 
    665         rc = sif_trans_begin(entry->smenu->repo, &trans);
    666         if (rc != EOK)
    667                 goto error;
    668 
    669         sif_node_destroy(trans, entry->nentry);
    670 
    671         rc = sif_trans_end(trans);
    672         if (rc != EOK)
    673                 goto error;
    674 
    675         smenu_entry_delete(entry);
    676         return EOK;
    677 error:
    678         if (trans != NULL)
    679                 sif_trans_abort(trans);
    680         return rc;
    681 }
    682 
    683588/** Move start menu entry up.
    684589 *
    685590 * @param entry Start menu entry
    686  * @return EOK on success or an error code
    687  */
    688 errno_t smenu_entry_move_up(smenu_entry_t *entry)
    689 {
    690         errno_t rc;
    691         sif_trans_t *trans = NULL;
    692         sif_node_t *nnode = NULL;
    693         sif_node_t *old_node;
     591 */
     592void smenu_entry_move_up(smenu_entry_t *entry)
     593{
    694594        smenu_entry_t *prev;
    695 
    696         rc = sif_trans_begin(entry->smenu->repo, &trans);
    697         if (rc != EOK)
    698                 goto error;
    699595
    700596        prev = tbarcfg_smenu_prev(entry);
    701597        if (prev == NULL) {
    702598                /* Entry is already at first position, nothing to do. */
    703                 return EOK;
    704         }
    705 
    706         rc = sif_node_insert_before(trans, prev->nentry, "entry", &nnode);
    707         if (rc != EOK)
    708                 goto error;
    709 
    710         old_node = entry->nentry;
    711         entry->nentry = nnode;
    712 
    713         rc = smenu_entry_save_trans(entry, trans);
    714         if (rc != EOK) {
    715                 entry->nentry = old_node;
    716                 goto error;
    717         }
    718 
    719         sif_node_destroy(trans, old_node);
    720 
    721         rc = sif_trans_end(trans);
    722         if (rc != EOK) {
    723                 entry->nentry = old_node;
    724                 goto error;
     599                return;
    725600        }
    726601
    727602        list_remove(&entry->lentries);
    728603        list_insert_before(&entry->lentries, &prev->lentries);
    729         return EOK;
    730 error:
    731         if (nnode != NULL)
    732                 sif_node_destroy(trans, nnode);
    733         if (trans != NULL)
    734                 sif_trans_abort(trans);
    735         return rc;
    736604}
    737605
     
    739607 *
    740608 * @param entry Start menu entry
    741  * @return EOK on success or an error code
    742  */
    743 errno_t smenu_entry_move_down(smenu_entry_t *entry)
    744 {
    745         errno_t rc;
    746         sif_trans_t *trans = NULL;
    747         sif_node_t *nnode = NULL;
    748         sif_node_t *old_node;
     609 */
     610void smenu_entry_move_down(smenu_entry_t *entry)
     611{
    749612        smenu_entry_t *next;
    750 
    751         rc = sif_trans_begin(entry->smenu->repo, &trans);
    752         if (rc != EOK)
    753                 goto error;
    754613
    755614        next = tbarcfg_smenu_next(entry);
    756615        if (next == NULL) {
    757616                /* Entry is already at last position, nothing to do. */
    758                 return EOK;
    759         }
    760 
    761         rc = sif_node_insert_after(trans, next->nentry, "entry", &nnode);
    762         if (rc != EOK)
    763                 goto error;
    764 
    765         old_node = entry->nentry;
    766         entry->nentry = nnode;
    767 
    768         rc = smenu_entry_save_trans(entry, trans);
    769         if (rc != EOK) {
    770                 entry->nentry = old_node;
    771                 goto error;
    772         }
    773 
    774         sif_node_destroy(trans, old_node);
    775 
    776         rc = sif_trans_end(trans);
    777         if (rc != EOK) {
    778                 entry->nentry = old_node;
    779                 goto error;
     617                return;
    780618        }
    781619
    782620        list_remove(&entry->lentries);
    783621        list_insert_after(&entry->lentries, &next->lentries);
    784         return EOK;
    785 error:
    786         if (nnode != NULL)
    787                 sif_node_destroy(trans, nnode);
    788         if (trans != NULL)
    789                 sif_trans_abort(trans);
    790         return rc;
    791622}
    792623
  • uspace/lib/tbarcfg/test/tbarcfg.c

    ra3ba37d rbff8619  
    5757        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    5858
     59        tbarcfg_sync(tbcfg);
    5960        tbarcfg_close(tbcfg);
    6061
     
    170171        PCUT_ASSERT_TRUE(smenu_entry_get_separator(e2));
    171172
     173        tbarcfg_sync(tbcfg);
    172174        tbarcfg_close(tbcfg);
    173175
     
    261263        smenu_entry_set_terminal(e, true);
    262264
    263         rc = smenu_entry_save(e);
     265        rc = tbarcfg_sync(tbcfg);
    264266        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    265267
     
    272274        PCUT_ASSERT_TRUE(terminal);
    273275
     276        tbarcfg_sync(tbcfg);
    274277        tbarcfg_close(tbcfg);
    275278
     
    359362        PCUT_ASSERT_EQUALS(e, f);
    360363
    361         rc = smenu_entry_destroy(e);
    362         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     364        smenu_entry_destroy(e);
    363365
    364366        f = tbarcfg_smenu_first(tbcfg);
     
    400402        /* Moving the first entry up should have no effect */
    401403
    402         rc = smenu_entry_move_up(e1);
    403         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     404        smenu_entry_move_up(e1);
    404405
    405406        f = tbarcfg_smenu_first(tbcfg);
     
    408409        /* Moving the second entry up should move it to first position */
    409410
    410         rc = smenu_entry_move_up(e2);
    411         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     411        smenu_entry_move_up(e2);
    412412
    413413        f = tbarcfg_smenu_first(tbcfg);
     
    416416        /* Moving the last entry up should move it to second position */
    417417
    418         rc = smenu_entry_move_up(e3);
    419         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     418        smenu_entry_move_up(e3);
    420419
    421420        f = tbarcfg_smenu_first(tbcfg);
     
    428427        PCUT_ASSERT_EQUALS(e1, f);
    429428
     429        tbarcfg_sync(tbcfg);
    430430        tbarcfg_close(tbcfg);
    431431
     
    496496        /* Moving the last entry down should have no effect */
    497497
    498         rc = smenu_entry_move_down(e3);
    499         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     498        smenu_entry_move_down(e3);
    500499
    501500        f = tbarcfg_smenu_last(tbcfg);
     
    504503        /* Moving the second entry down should move it to last position */
    505504
    506         rc = smenu_entry_move_down(e2);
    507         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     505        smenu_entry_move_down(e2);
    508506
    509507        f = tbarcfg_smenu_last(tbcfg);
     
    512510        /* Moving the first entry down should move it to second position */
    513511
    514         rc = smenu_entry_move_down(e1);
    515         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     512        smenu_entry_move_down(e1);
    516513
    517514        f = tbarcfg_smenu_last(tbcfg);
     
    524521        PCUT_ASSERT_EQUALS(e3, f);
    525522
     523        tbarcfg_sync(tbcfg);
    526524        tbarcfg_close(tbcfg);
    527525
  • uspace/srv/volsrv/types/volume.h

    ra3ba37d rbff8619  
    11/*
    2  * Copyright (c) 2018 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include <refcount.h>
    4242#include <fibril_synch.h>
    43 #include <sif.h>
    4443
    4544/** Volume */
     
    5756        /** Mount point */
    5857        char *mountp;
    59         /** SIF node for this volume */
    60         sif_node_t *nvolume;
    6158} vol_volume_t;
    6259
     
    6764        /** Volumes (list of vol_volume_t) */
    6865        list_t volumes;
    69         /** Cconfiguration repo session */
    70         sif_sess_t *repo;
    71         /** Volumes SIF node */
    72         sif_node_t *nvolumes;
    7366        /** Next ID */
    7467        sysarg_t next_id;
     68        /** Configuration file path */
     69        char *cfg_path;
    7570} vol_volumes_t;
    7671
  • uspace/srv/volsrv/volume.c

    ra3ba37d rbff8619  
    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/** Sync volume configuration to config file.
     191 *
     192 * @param volumes List of volumes
     193 * @return EOK on success, ENOMEM if out of memory
     194 */
     195errno_t vol_volumes_sync(vol_volumes_t *volumes)
     196{
     197        sif_doc_t *doc = NULL;
     198        errno_t rc;
     199
     200        rc = sif_new(&doc);
     201        if (rc != EOK)
     202                goto error;
     203
     204        rc = vol_volumes_save(volumes, sif_get_root(doc));
     205        if (rc != EOK)
     206                goto error;
     207
     208        rc = sif_save(doc, volumes->cfg_path);
     209        if (rc != EOK)
     210                goto error;
     211
     212        sif_delete(doc);
     213        return EOK;
     214error:
     215        if (doc != NULL)
     216                (void) sif_delete(doc);
    183217        return rc;
    184218}
     
    206240        }
    207241
    208         (void) sif_close(volumes->repo);
     242        free(volumes->cfg_path);
    209243        free(volumes);
    210244}
     
    383417        char *mp;
    384418        char *old_mp;
    385         errno_t rc;
    386         sif_trans_t *trans = NULL;
    387         sif_node_t *nvolume;
     419        bool was_persist;
    388420
    389421        mp = str_dup(mountp);
     
    391423                return ENOMEM;
    392424
     425        was_persist = vol_volume_is_persist(volume);
     426
    393427        old_mp = volume->mountp;
    394428        volume->mountp = mp;
    395429
    396430        if (vol_volume_is_persist(volume)) {
    397                 /* Volume is now persistent */
    398                 if (volume->nvolume == NULL) {
    399                         /* Prevent volume from being freed */
     431                if (!was_persist) {
     432                        /*
     433                         * Volume is now persistent. Prevent it from being
     434                         * freed.
     435                         */
    400436                        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 */
     437                }
     438        } else {
     439                if (was_persist) {
     440                        /*
     441                         * Volume is now non-persistent
     442                         * Allow volume to be freed.
     443                         */
    430444                        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 
     445                }
     446        }
     447
     448        vol_volumes_sync(volume->volumes);
    466449        free(old_mp);
    467450        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;
    475451}
    476452
     
    521497}
    522498
    523 /** Load volumes from SIF repository.
     499/** Load volumes from SIF document.
    524500 *
    525501 * @param nvolumes Volumes node
     
    536512        errno_t rc;
    537513
    538         volumes->nvolumes = nvolumes;
    539 
    540514        nvolume = sif_node_first_child(nvolumes);
    541515        while (nvolume != NULL) {
     
    565539                volume->mountp = str_dup(mountp);
    566540
    567                 volume->nvolume = nvolume;
    568541                fibril_mutex_lock(&volumes->lock);
    569542                vol_volume_add_locked(volumes, volume);
     
    579552}
    580553
     554/** Save volumes to SIF document.
     555 *
     556 * @param volumes List of volumes
     557 * @param rnode Configuration root node
     558 * @return EOK on success, ENOMEM if out of memory
     559 */
     560errno_t vol_volumes_save(vol_volumes_t *volumes, sif_node_t *rnode)
     561{
     562        sif_node_t *nvolumes;
     563        sif_node_t *node;
     564        link_t *link;
     565        vol_volume_t *volume;
     566        errno_t rc;
     567
     568        /* Create 'volumes' node. */
     569        rc = sif_node_append_child(rnode, "volumes", &nvolumes);
     570        if (rc != EOK)
     571                goto error;
     572
     573        link = list_first(&volumes->volumes);
     574        while (link != NULL) {
     575                volume = list_get_instance(link, vol_volume_t, lvolumes);
     576
     577                if (vol_volume_is_persist(volume)) {
     578                        /* Create 'volume' node. */
     579                        rc = sif_node_append_child(rnode, "volume", &node);
     580                        if (rc != EOK)
     581                                goto error;
     582
     583                        rc = sif_node_set_attr(node, "label", volume->label);
     584                        if (rc != EOK)
     585                                goto error;
     586
     587                        rc = sif_node_set_attr(node, "mountp", volume->mountp);
     588                        if (rc != EOK)
     589                                goto error;
     590                }
     591
     592                link = list_next(&volume->lvolumes, &volumes->volumes);
     593        }
     594
     595        return EOK;
     596error:
     597        return rc;
     598}
     599
    581600/** Get volume information.
    582601 *
  • uspace/srv/volsrv/volume.h

    ra3ba37d rbff8619  
    11/*
    2  * Copyright (c) 2018 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4242
    4343extern errno_t vol_volumes_create(const char *, vol_volumes_t **);
     44extern errno_t vol_volumes_sync(vol_volumes_t *);
    4445extern void vol_volumes_destroy(vol_volumes_t *);
    4546extern errno_t vol_volume_lookup_ref(vol_volumes_t *, const char *,
Note: See TracChangeset for help on using the changeset viewer.