feat(scheduler-snapshot-job-allocation): add dup_job_alloc deep-copy primitive
Task 1.1: new deep-copy for xce_job_alloc_t composed from existing make_alloc/make_host_alloc/make_job_alloc, explicitly preserving each allocation's original from/duration rather than accepting make_alloc's own time(NULL) stamp. TDD: 6 new unit tests (single-host, multi-host, multi-resource-per-host, shared-resource-pool, independence-after-free, from/duration fidelity), all passing under ASAN. Also logs bug-1723 (pre-existing, unrelated leak in two bug-1722 test fixtures, confirmed via git-stash A/B rebuild to be byte-for-byte identical before and after this change) -- documentation only, not fixed here. Requirements: 1.1, 1.4
This commit is contained in:
parent
1b4737360b
commit
097e33ae34
5 changed files with 1023 additions and 418 deletions
|
|
@ -167,6 +167,124 @@ xce_job_alloc_t* make_job_alloc(uint64_t jobid, int nhost,
|
|||
return jalloc;
|
||||
}
|
||||
|
||||
/* dup_job_alloc() (scheduler-snapshot-job-allocation task 1.1) -- deep-copy
|
||||
* a job's resource allocation, independent of the source, for safe
|
||||
* cross-core snapshot restoration (Req 1.1, 1.4). Composed entirely from
|
||||
* make_alloc()/make_host_alloc()/make_job_alloc() below; on any allocation
|
||||
* failure partway through, returns NULL rather than a partial/inconsistent
|
||||
* result -- matching this file's existing convention (make_host_account()/
|
||||
* make_job_account() do not unwind partial state on OOM either; a leak on
|
||||
* this rare path is accepted, not a defect). */
|
||||
|
||||
static xce_alloc_t* dup_alloc(const xce_alloc_t* src)
|
||||
{
|
||||
xce_alloc_t* alloc = NULL;
|
||||
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make_alloc() stamps ->from = time(NULL) internally rather than
|
||||
* accepting the caller's original value, so from/duration are
|
||||
* explicitly re-stamped from src below after construction. */
|
||||
alloc = make_alloc(src->resname, src->reserve, src->instid,
|
||||
(float)src->value, 0);
|
||||
if (alloc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
alloc->from = src->from;
|
||||
alloc->duration = src->duration;
|
||||
|
||||
return alloc;
|
||||
}
|
||||
|
||||
static xce_host_alloc_t* dup_host_alloc(const xce_host_alloc_t* src)
|
||||
{
|
||||
xce_alloc_t** allocs = NULL;
|
||||
xce_host_alloc_t* halloc = NULL;
|
||||
int i;
|
||||
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (src->nallocs > 0) {
|
||||
allocs = (xce_alloc_t**)calloc((size_t)src->nallocs,
|
||||
sizeof(*allocs));
|
||||
if (allocs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < src->nallocs; i++) {
|
||||
allocs[i] = dup_alloc(src->allocs[i]);
|
||||
if (allocs[i] == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
halloc = make_host_alloc(src->host, src->nallocs, allocs);
|
||||
|
||||
return halloc;
|
||||
}
|
||||
|
||||
xce_job_alloc_t* dup_job_alloc(const xce_job_alloc_t* src)
|
||||
{
|
||||
xce_host_alloc_t** hallocs = NULL;
|
||||
xce_alloc_t** shared = NULL;
|
||||
xce_job_alloc_t* jalloc = NULL;
|
||||
int i;
|
||||
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (src->nhosts > 0) {
|
||||
hallocs = (xce_host_alloc_t**)calloc((size_t)src->nhosts,
|
||||
sizeof(*hallocs));
|
||||
if (hallocs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < src->nhosts; i++) {
|
||||
hallocs[i] = dup_host_alloc(src->allocs[i]);
|
||||
if (hallocs[i] == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jalloc = make_job_alloc(src->jobid, src->nhosts, hallocs);
|
||||
if (jalloc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* make_job_alloc() always zeroes nres_shared/allocs_shared itself, so
|
||||
* the shared-resource pool is populated here, after construction --
|
||||
* the same "patch after construct" pattern used for from/duration
|
||||
* above. */
|
||||
if (src->nres_shared > 0) {
|
||||
shared = (xce_alloc_t**)calloc((size_t)src->nres_shared,
|
||||
sizeof(*shared));
|
||||
if (shared == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < src->nres_shared; i++) {
|
||||
shared[i] = dup_alloc(src->allocs_shared[i]);
|
||||
if (shared[i] == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
jalloc->allocs_shared = shared;
|
||||
jalloc->nres_shared = src->nres_shared;
|
||||
}
|
||||
|
||||
return jalloc;
|
||||
}
|
||||
|
||||
xce_job_account_t* make_job_account(xce_job_alloc_t* jalloc)
|
||||
{
|
||||
xce_job_account_t* account = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue