Changeset ebb1489 in mainline for uspace/srv/volsrv/volume.c
- Timestamp:
- 2024-10-13T08:23:40Z (2 months ago)
- 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)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/volsrv/volume.c
r2a0c827c rebb1489 1 1 /* 2 * Copyright (c) 20 18Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 48 48 #include <fibril_synch.h> 49 49 #include <io/log.h> 50 #include <sif.h> 50 51 #include <stdbool.h> 51 52 #include <stdlib.h> … … 60 61 vol_volume_t **); 61 62 static errno_t vol_volumes_load(sif_node_t *, vol_volumes_t *); 63 static errno_t vol_volumes_save(vol_volumes_t *, sif_node_t *); 62 64 63 65 /** Allocate new volume structure. … … 113 115 { 114 116 vol_volumes_t *volumes; 115 sif_sess_t *repo = NULL; 116 sif_trans_t *trans = NULL; 117 sif_doc_t *doc = NULL; 117 118 sif_node_t *node; 119 sif_node_t *nvolumes; 118 120 const char *ntype; 119 121 errno_t rc; … … 123 125 return ENOMEM; 124 126 127 volumes->cfg_path = str_dup(cfg_path); 128 if (volumes->cfg_path == NULL) { 129 rc = ENOMEM; 130 goto error; 131 } 132 125 133 fibril_mutex_initialize(&volumes->lock); 126 134 list_initialize(&volumes->volumes); … … 128 136 129 137 /* Try opening existing repository */ 130 rc = sif_ open(cfg_path, &repo);138 rc = sif_load(cfg_path, &doc); 131 139 if (rc != EOK) { 132 140 /* Failed to open existing, create new repository */ 133 rc = sif_ create(cfg_path, &repo);141 rc = sif_new(&doc); 134 142 if (rc != EOK) 135 143 goto error; 136 144 137 rc = sif_trans_begin(repo, &trans); 145 /* Create 'volumes' node. */ 146 rc = sif_node_append_child(sif_get_root(doc), "volumes", 147 &nvolumes); 138 148 if (rc != EOK) 139 149 goto error; 140 150 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); 144 152 if (rc != EOK) 145 153 goto error; 146 154 147 rc = sif_trans_end(trans); 148 if (rc != EOK) 149 goto error; 150 151 trans = NULL; 155 sif_delete(doc); 152 156 } else { 153 157 /* 154 * Opened existing repo. Find 'volumes' node, should be155 * the first child of the root node.158 * Loaded existing configuration. Find 'volumes' node, should 159 * be the first child of the root node. 156 160 */ 157 node = sif_node_first_child(sif_get_root( repo));161 node = sif_node_first_child(sif_get_root(doc)); 158 162 159 163 /* Verify it's the correct node type */ … … 167 171 if (rc != EOK) 168 172 goto error; 169 } 170 171 volumes->repo = repo; 173 174 sif_delete(doc); 175 } 176 172 177 *rvolumes = volumes; 173 174 178 return EOK; 175 179 error: 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); 180 184 if (volumes != NULL) 181 185 free(volumes); 182 186 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 */ 196 errno_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; 242 error: 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 */ 253 errno_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; 272 error: 273 if (doc != NULL) 274 (void) sif_delete(doc); 183 275 return rc; 184 276 } … … 206 298 } 207 299 208 (void) sif_close(volumes->repo);300 free(volumes->cfg_path); 209 301 free(volumes); 210 302 } … … 383 475 char *mp; 384 476 char *old_mp; 385 errno_t rc; 386 sif_trans_t *trans = NULL; 387 sif_node_t *nvolume; 477 bool was_persist; 388 478 389 479 mp = str_dup(mountp); … … 391 481 return ENOMEM; 392 482 483 was_persist = vol_volume_is_persist(volume); 484 393 485 old_mp = volume->mountp; 394 486 volume->mountp = mp; 395 487 396 488 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 */ 400 494 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 */ 430 502 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); 466 507 free(old_mp); 467 508 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;475 509 } 476 510 … … 521 555 } 522 556 523 /** Load volumes from SIF repository.557 /** Load volumes from SIF document. 524 558 * 525 559 * @param nvolumes Volumes node … … 536 570 errno_t rc; 537 571 538 volumes->nvolumes = nvolumes;539 540 572 nvolume = sif_node_first_child(nvolumes); 541 573 while (nvolume != NULL) { … … 565 597 volume->mountp = str_dup(mountp); 566 598 567 volume->nvolume = nvolume;568 599 fibril_mutex_lock(&volumes->lock); 569 600 vol_volume_add_locked(volumes, volume); … … 579 610 } 580 611 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 */ 618 errno_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; 654 error: 655 return rc; 656 } 657 581 658 /** Get volume information. 582 659 *
Note:
See TracChangeset
for help on using the changeset viewer.