* plugin scheduler: run iceberg and lifecycle lanes concurrently
The default lane serialises job types under a single admin lock
because volume-management operations share global state. Iceberg
and lifecycle lanes have no such constraint, so run each of their
job types independently in separate goroutines.
* Fix concurrent lane scheduler status
* plugin scheduler: address review feedback
- Extract collectDueJobTypes helper to deduplicate policy loading
between locked and concurrent iteration paths.
- Use atomic.Bool instead of sync.Mutex for hadJobs in the concurrent
path.
- Set lane loop state to "busy" before launching concurrent goroutines
so the lane is not reported as idle while work runs.
- Convert TestLaneRequiresLock to table-driven style.
- Add TestRunLaneSchedulerIterationLockBehavior to verify the scheduler
acquires the admin lock only for lanes that require it.
- Fix flaky TestGetLaneSchedulerStatusShowsActiveConcurrentLaneWork by
not starting background scheduler goroutines that race with the
direct runJobTypeIteration call.