/* * basil_request - issue BASIL request and parse response * @bp: method-dependent parse data to guide the parsing process * * Returns 0 if ok, a negative %basil_error otherwise. */ int basil_request(struct basil_parse_data *bp) { int to_child, from_child; int ec, rc = -BE_UNKNOWN; FILE *apbasil; pid_t pid; if (log_sel == -1) _init_log_config(); if (!cray_conf->apbasil) { error("No alps client defined"); return 0; } assert(bp->version < BV_MAX); assert(bp->method > BM_none && bp->method < BM_MAX); pid = popen2(cray_conf->apbasil, &to_child, &from_child, true); if (pid < 0) fatal("popen2(\"%s\", ...)", cray_conf->apbasil); /* write out request */ apbasil = fdopen(to_child, "w"); if (apbasil == NULL) fatal("fdopen(): %s", strerror(errno)); setlinebuf(apbasil); _write_xml(apbasil, "<?xml version=\"1.0\"?>\n" "<BasilRequest protocol=\"%s\" method=\"%s\" ", bv_names[bp->version], bm_names[bp->method]); switch (bp->method) { case BM_engine: _write_xml(apbasil, "type=\"ENGINE\"/>"); break; case BM_inventory: _write_xml(apbasil, "type=\"INVENTORY\"/>"); break; case BM_reserve: _write_xml(apbasil, ">\n"); _rsvn_write_reserve_xml(apbasil, bp->mdata.res); break; case BM_confirm: if (bp->version == BV_1_0 && *bp->mdata.res->batch_id != '\0') _write_xml(apbasil, "job_name=\"%s\" ", bp->mdata.res->batch_id); _write_xml(apbasil, "reservation_id=\"%u\" %s=\"%llu\"/>\n", bp->mdata.res->rsvn_id, bp->version >= BV_3_1 ? "pagg_id" : "admin_cookie", (unsigned long long)bp->mdata.res->pagg_id); break; case BM_release: _write_xml(apbasil, "reservation_id=\"%u\"/>\n", bp->mdata.res->rsvn_id); break; case BM_switch: { char *suspend = bp->mdata.res->suspended ? "OUT" : "IN"; _write_xml(apbasil, ">\n"); _write_xml(apbasil, " <ReservationArray>\n"); _write_xml(apbasil, " <Reservation reservation_id=\"%u\" " "action=\"%s\"/>\n", bp->mdata.res->rsvn_id, suspend); _write_xml(apbasil, " </ReservationArray>\n"); _write_xml(apbasil, "</BasilRequest>\n"); } break; default: /* ignore BM_none, BM_MAX, and BM_UNKNOWN covered above */ break; } if (fclose(apbasil) < 0) /* also closes to_child */ error("fclose(apbasil): %s", strerror(errno)); rc = parse_basil(bp, from_child); ec = wait_for_child(pid); if (ec) { error("%s child process for BASIL %s method exited with %d", cray_conf->apbasil, bm_names[bp->method], ec); } return rc; }
/* * basil_request - issue BASIL request and parse response * @bp: method-dependent parse data to guide the parsing process * * Returns 0 if ok, a negative %basil_error otherwise. */ int basil_request(struct basil_parse_data *bp) { int to_child, from_child; int ec, i, rc = -BE_UNKNOWN; FILE *apbasil; pid_t pid = -1; pthread_t thread; pthread_attr_t attr; int time_it_out = 1; DEF_TIMERS; if (log_sel == -1) _init_log_config(); if (!cray_conf->apbasil) { error("No alps client defined"); return 0; } if ((cray_conf->apbasil_timeout == 0) || (cray_conf->apbasil_timeout == (uint16_t) NO_VAL)) { debug2("No ApbasilTimeout configured (%u)", cray_conf->apbasil_timeout); time_it_out = 0; } else { slurm_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); } assert(bp->version < BV_MAX); assert(bp->method > BM_none && bp->method < BM_MAX); START_TIMER; for (i = 0; ((i < 10) && (pid < 0)); i++) { if (i) usleep(100000); pid = popen2(cray_conf->apbasil, &to_child, &from_child, true); } if (pid < 0) fatal("popen2(\"%s\", ...)", cray_conf->apbasil); if (time_it_out) { pthread_create(&thread, &attr, _timer_func, (void*)&pid); } /* write out request */ apbasil = fdopen(to_child, "w"); if (apbasil == NULL) fatal("fdopen(): %s", strerror(errno)); setlinebuf(apbasil); _write_xml(apbasil, "<?xml version=\"1.0\"?>\n" "<BasilRequest protocol=\"%s\" method=\"%s\" ", bv_names[bp->version], bm_names[bp->method]); switch (bp->method) { case BM_engine: _write_xml(apbasil, "type=\"ENGINE\"/>"); break; case BM_inventory: _write_xml(apbasil, "type=\"INVENTORY\"/>"); break; case BM_reserve: _write_xml(apbasil, ">\n"); _rsvn_write_reserve_xml(apbasil, bp->mdata.res, bp->version); break; case BM_confirm: if (bp->version == BV_1_0 && *bp->mdata.res->batch_id != '\0') _write_xml(apbasil, "job_name=\"%s\" ", bp->mdata.res->batch_id); _write_xml(apbasil, "reservation_id=\"%u\" %s=\"%llu\"/>\n", bp->mdata.res->rsvn_id, bp->version >= BV_3_1 ? "pagg_id" : "admin_cookie", (unsigned long long)bp->mdata.res->pagg_id); break; case BM_release: _write_xml(apbasil, "reservation_id=\"%u\"/>\n", bp->mdata.res->rsvn_id); break; case BM_switch: { char *suspend = bp->mdata.res->suspended ? "OUT" : "IN"; _write_xml(apbasil, ">\n"); _write_xml(apbasil, " <ReservationArray>\n"); _write_xml(apbasil, " <Reservation reservation_id=\"%u\" " "action=\"%s\"/>\n", bp->mdata.res->rsvn_id, suspend); _write_xml(apbasil, " </ReservationArray>\n"); _write_xml(apbasil, "</BasilRequest>\n"); } break; default: /* ignore BM_none, BM_MAX, and BM_UNKNOWN covered above */ break; } if (fclose(apbasil) < 0) /* also closes to_child */ error("fclose(apbasil): %s", strerror(errno)); rc = parse_basil(bp, from_child); ec = wait_for_child(pid); if (time_it_out) { slurm_attr_destroy(&attr); debug2("Killing the timer thread."); pthread_mutex_lock(&timer_lock); pthread_cond_broadcast(&timer_cond); pthread_mutex_unlock(&timer_lock); } END_TIMER; if (ec) { error("%s child process for BASIL %s method exited with %d", cray_conf->apbasil, bm_names[bp->method], ec); } else if (DELTA_TIMER > 5000000) { /* 5 seconds limit */ info("%s child process for BASIL %s method time %s", cray_conf->apbasil, bm_names[bp->method], TIME_STR); } return rc; }