Changeset a0c3080 in mainline


Ignore:
Timestamp:
2024-11-28T17:09:52Z (7 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
586b39d
Parents:
65706f1
Message:

hr: util: hotspare and volume change state functions

Location:
uspace/srv/bd/hr
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/bd/hr/raid0.c

    r65706f1 ra0c3080  
    181181        if (vol->status == HR_VOL_ONLINE)
    182182                return EOK;
    183         return EINVAL;
     183        return EIO;
    184184}
    185185
     
    190190static errno_t hr_raid0_update_vol_status(hr_volume_t *vol)
    191191{
     192        hr_vol_status_t old_state = vol->status;
     193
    192194        for (size_t i = 0; i < vol->extent_no; i++) {
    193195                if (vol->extents[i].status != HR_EXT_ONLINE) {
    194                         HR_WARN("RAID 0 needs all extents to be ONLINE, "
    195                             "marking \"%s\" (%lu) as FAULTY",
    196                             vol->devname, vol->svc_id);
    197                         vol->status = HR_VOL_FAULTY;
    198                         return EINVAL;
     196                        if (old_state != HR_VOL_FAULTY)
     197                                hr_update_vol_status(vol, HR_VOL_FAULTY);
     198                        return EIO;
    199199                }
    200200        }
    201201
    202         vol->status = HR_VOL_ONLINE;
     202        if (old_state != HR_VOL_ONLINE)
     203                hr_update_vol_status(vol, HR_VOL_ONLINE);
     204
    203205        return EOK;
    204206}
     
    244246
    245247        left = cnt;
     248
    246249        while (left != 0) {
    247250                phys_block = ext_stripe * strip_size + strip_off;
  • uspace/srv/bd/hr/raid1.c

    r65706f1 ra0c3080  
    147147
    148148        vol->hotspares[vol->hotspare_no].svc_id = hotspare;
    149         vol->hotspares[vol->hotspare_no].status = HR_EXT_HOTSPARE;
     149        hr_update_hotspare_status(vol, vol->hotspare_no, HR_EXT_HOTSPARE);
     150
    150151        vol->hotspare_no++;
    151152
     
    158159                fid_t fib = fibril_create(hr_raid1_rebuild, vol);
    159160                if (fib == 0)
    160                         return EINVAL;
     161                        return ENOMEM;
    161162                fibril_start(fib);
    162163                fibril_detach(fib);
     
    219220            vol->status == HR_VOL_REBUILD)
    220221                return EOK;
    221         return EINVAL;
     222        return EIO;
    222223}
    223224
     
    232233
    233234        if (healthy == 0) {
    234                 if (old_state != HR_VOL_FAULTY) {
    235                         HR_WARN("RAID 1 needs at least 1 extent to be"
    236                             "ONLINE, marking \"%s\" (%lu) volume as FAULTY",
    237                             vol->devname, vol->svc_id);
    238                         vol->status = HR_VOL_FAULTY;
    239                 }
    240                 return EINVAL;
     235                if (old_state != HR_VOL_FAULTY)
     236                        hr_update_vol_status(vol, HR_VOL_FAULTY);
     237                return EIO;
    241238        } else if (healthy < vol->extent_no) {
    242239                if (old_state != HR_VOL_DEGRADED &&
    243240                    old_state != HR_VOL_REBUILD) {
    244                         HR_WARN("RAID 1 array \"%s\" (%lu) has some "
    245                             "unusable extent(s), marking volume as DEGRADED",
    246                             vol->devname, vol->svc_id);
    247                         vol->status = HR_VOL_DEGRADED;
     241
     242                        hr_update_vol_status(vol, HR_VOL_DEGRADED);
     243
    248244                        if (vol->hotspare_no > 0) {
    249245                                fid_t fib = fibril_create(hr_raid1_rebuild,
    250246                                    vol);
    251                                 if (fib == 0) {
    252                                         return EINVAL;
    253                                 }
     247                                if (fib == 0)
     248                                        return ENOMEM;
    254249                                fibril_start(fib);
    255250                                fibril_detach(fib);
     
    258253                return EOK;
    259254        } else {
    260                 if (old_state != HR_VOL_ONLINE) {
    261                         HR_WARN("RAID 1 array \"%s\" (%lu) has all extents "
    262                             "active, marking volume as ONLINE",
    263                             vol->devname, vol->svc_id);
    264                         vol->status = HR_VOL_ONLINE;
    265                 }
     255                if (old_state != HR_VOL_ONLINE)
     256                        hr_update_vol_status(vol, HR_VOL_ONLINE);
    266257                return EOK;
    267258        }
     
    297288
    298289        rc = hr_raid1_check_vol_status(vol);
    299         if (rc != EOK) {
    300                 fibril_mutex_unlock(&vol->lock);
    301                 return EIO;
    302         }
     290        if (rc != EOK)
     291                goto end;
    303292
    304293        size_t successful = 0;
     
    352341        default:
    353342                rc = EINVAL;
     343                goto end;
    354344        }
    355345
     
    359349                rc = EIO;
    360350
     351end:
    361352        (void)hr_raid1_update_vol_status(vol);
    362353        fibril_mutex_unlock(&vol->lock);
     
    400391        }
    401392
     393        size_t hotspare_idx = vol->hotspare_no - 1;
     394
     395        hr_ext_status_t hs_state = vol->hotspares[hotspare_idx].status;
     396        if (hs_state != HR_EXT_HOTSPARE) {
     397                HR_ERROR("hr_raid1_rebuild(): invalid hotspare state \"%s\", "
     398                    "aborting rebuild\n", hr_get_ext_status_msg(hs_state));
     399                rc = EINVAL;
     400                goto end;
     401        }
     402
     403        HR_DEBUG("hr_raid1_rebuild(): swapping in hotspare\n");
     404
    402405        block_fini(vol->extents[bad].svc_id);
    403406
    404         size_t hotspare_idx = vol->hotspare_no - 1;
    405 
    406         vol->rebuild_blk = 0;
    407407        vol->extents[bad].svc_id = vol->hotspares[hotspare_idx].svc_id;
    408         hr_update_ext_status(vol, bad, HR_EXT_REBUILD);
     408        hr_update_ext_status(vol, bad, HR_EXT_HOTSPARE);
    409409
    410410        vol->hotspares[hotspare_idx].svc_id = 0;
    411         vol->hotspares[hotspare_idx].status = HR_EXT_MISSING;
     411        hr_update_hotspare_status(vol, hotspare_idx, HR_EXT_MISSING);
     412
    412413        vol->hotspare_no--;
    413414
    414         HR_WARN("hr_raid1_rebuild(): changing volume \"%s\" (%lu) state "
    415             "from %s to %s\n", vol->devname, vol->svc_id,
    416             hr_get_vol_status_msg(vol->status),
    417             hr_get_vol_status_msg(HR_VOL_REBUILD));
    418         vol->status = HR_VOL_REBUILD;
    419 
    420         hr_extent_t *hotspare = &vol->extents[bad];
    421 
    422         HR_DEBUG("hr_raid1_rebuild(): initing (%lu)\n", hotspare->svc_id);
    423 
    424         rc = block_init(hotspare->svc_id);
     415        hr_extent_t *rebuild_ext = &vol->extents[bad];
     416
     417        rc = block_init(rebuild_ext->svc_id);
    425418        if (rc != EOK) {
    426419                HR_ERROR("hr_raid1_rebuild(): initing (%lu) failed, "
    427                     "aborting rebuild\n", hotspare->svc_id);
     420                    "aborting rebuild\n", rebuild_ext->svc_id);
    428421                goto end;
    429422        }
     423
     424        HR_DEBUG("hr_raid1_rebuild(): starting rebuild on (%lu)\n",
     425            rebuild_ext->svc_id);
     426
     427        hr_update_ext_status(vol, bad, HR_EXT_REBUILD);
     428        hr_update_vol_status(vol, HR_VOL_REBUILD);
    430429
    431430        size_t left = vol->data_blkno;
     
    435434        hr_extent_t *ext;
    436435
     436        vol->rebuild_blk = 0;
     437
    437438        size_t cnt;
    438439        uint64_t ba = 0;
    439440        hr_add_ba_offset(vol, &ba);
     441
    440442        while (left != 0) {
    441443                vol->rebuild_blk = ba;
     
    462464                }
    463465
    464                 rc = block_write_direct(hotspare->svc_id, ba, cnt, buf);
     466                rc = block_write_direct(rebuild_ext->svc_id, ba, cnt, buf);
    465467                if (rc != EOK) {
    466468                        hr_raid1_handle_extent_error(vol, bad, rc);
  • uspace/srv/bd/hr/raid4.c

    r65706f1 ra0c3080  
    161161
    162162        vol->hotspares[vol->hotspare_no].svc_id = hotspare;
    163         vol->hotspares[vol->hotspare_no].status = HR_EXT_HOTSPARE;
     163        hr_update_hotspare_status(vol, vol->hotspare_no, HR_EXT_HOTSPARE);
     164
    164165        vol->hotspare_no++;
    165166
     
    172173                fid_t fib = fibril_create(hr_raid4_rebuild, vol);
    173174                if (fib == 0)
    174                         return EINVAL;
     175                        return ENOMEM;
    175176                fibril_start(fib);
    176177                fibril_detach(fib);
     
    233234            vol->status == HR_VOL_REBUILD)
    234235                return EOK;
    235         return EINVAL;
     236        return EIO;
    236237}
    237238
     
    258259        switch (bad) {
    259260        case 0:
    260                 if (old_state != HR_VOL_ONLINE) {
    261                         HR_WARN("RAID 4 has all extents online, "
    262                             "marking \"%s\" (%lu) as ONLINE",
    263                             vol->devname, vol->svc_id);
    264                         vol->status = HR_VOL_ONLINE;
    265                 }
     261                if (old_state != HR_VOL_ONLINE)
     262                        hr_update_vol_status(vol, HR_VOL_ONLINE);
    266263                return EOK;
    267264        case 1:
    268265                if (old_state != HR_VOL_DEGRADED &&
    269266                    old_state != HR_VOL_REBUILD) {
    270                         HR_WARN("RAID 4 array \"%s\" (%lu) has 1 extent "
    271                             "inactive, marking as DEGRADED",
    272                             vol->devname, vol->svc_id);
    273                         vol->status = HR_VOL_DEGRADED;
     267
     268                        hr_update_vol_status(vol, HR_VOL_DEGRADED);
     269
    274270                        if (vol->hotspare_no > 0) {
    275271                                fid_t fib = fibril_create(hr_raid4_rebuild,
    276272                                    vol);
    277                                 if (fib == 0) {
    278                                         return EINVAL;
    279                                 }
     273                                if (fib == 0)
     274                                        return ENOMEM;
    280275                                fibril_start(fib);
    281276                                fibril_detach(fib);
     
    284279                return EOK;
    285280        default:
    286                 if (old_state != HR_VOL_FAULTY) {
    287                         HR_WARN("RAID 4 array \"%s\" (%lu) has more "
    288                             "than one 1 extent unusable, marking as FAULTY",
    289                             vol->devname, vol->svc_id);
    290                         vol->status = HR_VOL_FAULTY;
    291                 }
    292                 return EINVAL;
     281                if (old_state != HR_VOL_FAULTY)
     282                        hr_update_vol_status(vol, HR_VOL_FAULTY);
     283                return EIO;
    293284        }
    294285}
     
    560551
    561552        left = cnt;
     553
    562554        while (left != 0) {
    563555                phys_block = ext_stripe * strip_size + strip_off;
     
    670662        }
    671663
     664        size_t hotspare_idx = vol->hotspare_no - 1;
     665
     666        hr_ext_status_t hs_state = vol->hotspares[hotspare_idx].status;
     667        if (hs_state != HR_EXT_HOTSPARE) {
     668                HR_ERROR("hr_raid4_rebuild(): invalid hotspare state \"%s\", "
     669                    "aborting rebuild\n", hr_get_ext_status_msg(hs_state));
     670                rc = EINVAL;
     671                goto end;
     672        }
     673
     674        HR_DEBUG("hr_raid4_rebuild(): swapping in hotspare\n");
     675
    672676        block_fini(vol->extents[bad].svc_id);
    673677
    674         size_t hotspare_idx = vol->hotspare_no - 1;
    675 
    676678        vol->extents[bad].svc_id = vol->hotspares[hotspare_idx].svc_id;
    677         hr_update_ext_status(vol, bad, HR_EXT_REBUILD);
     679        hr_update_ext_status(vol, bad, HR_EXT_HOTSPARE);
    678680
    679681        vol->hotspares[hotspare_idx].svc_id = 0;
    680         vol->hotspares[hotspare_idx].status = HR_EXT_MISSING;
     682        hr_update_hotspare_status(vol, hotspare_idx, HR_EXT_MISSING);
     683
    681684        vol->hotspare_no--;
    682685
    683         HR_WARN("hr_raid4_rebuild(): changing volume \"%s\" (%lu) state "
    684             "from %s to %s\n", vol->devname, vol->svc_id,
    685             hr_get_vol_status_msg(vol->status),
    686             hr_get_vol_status_msg(HR_VOL_REBUILD));
    687         vol->status = HR_VOL_REBUILD;
    688 
    689         hr_extent_t *hotspare = &vol->extents[bad];
    690 
    691         HR_DEBUG("hr_raid4_rebuild(): initing (%lu)\n", hotspare->svc_id);
    692 
    693         rc = block_init(hotspare->svc_id);
     686        hr_extent_t *rebuild_ext = &vol->extents[bad];
     687
     688        rc = block_init(rebuild_ext->svc_id);
    694689        if (rc != EOK) {
    695690                HR_ERROR("hr_raid4_rebuild(): initing (%lu) failed, "
    696                     "aborting rebuild\n", hotspare->svc_id);
     691                    "aborting rebuild\n", rebuild_ext->svc_id);
    697692                goto end;
    698693        }
     694
     695        HR_DEBUG("hr_raid4_rebuild(): starting rebuild on (%lu)\n",
     696            rebuild_ext->svc_id);
     697
     698        hr_update_ext_status(vol, bad, HR_EXT_REBUILD);
     699        hr_update_vol_status(vol, HR_VOL_REBUILD);
    699700
    700701        uint64_t max_blks = DATA_XFER_LIMIT / vol->bsize;
     
    705706        uint64_t ba = 0, cnt;
    706707        hr_add_ba_offset(vol, &ba);
     708
    707709        while (left != 0) {
    708710                cnt = min(left, max_blks);
     
    735737                }
    736738
    737                 rc = block_write_direct(hotspare->svc_id, ba, cnt, xorbuf);
     739                rc = block_write_direct(rebuild_ext->svc_id, ba, cnt, xorbuf);
    738740                if (rc != EOK) {
    739741                        hr_raid4_handle_extent_error(vol, bad, rc);
  • uspace/srv/bd/hr/raid5.c

    r65706f1 ra0c3080  
    158158
    159159        vol->hotspares[vol->hotspare_no].svc_id = hotspare;
    160         vol->hotspares[vol->hotspare_no].status = HR_EXT_HOTSPARE;
     160        hr_update_hotspare_status(vol, vol->hotspare_no, HR_EXT_HOTSPARE);
     161
    161162        vol->hotspare_no++;
    162163
     
    169170                fid_t fib = fibril_create(hr_raid5_rebuild, vol);
    170171                if (fib == 0)
    171                         return EINVAL;
     172                        return ENOMEM;
    172173                fibril_start(fib);
    173174                fibril_detach(fib);
     
    230231            vol->status == HR_VOL_REBUILD)
    231232                return EOK;
    232         return EINVAL;
     233        return EIO;
    233234}
    234235
     
    255256        switch (bad) {
    256257        case 0:
    257                 if (old_state != HR_VOL_ONLINE) {
    258                         HR_WARN("RAID 5 has all extents online, "
    259                             "marking \"%s\" (%lu) as ONLINE",
    260                             vol->devname, vol->svc_id);
    261                         vol->status = HR_VOL_ONLINE;
    262                 }
     258                if (old_state != HR_VOL_ONLINE)
     259                        hr_update_vol_status(vol, HR_VOL_ONLINE);
    263260                return EOK;
    264261        case 1:
    265262                if (old_state != HR_VOL_DEGRADED &&
    266263                    old_state != HR_VOL_REBUILD) {
    267                         HR_WARN("RAID 5 array \"%s\" (%lu) has 1 extent "
    268                             "inactive, marking as DEGRADED",
    269                             vol->devname, vol->svc_id);
    270                         vol->status = HR_VOL_DEGRADED;
     264
     265                        hr_update_vol_status(vol, HR_VOL_DEGRADED);
     266
    271267                        if (vol->hotspare_no > 0) {
    272268                                fid_t fib = fibril_create(hr_raid5_rebuild,
    273269                                    vol);
    274                                 if (fib == 0) {
    275                                         return EINVAL;
    276                                 }
     270                                if (fib == 0)
     271                                        return ENOMEM;
    277272                                fibril_start(fib);
    278273                                fibril_detach(fib);
     
    281276                return EOK;
    282277        default:
    283                 if (old_state != HR_VOL_FAULTY) {
    284                         HR_WARN("RAID 5 array \"%s\" (%lu) has more "
    285                             "than one 1 extent inactive, marking as FAULTY",
    286                             vol->devname, vol->svc_id);
    287                         vol->status = HR_VOL_FAULTY;
    288                 }
    289                 return EINVAL;
     278                if (old_state != HR_VOL_FAULTY)
     279                        hr_update_vol_status(vol, HR_VOL_FAULTY);
     280                return EIO;
    290281        }
    291282}
     
    560551
    561552        left = cnt;
     553
    562554        while (left != 0) {
    563555                phys_block = ext_stripe * strip_size + strip_off;
     
    674666        }
    675667
     668        size_t hotspare_idx = vol->hotspare_no - 1;
     669
     670        hr_ext_status_t hs_state = vol->hotspares[hotspare_idx].status;
     671        if (hs_state != HR_EXT_HOTSPARE) {
     672                HR_ERROR("hr_raid5_rebuild(): invalid hotspare state \"%s\", "
     673                    "aborting rebuild\n", hr_get_ext_status_msg(hs_state));
     674                rc = EINVAL;
     675                goto end;
     676        }
     677
     678        HR_DEBUG("hr_raid5_rebuild(): swapping in hotspare\n");
     679
    676680        block_fini(vol->extents[bad].svc_id);
    677681
    678         size_t hotspare_idx = vol->hotspare_no - 1;
    679 
    680682        vol->extents[bad].svc_id = vol->hotspares[hotspare_idx].svc_id;
    681         hr_update_ext_status(vol, bad, HR_EXT_REBUILD);
     683        hr_update_ext_status(vol, bad, HR_EXT_HOTSPARE);
    682684
    683685        vol->hotspares[hotspare_idx].svc_id = 0;
    684         vol->hotspares[hotspare_idx].status = HR_EXT_MISSING;
     686        hr_update_hotspare_status(vol, hotspare_idx, HR_EXT_MISSING);
     687
    685688        vol->hotspare_no--;
    686689
    687         HR_WARN("hr_raid5_rebuild(): changing volume \"%s\" (%lu) state "
    688             "from %s to %s\n", vol->devname, vol->svc_id,
    689             hr_get_vol_status_msg(vol->status),
    690             hr_get_vol_status_msg(HR_VOL_REBUILD));
    691         vol->status = HR_VOL_REBUILD;
    692 
    693         hr_extent_t *hotspare = &vol->extents[bad];
    694 
    695         HR_DEBUG("hr_raid5_rebuild(): initing (%lu)\n", hotspare->svc_id);
    696 
    697         rc = block_init(hotspare->svc_id);
     690        hr_extent_t *rebuild_ext = &vol->extents[bad];
     691
     692        rc = block_init(rebuild_ext->svc_id);
    698693        if (rc != EOK) {
    699694                HR_ERROR("hr_raid5_rebuild(): initing (%lu) failed, "
    700                     "aborting rebuild\n", hotspare->svc_id);
     695                    "aborting rebuild\n", rebuild_ext->svc_id);
    701696                goto end;
    702697        }
     698
     699        HR_DEBUG("hr_raid5_rebuild(): starting rebuild on (%lu)\n",
     700            rebuild_ext->svc_id);
     701
     702        hr_update_ext_status(vol, bad, HR_EXT_REBUILD);
     703        hr_update_vol_status(vol, HR_VOL_REBUILD);
    703704
    704705        uint64_t max_blks = DATA_XFER_LIMIT / vol->bsize;
     
    709710        uint64_t ba = 0, cnt;
    710711        hr_add_ba_offset(vol, &ba);
     712
    711713        while (left != 0) {
    712714                cnt = min(left, max_blks);
     
    741743                }
    742744
    743                 rc = block_write_direct(hotspare->svc_id, ba, cnt, xorbuf);
     745                rc = block_write_direct(rebuild_ext->svc_id, ba, cnt, xorbuf);
    744746                if (rc != EOK) {
    745747                        hr_raid5_handle_extent_error(vol, bad, rc);
  • uspace/srv/bd/hr/util.c

    r65706f1 ra0c3080  
    204204}
    205205
    206 void hr_update_ext_status(hr_volume_t *vol, uint64_t extent, hr_ext_status_t s)
    207 {
    208         HR_WARN("vol %s, changing extent: %lu, to status: %s",
    209             vol->devname, extent, hr_get_ext_status_msg(s));
     206void hr_update_ext_status(hr_volume_t *vol, size_t extent, hr_ext_status_t s)
     207{
     208        hr_ext_status_t old = vol->extents[extent].status;
     209        HR_WARN("\"%s\": changing state of extent %lu: %s -> %s\n",
     210            vol->devname, extent, hr_get_ext_status_msg(old),
     211            hr_get_ext_status_msg(s));
    210212        vol->extents[extent].status = s;
     213}
     214
     215void hr_update_hotspare_status(hr_volume_t *vol, size_t hs, hr_ext_status_t s)
     216{
     217        hr_ext_status_t old = vol->hotspares[hs].status;
     218        HR_WARN("\"%s\": changing state of hotspare %lu: %s -> %s\n",
     219            vol->devname, hs, hr_get_ext_status_msg(old),
     220            hr_get_ext_status_msg(s));
     221        vol->hotspares[hs].status = s;
     222}
     223
     224void hr_update_vol_status(hr_volume_t *vol, hr_vol_status_t s)
     225{
     226        HR_WARN("\"%s\": changing state: %s -> %s\n", vol->devname,
     227            hr_get_vol_status_msg(vol->status), hr_get_vol_status_msg(s));
     228        vol->status = s;
    211229}
    212230
  • uspace/srv/bd/hr/util.h

    r65706f1 ra0c3080  
    5656extern errno_t hr_check_ba_range(hr_volume_t *, size_t, uint64_t);
    5757extern void hr_add_ba_offset(hr_volume_t *, uint64_t *);
    58 extern void hr_update_ext_status(hr_volume_t *, uint64_t, hr_ext_status_t);
     58extern void hr_update_ext_status(hr_volume_t *, size_t, hr_ext_status_t);
     59extern void hr_update_hotspare_status(hr_volume_t *, size_t, hr_ext_status_t);
     60extern void hr_update_vol_status(hr_volume_t *, hr_vol_status_t);
    5961extern void hr_sync_all_extents(hr_volume_t *);
    6062extern size_t hr_count_extents(hr_volume_t *, hr_ext_status_t);
Note: See TracChangeset for help on using the changeset viewer.