Changeset d1d355f in mainline for uspace/srv


Ignore:
Timestamp:
2025-05-06T21:30:30Z (10 months ago)
Author:
Miroslav Cimerman <mc@…>
Children:
c2f0160
Parents:
40f56a4
Message:

hr: refactor hrctl and some hr IPC methods

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

Legend:

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

    r40f56a4 rd1d355f  
    6161static void hr_auto_assemble_srv(ipc_call_t *);
    6262static void hr_stop_srv(ipc_call_t *);
     63static void hr_stop_all_srv(ipc_call_t *);
    6364static void hr_add_hotspare_srv(ipc_call_t *);
    6465static void hr_print_status_srv(ipc_call_t *);
     
    163164        fibril_rwlock_write_unlock(&hr_volumes_lock);
    164165
    165         HR_DEBUG("created volume \"%s\" (%" PRIun ")\n", vol->devname,
    166             vol->svc_id);
     166        HR_NOTE("created volume \"%s\"\n", vol->devname);
    167167
    168168        free(cfg);
     
    275275        errno_t rc = EOK;
    276276        service_id_t svc_id;
    277         long fail_extent;
    278277        hr_volume_t *vol;
    279278
    280279        svc_id = ipc_get_arg1(icall);
    281         fail_extent = (long)ipc_get_arg2(icall);
    282280
    283281        vol = hr_get_volume(svc_id);
     
    287285        }
    288286
    289         if (fail_extent == -1) {
    290                 rc = hr_remove_volume(svc_id);
    291                 if (rc != EOK) {
    292                         async_answer_0(icall, rc);
    293                         return;
     287        rc = hr_remove_volume(vol);
     288
     289        async_answer_0(icall, rc);
     290}
     291
     292static void hr_stop_all_srv(ipc_call_t *icall)
     293{
     294        HR_DEBUG("%s()", __func__);
     295
     296        hr_volume_t *vol;
     297        errno_t rc = EOK;
     298
     299        while (true) {
     300                fibril_rwlock_write_lock(&hr_volumes_lock);
     301                if (list_empty(&hr_volumes)) {
     302                        fibril_rwlock_write_unlock(&hr_volumes_lock);
     303                        break;
    294304                }
    295         } else {
    296                 fibril_rwlock_write_lock(&vol->states_lock);
    297                 fibril_rwlock_read_lock(&vol->extents_lock);
    298 
    299                 /* TODO: maybe expose extent state callbacks */
    300                 hr_update_ext_status(vol, fail_extent, HR_EXT_FAILED);
    301                 hr_mark_vol_state_dirty(vol);
    302 
    303                 fibril_rwlock_read_unlock(&vol->extents_lock);
    304                 fibril_rwlock_write_unlock(&vol->states_lock);
    305 
    306                 vol->hr_ops.status_event(vol);
    307         }
    308         async_answer_0(icall, rc);
     305
     306                vol = list_pop(&hr_volumes, hr_volume_t, lvolumes);
     307
     308                fibril_rwlock_write_unlock(&hr_volumes_lock);
     309
     310                rc = hr_remove_volume(vol);
     311                if (rc != EOK)
     312                        break;
     313        }
     314
     315        async_answer_0(icall, rc);
     316}
     317
     318static void hr_fail_extent_srv(ipc_call_t *icall)
     319{
     320        HR_DEBUG("%s()", __func__);
     321
     322        service_id_t svc_id;
     323        size_t fail_extent;
     324        hr_volume_t *vol;
     325
     326        svc_id = (service_id_t)ipc_get_arg1(icall);
     327        fail_extent = (size_t)ipc_get_arg2(icall);
     328
     329        vol = hr_get_volume(svc_id);
     330        if (vol == NULL) {
     331                async_answer_0(icall, ENOENT);
     332                return;
     333        }
     334
     335        fibril_rwlock_write_lock(&vol->states_lock);
     336        fibril_rwlock_read_lock(&vol->extents_lock);
     337
     338        hr_update_ext_status(vol, fail_extent, HR_EXT_FAILED);
     339        hr_mark_vol_state_dirty(vol);
     340
     341        fibril_rwlock_read_unlock(&vol->extents_lock);
     342        fibril_rwlock_write_unlock(&vol->states_lock);
     343
     344        vol->hr_ops.status_event(vol);
     345
     346        async_answer_0(icall, EOK);
    309347}
    310348
     
    438476                        hr_stop_srv(&call);
    439477                        break;
     478                case HR_STOP_ALL:
     479                        hr_stop_all_srv(&call);
     480                        break;
     481                case HR_FAIL_EXTENT:
     482                        hr_fail_extent_srv(&call);
     483                        break;
    440484                case HR_ADD_HOTSPARE:
    441485                        hr_add_hotspare_srv(&call);
  • uspace/srv/bd/hr/util.c

    r40f56a4 rd1d355f  
    162162void hr_destroy_vol_struct(hr_volume_t *vol)
    163163{
     164        HR_DEBUG("%s()", __func__);
     165
    164166        if (vol == NULL)
    165167                return;
     
    173175hr_volume_t *hr_get_volume(service_id_t svc_id)
    174176{
    175         HR_DEBUG("hr_get_volume(): (%" PRIun ")\n", svc_id);
     177        HR_DEBUG("%s()", __func__);
    176178
    177179        hr_volume_t *rvol = NULL;
     
    189191}
    190192
    191 errno_t hr_remove_volume(service_id_t svc_id)
    192 {
    193         HR_DEBUG("hr_remove_volume(): (%" PRIun ")\n", svc_id);
    194 
    195         errno_t rc;
     193errno_t hr_remove_volume(hr_volume_t *vol)
     194{
     195        HR_DEBUG("%s()", __func__);
    196196
    197197        fibril_rwlock_write_lock(&hr_volumes_lock);
    198         list_foreach(hr_volumes, lvolumes, hr_volume_t, vol) {
    199                 if (vol->svc_id == svc_id) {
    200                         int open_cnt = atomic_load_explicit(&vol->open_cnt,
    201                             memory_order_relaxed);
    202                         /*
    203                          * The "atomicity" of this if condition is provided
    204                          * by the write lock - no new bd connection can
    205                          * come, because we need to get the bd_srvs_t from
    206                          * volume, which we get from the list.
    207                          * (see hr_client_conn() in hr.c)
    208                          */
    209                         if (open_cnt > 0) {
    210                                 fibril_rwlock_write_unlock(&hr_volumes_lock);
    211                                 return EBUSY;
    212                         }
    213                         list_remove(&vol->lvolumes);
    214                         fibril_rwlock_write_unlock(&hr_volumes_lock);
    215 
    216                         vol->meta_ops->save(vol, NO_STATE_CALLBACK);
    217 
    218                         hr_destroy_vol_struct(vol);
    219 
    220                         rc = loc_service_unregister(hr_srv, svc_id);
    221                         return rc;
    222                 }
    223         }
     198
     199        int open_cnt = atomic_load_explicit(&vol->open_cnt,
     200            memory_order_relaxed);
     201        /*
     202         * The atomicity of this if condition (and this whole
     203         * operation) is provided by the write lock - no new
     204         * bd connection can come, because we need to get the
     205         * bd_srvs_t from the volume, which we get from the list.
     206         * (see hr_client_conn() in hr.c)
     207         */
     208        if (open_cnt > 0) {
     209                fibril_rwlock_write_unlock(&hr_volumes_lock);
     210                return EBUSY;
     211        }
     212
     213        list_remove(&vol->lvolumes);
    224214
    225215        fibril_rwlock_write_unlock(&hr_volumes_lock);
    226         return ENOENT;
     216
     217        /* save metadata, but we don't care about states anymore */
     218        (void)vol->meta_ops->save(vol, NO_STATE_CALLBACK);
     219
     220        service_id_t svc_id = vol->svc_id;
     221
     222        HR_NOTE("deactivating volume \"%s\"\n", vol->devname);
     223
     224        hr_destroy_vol_struct(vol);
     225
     226        errno_t rc = loc_service_unregister(hr_srv, svc_id);
     227        return rc;
    227228}
    228229
     
    836837                goto error;
    837838
    838         fibril_rwlock_write_lock(&hr_volumes_lock);
    839 
    840839        /*
    841840         * XXX: register it here
     
    852851         */
    853852        rc = hr_register_volume(vol);
    854         if (rc != EOK) {
    855                 fibril_rwlock_write_unlock(&hr_volumes_lock);
    856                 goto error;
    857         }
     853        if (rc != EOK)
     854                goto error;
    858855
    859856        (void)vol->meta_ops->save(vol, WITH_STATE_CALLBACK);
    860857
     858        fibril_rwlock_write_lock(&hr_volumes_lock);
    861859        list_append(&vol->lvolumes, &hr_volumes);
    862 
    863860        fibril_rwlock_write_unlock(&hr_volumes_lock);
     861
     862        HR_NOTE("assembled volume \"%s\"\n", vol->devname);
    864863
    865864        return EOK;
  • uspace/srv/bd/hr/util.h

    r40f56a4 rd1d355f  
    7171extern void              hr_destroy_vol_struct(hr_volume_t *);
    7272extern hr_volume_t      *hr_get_volume(service_id_t);
    73 extern errno_t           hr_remove_volume(service_id_t);
     73extern errno_t           hr_remove_volume(hr_volume_t *);
    7474extern errno_t           hr_init_extents_from_cfg(hr_volume_t *, hr_config_t *);
    7575extern void              hr_fini_devs(hr_volume_t *);
Note: See TracChangeset for help on using the changeset viewer.