int acsAttach() { if (acsConstants) { return 0; } if (getAcssdr() == NULL) { /* ACS can't find ACS SDR. */ return -1; } CHKERR(sdr_begin_xn(acsSdr)); if (acsdbObject == 0) { acsdbObject = sdr_find(acsSdr, acsDbName, NULL); if (acsdbObject == 0) { sdr_exit_xn(acsSdr); return -1; } } acsConstants = &acsConstantsBuf; sdr_read(acsSdr, (char *) acsConstants, acsdbObject, sizeof(AcsDB)); sdr_exit_xn(acsSdr); return 0; }
int dtn2_updateRule(char *nodeNm, char *demux, FwdDirective *directive) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; OBJ_POINTER(Dtn2Plan, plan); Object ruleAddr; Dtn2Rule ruleBuf; CHKERR(nodeNm && demux && directive); if (*demux == '\0') { writeMemo("[?] Zero-length DTN2 rule demux."); return 0; } if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] No plan defined for this node", nodeNm); return 0; } GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt)); dtn2_findRule(nodeName, demux, plan, &ruleAddr, &elt); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Unknown rule", demux); return 0; } /* All parameters validated, okay to update the rule. */ sdr_stage(sdr, (char *) &ruleBuf, ruleAddr, sizeof(Dtn2Rule)); dtn2_destroyDirective(&ruleBuf.directive); memcpy((char *) &ruleBuf.directive, (char *) directive, sizeof(FwdDirective)); sdr_write(sdr, ruleAddr, (char *) &ruleBuf, sizeof(Dtn2Rule)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't update rule.", NULL); return -1; } return 1; }
int dtn2_removeRule(char *nodeNm, char *demux) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; OBJ_POINTER(Dtn2Plan, plan); Object ruleAddr; OBJ_POINTER(Dtn2Rule, rule); CHKERR(nodeNm && demux); if (*demux == '\0') { writeMemo("[?] Zero-length DTN2 rule demux."); return 0; } if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] No plan defined for this node", nodeNm); return 0; } GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt)); dtn2_findRule(nodeName, demux, plan, &ruleAddr, &elt); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Unknown rule", demux); return 0; } /* All parameters validated, okay to remove the rule. */ GET_OBJ_POINTER(sdr, Dtn2Rule, rule, ruleAddr); dtn2_destroyDirective(&(rule->directive)); sdr_free(sdr, ruleAddr); sdr_list_delete(sdr, elt, NULL, NULL); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't remove rule.", NULL); return -1; } return 1; }
static DtnDB *_dtn2Constants() { static DtnDB buf; static DtnDB *db = NULL; Sdr sdr; Object dbObject; if (db == NULL) { sdr = getIonsdr(); CHKNULL(sdr); dbObject = _dtn2dbObject(NULL); if (dbObject) { if (sdr_heap_is_halted(sdr)) { sdr_read(sdr, (char *) &buf, dbObject, sizeof(DtnDB)); } else { CHKNULL(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &buf, dbObject, sizeof(DtnDB)); sdr_exit_xn(sdr); } db = &buf; } } return db; }
int dtn2_removePlan(char *nodeNm) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; Object planObj; OBJ_POINTER(Dtn2Plan, plan); CHKERR(nodeNm); if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Unknown plan", nodeNm); return 0; } planObj = sdr_list_data(sdr, elt); GET_OBJ_POINTER(sdr, Dtn2Plan, plan, planObj); if (sdr_list_length(sdr, plan->rules) > 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Can't remove plan; still has rules", nodeNm); return 0; } /* Okay to remove this plan from the database. */ sdr_list_delete(sdr, elt, NULL, NULL); dtn2_destroyDirective(&(plan->defaultDirective)); sdr_list_destroy(sdr, plan->rules, NULL, NULL); sdr_free(sdr, plan->nodeName); sdr_free(sdr, planObj); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't remove plan.", nodeNm); return -1; } return 1; }
static void executeList(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); PsmPartition ionwm = getIonwm(); IonVdb *vdb = getIonVdb(); PsmAddress elt; PsmAddress addr; char buffer[RFX_NOTE_LEN]; if (tokenCount < 2) { printText("List what?"); return; } if (strcmp(tokens[1], "contact") == 0) { CHKVOID(sdr_begin_xn(sdr)); for (elt = sm_rbt_first(ionwm, vdb->contactIndex); elt; elt = sm_rbt_next(ionwm, elt)) { addr = sm_rbt_data(ionwm, elt); rfx_print_contact(addr, buffer); printText(buffer); } sdr_exit_xn(sdr); return; } if (strcmp(tokens[1], "range") == 0) { CHKVOID(sdr_begin_xn(sdr)); for (elt = sm_rbt_first(ionwm, vdb->rangeIndex); elt; elt = sm_rbt_next(ionwm, elt)) { addr = sm_rbt_data(ionwm, elt); rfx_print_range(addr, buffer); printText(buffer); } sdr_exit_xn(sdr); return; } SYNTAX_ERROR; }
static void applyRateControl(Sdr sdr) { BpVdb *vdb = getBpVdb(); PsmPartition ionwm = getIonwm(); Throttle *throttle; PsmAddress elt; VInduct *induct; VOutduct *outduct; long capacityLimit; sdr_begin_xn(sdr); /* Just to lock memory. */ /* Recalculate limit on local bundle generation. */ manageProductionThrottle(vdb); /* Enable some bundle acquisition. */ for (elt = sm_list_first(ionwm, vdb->inducts); elt; elt = sm_list_next(ionwm, elt)) { induct = (VInduct *) psp(ionwm, sm_list_data(ionwm, elt)); throttle = &(induct->acqThrottle); capacityLimit = throttle->nominalRate << 1; throttle->capacity += throttle->nominalRate; if (throttle->capacity > capacityLimit) { throttle->capacity = capacityLimit; } if (throttle->capacity > 0) { sm_SemGive(throttle->semaphore); } } /* Enable some bundle transmission. */ for (elt = sm_list_first(ionwm, vdb->outducts); elt; elt = sm_list_next(ionwm, elt)) { outduct = (VOutduct *) psp(ionwm, sm_list_data(ionwm, elt)); throttle = &(outduct->xmitThrottle); capacityLimit = throttle->nominalRate << 1; throttle->capacity += throttle->nominalRate; if (throttle->capacity > capacityLimit) { throttle->capacity = capacityLimit; } if (throttle->capacity > 0) { sm_SemGive(throttle->semaphore); } } sdr_exit_xn(sdr); /* Unlock memory. */ }
int dtn2_addPlan(char *nodeNm, FwdDirective *defaultDir) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object nextPlan; Dtn2Plan plan; Object planObj; CHKERR(nodeNm && defaultDir); if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); if (locatePlan(nodeName, &nextPlan) != 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Duplicate plan", nodeNm); return 0; } /* Okay to add this plan to the database. */ plan.nodeName = sdr_string_create(sdr, nodeName); memcpy((char *) &plan.defaultDirective, (char *) defaultDir, sizeof(FwdDirective)); plan.rules = sdr_list_create(sdr); planObj = sdr_malloc(sdr, sizeof(Dtn2Plan)); if (planObj) { if (nextPlan) { oK(sdr_list_insert_before(sdr, nextPlan, planObj)); } else { oK(sdr_list_insert_last(sdr, (_dtn2Constants())->plans, planObj)); } sdr_write(sdr, planObj, (char *) &plan, sizeof(Dtn2Plan)); } if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't add plan.", nodeNm); return -1; } return 1; }
void bp_untrack(Object bundleObj, Object trackingElt) { Sdr sdr = getIonsdr(); OBJ_POINTER(Bundle, bundle); Object elt; CHKVOID(bundleObj && trackingElt); sdr_begin_xn(sdr); GET_OBJ_POINTER(sdr, Bundle, bundle, bundleObj); if (bundle->trackingElts == 0) { sdr_exit_xn(sdr); return; } for (elt = sdr_list_first(sdr, bundle->trackingElts); elt; elt = sdr_list_next(sdr, elt)) { if (sdr_list_data(sdr, elt) == trackingElt) { break; } } if (elt == 0) /* Not found. */ { sdr_exit_xn(sdr); return; } sdr_list_delete(sdr, elt, NULL, NULL); if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed removing bundle tracking elt.", NULL); } }
static void executeInfo(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); ImcDB imcdb; if (tokenCount != 2) { SYNTAX_ERROR; return; } CHKVOID(sdr_begin_xn(sdr)); sdr_read(getIonsdr(), (char *) &imcdb, getImcDbObject(), sizeof(ImcDB)); printKin(strtouvast(tokens[1]), imcdb.parent); sdr_exit_xn(sdr); }
int dtn2Init() { Sdr sdr = getIonsdr(); Object dtn2dbObject; DtnDB dtn2dbBuf; /* Recover the DTN database, creating it if necessary. */ CHKERR(sdr_begin_xn(sdr)); dtn2dbObject = sdr_find(sdr, DTN_DBNAME, NULL); switch (dtn2dbObject) { case -1: /* SDR error. */ sdr_cancel_xn(sdr); putErrmsg("Failed seeking DTN database in SDR.", NULL); return -1; case 0: /* Not found; must create new DB. */ dtn2dbObject = sdr_malloc(sdr, sizeof(DtnDB)); if (dtn2dbObject == 0) { sdr_cancel_xn(sdr); putErrmsg("No space for DTN database.", NULL); return -1; } memset((char *) &dtn2dbBuf, 0, sizeof(DtnDB)); dtn2dbBuf.plans = sdr_list_create(sdr); sdr_write(sdr, dtn2dbObject, (char *) &dtn2dbBuf, sizeof(DtnDB)); sdr_catlg(sdr, DTN_DBNAME, 0, dtn2dbObject); if (sdr_end_xn(sdr)) { putErrmsg("Can't create DTN database.", NULL); return -1; } break; default: /* Found DB in the SDR. */ sdr_exit_xn(sdr); } oK(_dtn2dbObject(&dtn2dbObject)); oK(_dtn2Constants()); return 0; }
void sdrnm_state_get(SdrnmState *state) { Sdr sdr = getIonsdr(); SdrUsageSummary usage; CHKVOID(state); CHKVOID(sdr_begin_xn(sdr)); sdr_usage(sdr, &usage); state->smallPoolSize = usage.smallPoolSize; state->smallPoolFree = usage.smallPoolFree; state->smallPoolAllocated = usage.smallPoolAllocated; state->largePoolSize = usage.largePoolSize; state->largePoolFree = usage.largePoolFree; state->largePoolAllocated = usage.largePoolAllocated; state->unusedSize = usage.unusedSize; sdr_exit_xn(sdr); }
static void executeInfo() { Sdr sdr = getIonsdr(); OBJ_POINTER(CfdpDB, db); char buffer[256]; sdr_begin_xn(sdr); /* Just to lock memory. */ GET_OBJ_POINTER(sdr, CfdpDB, db, getCfdpDbObject()); isprintf(buffer, sizeof buffer, "xncount=%lu, maxtrnbr=%lu, \ fillchar=0x%x, discard=%hu, requirecrc=%hu, segsize=%hu, mtusize = %hu, \ inactivity=%u, ckperiod=%u, maxtimeouts=%u", db->transactionCounter, db->maxTransactionNbr, db->fillCharacter, db->discardIncompleteFile, db->crcRequired, db->maxFileDataLength, db->mtuSize, db->transactionInactivityLimit, db->checkTimerPeriod, db->checkTimeoutLimit); sdr_exit_xn(sdr); printText(buffer); }
int dtn2_updatePlan(char *nodeNm, FwdDirective *defaultDir) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; Object planObj; Dtn2Plan plan; CHKERR(nodeNm && defaultDir); if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] No plan defined for this node", nodeNm); return 0; } /* Okay to update this plan. */ planObj = sdr_list_data(sdr, elt); sdr_stage(sdr, (char *) &plan, planObj, sizeof(Dtn2Plan)); dtn2_destroyDirective(&plan.defaultDirective); memcpy((char *) &plan.defaultDirective, (char *) defaultDir, sizeof(FwdDirective)); sdr_write(sdr, planObj, (char *) &plan, sizeof(Dtn2Plan)); if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't update plan.", nodeNm); return -1; } return 1; }
int acslist(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { #else int main(int argc, char **argv) { if(argc > 1) { if (strcmp(argv[1], "-s") == 0 || strcmp(argv[1], "--stdout") == 0) { printToStdout = 1; argc--; argv++; } } #endif Sdr acsSdr; /* Attach to ACS database. */ if (acsAttach() < 0) { putErrmsg("Can't attach to ACS.", NULL); return 1; } acsSdr = getAcssdr(); /* Lock SDR and check the database. */ CHKZERO(sdr_begin_xn(acsSdr)); printAndCheckByCids(acsSdr); checkByBids(acsSdr); sdr_exit_xn(acsSdr); /* Cleanup */ writeErrmsgMemos(); acsDetach(); bp_detach(); return errors == 0 ? 0 : 1; }
static IonDB *_ionConstants() { static IonDB buf; static IonDB *db = NULL; Sdr sdr; Object dbObject; if (db == NULL) { /* Load constants into a conveniently accessed * structure. Note that this CANNOT be treated * as a current database image in later * processing. */ sdr = _ionsdr(NULL); CHKNULL(sdr); dbObject = _iondbObject(NULL); if (dbObject) { if (sdr_heap_is_halted(sdr)) { sdr_read(sdr, (char *) &buf, dbObject, sizeof(IonDB)); } else { CHKNULL(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &buf, dbObject, sizeof(IonDB)); sdr_exit_xn(sdr); } db = &buf; } } return db; }
int bp_track(Object bundleObj, Object trackingElt) { Sdr sdr = getIonsdr(); OBJ_POINTER(Bundle, bundle); CHKERR(bundleObj && trackingElt); sdr_begin_xn(sdr); GET_OBJ_POINTER(sdr, Bundle, bundle, bundleObj); if (bundle->trackingElts == 0) { sdr_exit_xn(sdr); putErrmsg("Corrupt bundle? Has no trackingElts list.", NULL); return -1; } sdr_list_insert_last(sdr, bundle->trackingElts, trackingElt); if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed adding bundle tracking elt.", NULL); return -1; } return 0; }
static void executeList(int tokenCount, char **tokens) { Sdr sdr = getIonsdr(); ImcDB imcdb; Object elt; OBJ_POINTER(NodeId, node); if (tokenCount != 1) { SYNTAX_ERROR; return; } CHKVOID(sdr_begin_xn(sdr)); sdr_read(getIonsdr(), (char *) &imcdb, getImcDbObject(), sizeof(ImcDB)); for (elt = sdr_list_first(sdr, imcdb.kin); elt; elt = sdr_list_next(sdr, elt)) { GET_OBJ_POINTER(sdr, NodeId, node, sdr_list_data(sdr, elt)); printKin(node->nbr, imcdb.parent); } sdr_exit_xn(sdr); }
int tcpclo(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { char *ductName = (char *) a1; #else int main(int argc, char *argv[]) { char *ductName = (argc > 1 ? argv[1] : NULL); #endif unsigned char *buffer; VOutduct *vduct; PsmAddress vductElt; Sdr sdr; Outduct duct; ClProtocol protocol; Outflow outflows[3]; int i; char *hostName; unsigned short portNbr; unsigned int hostNbr; struct sockaddr socketName; struct sockaddr_in *inetName; int running = 1; pthread_mutex_t mutex; KeepaliveThreadParms parms; ReceiveThreadParms rparms; pthread_t keepaliveThread; pthread_t receiverThread; Object bundleZco; BpExtendedCOS extendedCOS; char destDuctName[MAX_CL_DUCT_NAME_LEN + 1]; unsigned int bundleLength; int ductSocket = -1; int bytesSent; int keepalivePeriod = 0; VInduct *viduct; if (ductName == NULL) { PUTS("Usage: tcpclo <remote host name>[:<port number>]"); return 0; } if (bpAttach() < 0) { putErrmsg("tcpclo can't attach to BP", NULL); return 1; } buffer = MTAKE(TCPCLA_BUFSZ); if (buffer == NULL) { putErrmsg("No memory for TCP buffer in tcpclo.", NULL); return 1; } findOutduct("tcp", ductName, &vduct, &vductElt); if (vductElt == 0) { putErrmsg("No such tcp duct.", ductName); MRELEASE(buffer); return 1; } if (vduct->cloPid != ERROR && vduct->cloPid != sm_TaskIdSelf()) { putErrmsg("CLO task is already started for this duct.", itoa(vduct->cloPid)); MRELEASE(buffer); return 1; } /* All command-line arguments are now validated. */ sdr = getIonsdr(); CHKERR(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &duct, sdr_list_data(sdr, vduct->outductElt), sizeof(Outduct)); sdr_read(sdr, (char *) &protocol, duct.protocol, sizeof(ClProtocol)); sdr_exit_xn(sdr); if (protocol.nominalRate == 0) { vduct->xmitThrottle.nominalRate = DEFAULT_TCP_RATE; } else { vduct->xmitThrottle.nominalRate = protocol.nominalRate; } memset((char *) outflows, 0, sizeof outflows); outflows[0].outboundBundles = duct.bulkQueue; outflows[1].outboundBundles = duct.stdQueue; outflows[2].outboundBundles = duct.urgentQueue; for (i = 0; i < 3; i++) { outflows[i].svcFactor = 1 << i; } hostName = ductName; parseSocketSpec(ductName, &portNbr, &hostNbr); if (portNbr == 0) { portNbr = BpTcpDefaultPortNbr; } portNbr = htons(portNbr); if (hostNbr == 0) { putErrmsg("Can't get IP address for host.", hostName); MRELEASE(buffer); return 1; } hostNbr = htonl(hostNbr); memset((char *) &socketName, 0, sizeof socketName); inetName = (struct sockaddr_in *) &socketName; inetName->sin_family = AF_INET; inetName->sin_port = portNbr; memcpy((char *) &(inetName->sin_addr.s_addr), (char *) &hostNbr, 4); if (_tcpOutductId(&socketName, "tcp", ductName) < 0) { putErrmsg("Can't record TCP Outduct ID for connection.", NULL); MRELEASE(buffer); return -1; } /* Set up signal handling. SIGTERM is shutdown signal. */ oK(tcpcloSemaphore(&(vduct->semaphore))); isignal(SIGTERM, shutDownClo); #ifndef mingw isignal(SIGPIPE, handleConnectionLoss); #endif /* Start the keepalive thread for the eventual connection. */ tcpDesiredKeepAlivePeriod = KEEPALIVE_PERIOD; parms.cloRunning = &running; pthread_mutex_init(&mutex, NULL); parms.mutex = &mutex; parms.socketName = &socketName; parms.ductSocket = &ductSocket; parms.keepalivePeriod = &keepalivePeriod; if (pthread_begin(&keepaliveThread, NULL, sendKeepalives, &parms)) { putSysErrmsg("tcpclo can't create keepalive thread", NULL); MRELEASE(buffer); pthread_mutex_destroy(&mutex); return 1; } // Returns the VInduct Object of first induct with same protocol // as the outduct. The VInduct is required to create an acq area. // The Acq Area inturn uses the throttle information from VInduct // object while receiving bundles. The throttle information // of all inducts of the same induct will be the same, so choosing // any induct will serve the purpose. findVInduct(&viduct,protocol.name); if(viduct == NULL) { putErrmsg("tcpclo can't get VInduct", NULL); MRELEASE(buffer); pthread_mutex_destroy(&mutex); return 1; } rparms.vduct = viduct; rparms.bundleSocket = &ductSocket; rparms.mutex = &mutex; rparms.cloRunning = &running; if (pthread_begin(&receiverThread, NULL, receiveBundles, &rparms)) { putSysErrmsg("tcpclo can't create receive thread", NULL); MRELEASE(buffer); pthread_mutex_destroy(&mutex); return 1; } /* Can now begin transmitting to remote duct. */ { char txt[500]; isprintf(txt, sizeof(txt), "[i] tcpclo is running, spec=[%s:%d].", inet_ntoa(inetName->sin_addr), ntohs(inetName->sin_port)); writeMemo(txt); } while (running && !(sm_SemEnded(tcpcloSemaphore(NULL)))) { if (bpDequeue(vduct, outflows, &bundleZco, &extendedCOS, destDuctName, 0, -1) < 0) { running = 0; /* Terminate CLO. */ continue; } if (bundleZco == 0) /* Interrupted. */ { continue; } CHKZERO(sdr_begin_xn(sdr)); bundleLength = zco_length(sdr, bundleZco); sdr_exit_xn(sdr); pthread_mutex_lock(&mutex); bytesSent = sendBundleByTCPCL(&socketName, &ductSocket, bundleLength, bundleZco, buffer, &keepalivePeriod); pthread_mutex_unlock(&mutex); if(bytesSent < 0) { running = 0; /* Terminate CLO. */ } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } writeMemo("[i] tcpclo done sending"); if (sendShutDownMessage(&ductSocket, SHUT_DN_NO, -1, &socketName) < 0) { putErrmsg("Sending Shutdown message failed!!",NULL); } if (ductSocket != -1) { closesocket(ductSocket); ductSocket=-1; } running = 0; pthread_join(keepaliveThread, NULL); writeMemo("[i] tcpclo keepalive thread killed"); pthread_join(receiverThread, NULL); writeMemo("[i] tcpclo receiver thread killed"); writeErrmsgMemos(); writeMemo("[i] tcpclo duct has ended."); oK(_tcpOutductId(&socketName, NULL, NULL)); MRELEASE(buffer); pthread_mutex_destroy(&mutex); bp_detach(); return 0; }
int acsInitialize(long heapWords, int logLevel) { AcsDB acsdbBuf; unsigned long zero = 0; /* sdr_stow() wants this */ if (heapWords == 0) { /* Caller wants us to supply a default. */ heapWords = ACS_SDR_DEFAULT_HEAPWORDS; } if (ionAttach() < 0) { putErrmsg("Can't attach to ION.", NULL); return -1; } { Sdr sdr = getIonsdr(); IonDB iondb; char *pathname = iondb.parmcopy.pathName; CHKERR(sdr_begin_xn(sdr)); sdr_read(sdr, (char *) &iondb, getIonDbObject(), sizeof(IonDB)); sdr_exit_xn(sdr); #if 0 { char text[100]; sprintf( text, "ION parms pathname : %s", pathname ); writeMemo( text ); } #endif if (sdr_load_profile(acssdrName, SDR_IN_DRAM, heapWords, SM_NO_KEY, pathname, NULL) < 0) { putErrmsg("Unable to load SDR profile for ACS.", NULL); return -1; } else { writeMemo("ACS SDR profile loaded."); } } acsSdr = sdr_start_using(acssdrName); if (acsSdr == NULL) { putErrmsg("Can't start using SDR for ACS.", NULL); return -1; } if (getAcssdr() < 0) { putErrmsg("ACS can't find ACS SDR.", NULL); return -1; } CHKERR(sdr_begin_xn(acsSdr)); acsdbObject = sdr_find(acsSdr, acsDbName, NULL); switch (acsdbObject) { case -1: /* SDR error. */ sdr_cancel_xn(acsSdr); putErrmsg("Can't seek ACS database in SDR.", NULL); return -1; case 0: /* Not found must create new DB. */ memset((char *) &acsdbBuf, 0, sizeof(AcsDB)); acsdbBuf.pendingCusts = sdr_list_create(acsSdr); acsdbBuf.logLevel = logLevel; acsdbBuf.cidHash = sdr_hash_create(acsSdr, sizeof(AcsCustodyId), ACS_CIDHASH_ROWCOUNT, 1); acsdbBuf.bidHash = sdr_hash_create(acsSdr, sizeof(AcsBundleId), ACS_BIDHASH_ROWCOUNT, 1); acsdbBuf.id = sdr_stow(acsSdr, zero); acsdbObject = sdr_malloc(acsSdr, sizeof(AcsDB)); if (acsdbObject == 0) { sdr_cancel_xn(acsSdr); putErrmsg("No space for ACS database.", NULL); return -1; } sdr_write(acsSdr, acsdbObject, (char *) &acsdbBuf, sizeof(AcsDB)); sdr_catlg(acsSdr, acsDbName, 0, acsdbObject); if (sdr_end_xn(acsSdr)) { putErrmsg("Can't create ACS database.", NULL); return -1; } break; default: sdr_exit_xn(acsSdr); } acsConstants = &acsConstantsBuf; CHKERR(sdr_begin_xn(acsSdr)); sdr_read(acsSdr, (char *) acsConstants, acsdbObject, sizeof(AcsDB)); sdr_exit_xn(acsSdr); return 0; }
int trySendAcs(SdrAcsPendingCust *custodian, BpCtReason reasonCode, unsigned char succeeded, const CtebScratchpad *cteb) { Object signalLElt; Object signalAddr; SdrAcsSignal signal; BpEvent timelineEvent; Object newSerializedZco; unsigned long newSerializedLength; int result; Sdr bpSdr = getIonsdr(); /* To prevent deadlock, take bpSdr before acsSdr. */ CHKERR(sdr_begin_xn(bpSdr)); CHKERR(sdr_begin_xn(acsSdr)); signalLElt = findSdrAcsSignal(custodian->signals, reasonCode, succeeded, &signalAddr); if (signalAddr == 0) { ACSLOG_ERROR("Can't find ACS signal"); sdr_exit_xn(acsSdr); sdr_exit_xn(bpSdr); return -1; } sdr_peek(acsSdr, signal, signalAddr); newSerializedLength = serializeAcs(signalAddr, &newSerializedZco, signal.serializedZcoLength); if (newSerializedLength == 0) { ACSLOG_ERROR("Can't serialize new ACS (%lu)", signal.serializedZcoLength); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } ACSLOG_DEBUG("Serialized a new ACS to %s that is %lu long (old: %lu)", custodian->eid, newSerializedLength, signal.serializedZcoLength); /* If serializeAcs() (which serializes an ACS that covers all the "old" * custody IDs as well as 1 "new" custody ID that we're trying to append) * returned an ACS that's larger than the custodian' preferred size, then: * 1) Send the old ACS (the biggest ACS that's smaller than custodian's * preferred size), covering all the old custody IDs but not the new * one. * 2) Make a new ACS that includes only the new custody ID. */ if (custodian->acsSize > 0 && newSerializedLength >= custodian->acsSize) { if(signal.serializedZco == 0) { /* We don't have an old unserialized ACS to send. This means the * first custody signal appended to this ACS exceeded the acsSize * parameter. The best we can do is send this ACS even though it's * bigger than the recommended acsSize. */ ACSLOG_WARN("Appending first CS to %s was bigger than %lu", custodian->eid, custodian->acsSize); signal.serializedZcoLength = newSerializedLength; signal.serializedZco = newSerializedZco; sdr_poke(acsSdr, signalAddr, signal); sendAcs(signalLElt); if(sdr_end_xn(acsSdr) < 0) { ACSLOG_ERROR("Can't serialize ACS bundle."); sdr_cancel_xn(bpSdr); return -1; } if (sdr_end_xn(bpSdr) < 0) { ACSLOG_ERROR("Can't send ACS bundle."); return -1; } return 0; } /* Calling this invalidates our signalLElt and signalAddr pointers, so * we must re-find the signal before using them again. */ sendAcs(signalLElt); /* Add the one that was uncovered by the serialized payload back in */ result = appendToSdrAcsSignals(custodian->signals, signal.pendingCustAddr, reasonCode, succeeded, cteb); switch (result) { case 0: /* Success; continue processing. */ break; default: ACSLOG_ERROR("Can't carry size-limited ID to new ACS"); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } /* Find the uncovered one that we just added. */ signalLElt = findSdrAcsSignal(custodian->signals, reasonCode, succeeded, &signalAddr); if (signalAddr == 0) { ACSLOG_ERROR("Can't find ACS signal"); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } sdr_peek(acsSdr, signal, signalAddr); /* Serialize the new one */ newSerializedLength = serializeAcs(signalAddr, &newSerializedZco, 0); if (newSerializedLength <= 0) { ACSLOG_ERROR("Can't serialize new ACS (%lu)", newSerializedLength); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } } else { if (signal.serializedZco != 0) { /* Free the old payload zco. */ zco_destroy(bpSdr, signal.serializedZco); } } /* Store the new ZCO */ signal.serializedZco = newSerializedZco; signal.serializedZcoLength = newSerializedLength; /* If there is not an ACS generation countdown timer, create one. */ if(signal.acsDue == 0) { timelineEvent.type = csDue; if(custodian->acsDelay == 0) { timelineEvent.time = getUTCTime() + DEFAULT_ACS_DELAY; } else { timelineEvent.time = getUTCTime() + custodian->acsDelay; } timelineEvent.ref = signalLElt; signal.acsDue = insertBpTimelineEvent(&timelineEvent); if (signal.acsDue == 0) { ACSLOG_ERROR("Can't add timeline event to generate ACS"); sdr_cancel_xn(acsSdr); sdr_cancel_xn(bpSdr); return -1; } } sdr_poke(acsSdr, signalAddr, signal); if(sdr_end_xn(acsSdr) < 0) { ACSLOG_ERROR("Can't track ACS"); sdr_cancel_xn(bpSdr); return -1; } if (sdr_end_xn(bpSdr) < 0) { ACSLOG_ERROR("Can't add timeline event to generate ACS"); return -1; } return 0; }
static int dispatchEvents(Sdr sdr, Object events, time_t currentTime) { Object elt; Object eventObj; LtpEvent event; int result; while (1) { sdr_begin_xn(sdr); elt = sdr_list_first(sdr, events); if (elt == 0) /* No more events to dispatch. */ { sdr_exit_xn(sdr); return 0; } eventObj = sdr_list_data(sdr, elt); sdr_read(sdr, (char *) &event, eventObj, sizeof(LtpEvent)); if (event.scheduledTime > currentTime) { /* This is the first future event. */ sdr_exit_xn(sdr); return 0; } sdr_free(sdr, eventObj); sdr_list_delete(sdr, elt, NULL, NULL); switch (event.type) { case LtpResendCheckpoint: result = ltpResendCheckpoint(event.refNbr2, event.refNbr3); break; /* Out of switch. */ case LtpResendXmitCancel: result = ltpResendXmitCancel(event.refNbr2); break; /* Out of switch. */ case LtpResendReport: result = ltpResendReport(event.refNbr1, event.refNbr2, event.refNbr3); break; /* Out of switch. */ case LtpResendRecvCancel: result = ltpResendRecvCancel(event.refNbr1, event.refNbr2); break; /* Out of switch. */ default: /* Spurious event. */ result = 0; /* Event is ignored. */ } if (result < 0) /* Dispatching failed. */ { sdr_cancel_xn(sdr); putErrmsg("failed handing LTP event", NULL); return result; } if (sdr_end_xn(sdr) < 0) { putErrmsg("failed dispatching LTP event", NULL); return -1; } } }
static int dispatchEvents(Sdr sdr, Object events, time_t currentTime) { Object elt; Object eventObj; OBJ_POINTER(BpEvent, event); int result; while (1) { sdr_begin_xn(sdr); CHKERR(ionLocked()); /* In case of killm. */ elt = sdr_list_first(sdr, events); if (elt == 0) /* No more events to dispatch. */ { sdr_exit_xn(sdr); return 0; } eventObj = sdr_list_data(sdr, elt); GET_OBJ_POINTER(sdr, BpEvent, event, eventObj); if (event->time > currentTime) { /* This is the first future event. */ sdr_exit_xn(sdr); return 0; } switch (event->type) { case expiredTTL: result = bpDestroyBundle(event->ref, 1); /* Note that bpDestroyBundle() always * erases the bundle's timeline event, * so we must NOT do so here. */ break; /* Out of switch. */ case xmitOverdue: result = bpReforwardBundle(event->ref); /* Note that bpReforwardBundle() always * erases the bundle's xmitOverdue event, * so we must NOT do so here. */ break; /* Out of switch. */ case ctDue: result = bpReforwardBundle(event->ref); /* Note that bpReforwardBundle() always * erases the bundle's ctDue event, so * we must NOT do so here. */ break; /* Out of switch. */ default: /* Spurious event; erase. */ sdr_free(sdr, eventObj); sdr_list_delete(sdr, elt, NULL, NULL); result = 0; /* Event is ignored. */ } if (result != 0) /* Dispatching failed. */ { sdr_cancel_xn(sdr); putErrmsg("Failed handing BP event.", NULL); return result; } if (sdr_end_xn(sdr) < 0) { putErrmsg("Failed dispatching BP event.", NULL); return -1; } } }
int dtn2_addRule(char *nodeNm, char *demux, FwdDirective *directive) { Sdr sdr = getIonsdr(); char nodeName[SDRSTRING_BUFSZ]; Object elt; OBJ_POINTER(Dtn2Plan, plan); Object nextRule; Dtn2Rule ruleBuf; Object addr; CHKERR(nodeNm && demux && directive); if (*demux == '\0') { writeMemo("[?] Zero-length DTN2 rule demux."); return 0; } if (filterNodeName(nodeName, nodeNm) < 0) { return 0; } CHKERR(sdr_begin_xn(sdr)); elt = locatePlan(nodeName, NULL); if (elt == 0) { sdr_exit_xn(sdr); writeMemoNote("[?] No plan defined for this node", nodeNm); return 0; } GET_OBJ_POINTER(sdr, Dtn2Plan, plan, sdr_list_data(sdr, elt)); if (locateRule(plan, demux, &nextRule) != 0) { sdr_exit_xn(sdr); writeMemoNote("[?] Duplicate rule", demux); return 0; } /* All parameters validated, okay to add the rule. */ memset((char *) &ruleBuf, 0, sizeof(Dtn2Rule)); ruleBuf.demux = sdr_string_create(sdr, demux); memcpy((char *) &ruleBuf.directive, (char *) directive, sizeof(FwdDirective)); addr = sdr_malloc(sdr, sizeof(Dtn2Rule)); if (addr) { if (nextRule) { elt = sdr_list_insert_before(sdr, nextRule, addr); } else { elt = sdr_list_insert_last(sdr, plan->rules, addr); } sdr_write(sdr, addr, (char *) &ruleBuf, sizeof(Dtn2Rule)); } if (sdr_end_xn(sdr) < 0) { putErrmsg("Can't add rule.", NULL); return -1; } return 1; }
int bp_send(BpSAP sap, int mode, char *destEid, char *reportToEid, int lifespan, int classOfService, BpCustodySwitch custodySwitch, unsigned char srrFlags, int ackRequested, BpExtendedCOS *ecos, Object adu, Object *bundleObj) { Sdr sdr = getIonsdr(); BpVdb *vdb = getBpVdb(); BpExtendedCOS defaultECOS = { 0, 0, 0 }; int aduOccupancy; MetaEid *sourceMetaEid; Throttle *throttle; CHKERR(bundleObj); *bundleObj = 0; CHKERR(adu); if (ecos == NULL) { ecos = &defaultECOS; } else { if (ecos->ordinal == 255) /* Reserved. */ { ecos->ordinal = 254; } } if (sap) { sourceMetaEid = &(sap->endpointMetaEid); } else { sourceMetaEid = NULL; } /* Admission control (bundle production throttling) * happens here. */ throttle = &(vdb->productionThrottle); sdr_begin_xn(sdr); /* Just to lock memory. */ aduOccupancy = zco_occupancy(sdr, adu); while (aduOccupancy > throttle->capacity) { sdr_exit_xn(sdr); if (mode == BP_NONBLOCKING) { errno = EWOULDBLOCK; return 0; } if (sm_SemTake(throttle->semaphore) < 0) { putErrmsg("Can't take throttle semaphore.", NULL); return -1; } if (sm_SemEnded(throttle->semaphore)) { putErrmsg("Bundle agent has been stopped.", NULL); return -1; } sdr_begin_xn(sdr); } sdr_exit_xn(sdr); /* Release memory. */ /* Now go ahead and send the bundle. */ return bpSend(sourceMetaEid, destEid, reportToEid, lifespan, classOfService, custodySwitch, srrFlags, ackRequested, ecos, adu, bundleObj, 0); }
int bp_receive(BpSAP sap, BpDelivery *dlvBuffer, int timeoutSeconds) { Sdr sdr = getIonsdr(); VEndpoint *vpoint; OBJ_POINTER(Endpoint, endpoint); Object dlvElt; Object bundleAddr; Bundle bundle; TimerParms timerParms; pthread_t timerThread; int result; char *dictionary; CHKERR(sap && dlvBuffer); if (timeoutSeconds < BP_BLOCKING) { putErrmsg("Illegal timeout interval.", itoa(timeoutSeconds)); return -1; } vpoint = sap->vpoint; sdr_begin_xn(sdr); if (vpoint->appPid != sm_TaskIdSelf()) { sdr_exit_xn(sdr); putErrmsg("Can't receive: not owner of endpoint.", itoa(vpoint->appPid)); return -1; } if (sm_SemEnded(vpoint->semaphore)) { sdr_exit_xn(sdr); writeMemo("[?] Endpoint has been stopped."); /* End task, but without error. */ return -1; } /* Get oldest bundle in delivery queue, if any; wait * for one if necessary. */ GET_OBJ_POINTER(sdr, Endpoint, endpoint, sdr_list_data(sdr, vpoint->endpointElt)); dlvElt = sdr_list_first(sdr, endpoint->deliveryQueue); if (dlvElt == 0) { sdr_exit_xn(sdr); if (timeoutSeconds == BP_POLL) { dlvBuffer->result = BpReceptionTimedOut; return 0; } /* Wait for semaphore to be given, either by the * deliverBundle() function or by timer thread. */ if (timeoutSeconds == BP_BLOCKING) { timerParms.interval = -1; } else /* This is a receive() with a deadline. */ { timerParms.interval = timeoutSeconds; timerParms.semaphore = vpoint->semaphore; if (pthread_create(&timerThread, NULL, timerMain, &timerParms) < 0) { putSysErrmsg("Can't enable interval timer", NULL); return -1; } } /* Take endpoint semaphore. */ if (sm_SemTake(vpoint->semaphore) < 0) { putErrmsg("Can't take endpoint semaphore.", NULL); return -1; } if (sm_SemEnded(vpoint->semaphore)) { writeMemo("[i] Endpoint has been stopped."); /* End task, but without error. */ return -1; } /* Have taken the semaphore, one way or another. */ sdr_begin_xn(sdr); dlvElt = sdr_list_first(sdr, endpoint->deliveryQueue); if (dlvElt == 0) /* Still nothing. */ { /* Either sm_SemTake() was interrupted * or else timer thread gave semaphore. */ sdr_exit_xn(sdr); if (timerParms.interval == 0) { /* Timer expired. */ dlvBuffer->result = BpReceptionTimedOut; pthread_join(timerThread, NULL); } else /* Interrupted. */ { dlvBuffer->result = BpReceptionInterrupted; if (timerParms.interval != -1) { pthread_cancel(timerThread); pthread_join(timerThread, NULL); } } return 0; } else /* Bundle was delivered. */ { if (timerParms.interval != -1) { pthread_cancel(timerThread); pthread_join(timerThread, NULL); } } } /* At this point, we have got a dlvElt and are in an SDR * transaction. */ bundleAddr = sdr_list_data(sdr, dlvElt); sdr_stage(sdr, (char *) &bundle, bundleAddr, sizeof(Bundle)); dictionary = retrieveDictionary(&bundle); if (dictionary == (char *) &bundle) { sdr_cancel_xn(sdr); putErrmsg("Can't retrieve dictionary.", NULL); return -1; } /* Now fill in the data indication structure. */ dlvBuffer->result = BpPayloadPresent; if (printEid(&bundle.id.source, dictionary, &dlvBuffer->bundleSourceEid) < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't print source EID.", NULL); return -1; } dlvBuffer->bundleCreationTime.seconds = bundle.id.creationTime.seconds; dlvBuffer->bundleCreationTime.count = bundle.id.creationTime.count; dlvBuffer->adminRecord = bundle.bundleProcFlags & BDL_IS_ADMIN; dlvBuffer->adu = zco_add_reference(sdr, bundle.payload.content); dlvBuffer->ackRequested = bundle.bundleProcFlags & BDL_APP_ACK_REQUEST; /* Now before returning we send delivery status report * if it is requested. */ if (SRR_FLAGS(bundle.bundleProcFlags) & BP_DELIVERED_RPT) { bundle.statusRpt.flags |= BP_DELIVERED_RPT; getCurrentDtnTime(&bundle.statusRpt.deliveryTime); } if (bundle.statusRpt.flags) { result = sendStatusRpt(&bundle, dictionary); if (result < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't send status report.", NULL); return -1; } } /* Finally delete the delivery list element and, if * possible, destroy the bundle itself. */ if (dictionary) { MRELEASE(dictionary); } sdr_list_delete(sdr, dlvElt, (SdrListDeleteFn) NULL, NULL); bundle.dlvQueueElt = 0; sdr_write(sdr, bundleAddr, (char *) &bundle, sizeof(Bundle)); if (bpDestroyBundle(bundleAddr, 0) < 0) { sdr_cancel_xn(sdr); putErrmsg("Can't destroy bundle.", NULL); return -1; } if (sdr_end_xn(sdr) < 0) { putErrmsg("Failure in bundle reception.", NULL); return -1; } return 0; }
int bp_open(char *eidString, BpSAP *bpsapPtr) { Sdr sdr; MetaEid metaEid; VScheme *vscheme; PsmAddress vschemeElt; Sap sap; VEndpoint *vpoint; PsmAddress vpointElt; CHKERR(eidString && *eidString && bpsapPtr); *bpsapPtr = NULL; /* Default, in case of failure. */ sdr = getIonsdr(); sdr_begin_xn(sdr); /* Just to lock memory. */ /* First validate the endpoint ID. */ if (parseEidString(eidString, &metaEid, &vscheme, &vschemeElt) == 0) { sdr_exit_xn(sdr); putErrmsg("Malformed EID.", eidString); return -1; } if (vschemeElt == 0) { sdr_exit_xn(sdr); putErrmsg("Scheme not known.", metaEid.schemeName); restoreEidString(&metaEid); return -1; } findEndpoint(NULL, metaEid.nss, vscheme, &vpoint, &vpointElt); if (vpointElt == 0) { sdr_exit_xn(sdr); putErrmsg("Endpoint not known.", metaEid.nss); restoreEidString(&metaEid); return -1; } /* Endpoint exists; make sure it's not already opened * by some application. */ if (vpoint->appPid > 0) /* Endpoint not closed. */ { if (sm_TaskExists(vpoint->appPid)) { sdr_exit_xn(sdr); if (vpoint->appPid == sm_TaskIdSelf()) { return 0; } restoreEidString(&metaEid); putErrmsg("Endpoint is already open.", itoa(vpoint->appPid)); return -1; } /* Application terminated without closing the * endpoint, so simply close it now. */ vpoint->appPid = -1; } /* Construct the service access point. */ sap.vpoint = vpoint; memcpy(&sap.endpointMetaEid, &metaEid, sizeof(MetaEid)); sap.endpointMetaEid.colon = NULL; sap.endpointMetaEid.schemeName = MTAKE(metaEid.schemeNameLength + 1); if (sap.endpointMetaEid.schemeName == NULL) { sdr_exit_xn(sdr); putErrmsg("Can't create BpSAP.", NULL); restoreEidString(&metaEid); return -1; } sap.endpointMetaEid.nss = MTAKE(metaEid.nssLength + 1); if (sap.endpointMetaEid.nss == NULL) { sdr_exit_xn(sdr); MRELEASE(sap.endpointMetaEid.schemeName); putErrmsg("Can't create BpSAP.", NULL); restoreEidString(&metaEid); return -1; } *bpsapPtr = MTAKE(sizeof(Sap)); if (*bpsapPtr == NULL) { sdr_exit_xn(sdr); MRELEASE(sap.endpointMetaEid.nss); MRELEASE(sap.endpointMetaEid.schemeName); putErrmsg("Can't create BpSAP.", NULL); restoreEidString(&metaEid); return -1; } istrcpy(sap.endpointMetaEid.schemeName, metaEid.schemeName, sizeof sap.endpointMetaEid.schemeName); istrcpy(sap.endpointMetaEid.nss, metaEid.nss, sizeof sap.endpointMetaEid.nss); restoreEidString(&metaEid); sap.recvSemaphore = vpoint->semaphore; memcpy((char *) *bpsapPtr, (char *) &sap, sizeof(Sap)); /* Having created the SAP, give its owner exclusive * access to the endpoint. */ vpoint->appPid = sm_TaskIdSelf(); sdr_exit_xn(sdr); /* Unlock memory. */ return 0; }
int ionAttach() { Sdr ionsdr = _ionsdr(NULL); Object iondbObject = _iondbObject(NULL); PsmPartition ionwm = _ionwm(NULL); IonVdb *ionvdb = _ionvdb(NULL); char *wdname; char wdnamebuf[256]; IonParms parms; sm_WmParms ionwmParms; char *ionvdbName = _ionvdbName(); if (ionsdr && iondbObject && ionwm && ionvdb) { return 0; /* Already attached. */ } if (sdr_initialize(0, NULL, SM_NO_KEY, NULL) < 0) { putErrmsg("Can't initialize the SDR system.", NULL); return -1; } wdname = getenv("ION_NODE_WDNAME"); if (wdname == NULL) { if (igetcwd(wdnamebuf, 256) == NULL) { putErrmsg("Can't get cwd name.", NULL); return -1; } wdname = wdnamebuf; } memset((char *) &parms, 0, sizeof parms); if (checkNodeListParms(&parms, wdname, 0) < 0) { putErrmsg("Failed checking node list parms.", NULL); return -1; } if (ionsdr == NULL) { ionsdr = sdr_start_using(parms.sdrName); if (ionsdr == NULL) { putErrmsg("Can't start using SDR for ION.", NULL); return -1; } oK(_ionsdr(&ionsdr)); } if (iondbObject == 0) { sdr_begin_xn(ionsdr); /* Lock database. */ iondbObject = sdr_find(ionsdr, _iondbName(), NULL); sdr_exit_xn(ionsdr); /* Unlock database. */ if (iondbObject == 0) { putErrmsg("ION database not found.", NULL); return -1; } oK(_iondbObject(&iondbObject)); } oK(_ionConstants()); /* Open ION shared-memory partition. */ if (ionwm == NULL) { ionwmParms.wmKey = parms.wmKey; ionwmParms.wmSize = 0; ionwmParms.wmAddress = NULL; ionwmParms.wmName = ION_SM_NAME; ionwm = _ionwm(&ionwmParms); if (ionwm == NULL) { putErrmsg("Can't open access to ION memory.", NULL); return -1; } } if (ionvdb == NULL) { if (_ionvdb(&ionvdbName) == NULL) { putErrmsg("ION volatile database not found.", NULL); return -1; } } ionRedirectMemos(); return 0; }
int ionInitialize(IonParms *parms, unsigned long ownNodeNbr) { char wdname[256]; Sdr ionsdr; Object iondbObject; IonDB iondbBuf; sm_WmParms ionwmParms; char *ionvdbName = _ionvdbName(); CHKERR(parms); CHKERR(ownNodeNbr); if (sdr_initialize(0, NULL, SM_NO_KEY, NULL) < 0) { putErrmsg("Can't initialize the SDR system.", NULL); return -1; } if (igetcwd(wdname, 256) == NULL) { putErrmsg("Can't get cwd name.", NULL); return -1; } if (checkNodeListParms(parms, wdname, ownNodeNbr) < 0) { putErrmsg("Failed checking node list parms.", NULL); return -1; } if (sdr_load_profile(parms->sdrName, parms->configFlags, parms->heapWords, parms->heapKey, parms->pathName) < 0) { putErrmsg("Unable to load SDR profile for ION.", NULL); return -1; } ionsdr = sdr_start_using(parms->sdrName); if (ionsdr == NULL) { putErrmsg("Can't start using SDR for ION.", NULL); return -1; } ionsdr = _ionsdr(&ionsdr); /* Recover the ION database, creating it if necessary. */ sdr_begin_xn(ionsdr); iondbObject = sdr_find(ionsdr, _iondbName(), NULL); switch (iondbObject) { case -1: /* SDR error. */ sdr_cancel_xn(ionsdr); putErrmsg("Can't seek ION database in SDR.", NULL); return -1; case 0: /* Not found; must create new DB. */ if (ownNodeNbr == 0) { sdr_cancel_xn(ionsdr); putErrmsg("Must supply non-zero node number.", NULL); return -1; } memset((char *) &iondbBuf, 0, sizeof(IonDB)); memcpy(iondbBuf.workingDirectoryName, wdname, 256); iondbBuf.ownNodeNbr = ownNodeNbr; iondbBuf.occupancyCeiling = ((sdr_heap_size(ionsdr) / 100) * (100 - ION_SEQUESTERED)); iondbBuf.receptionSpikeReserve = iondbBuf.occupancyCeiling / 16; if (iondbBuf.receptionSpikeReserve < MIN_SPIKE_RSRV) { iondbBuf.receptionSpikeReserve = MIN_SPIKE_RSRV; } iondbBuf.contacts = sdr_list_create(ionsdr); iondbBuf.ranges = sdr_list_create(ionsdr); iondbBuf.maxClockError = 0; iondbObject = sdr_malloc(ionsdr, sizeof(IonDB)); if (iondbObject == 0) { sdr_cancel_xn(ionsdr); putErrmsg("No space for database.", NULL); return -1; } sdr_write(ionsdr, iondbObject, (char *) &iondbBuf, sizeof(IonDB)); sdr_catlg(ionsdr, _iondbName(), 0, iondbObject); if (sdr_end_xn(ionsdr)) { putErrmsg("Can't create ION database.", NULL); return -1; } break; default: /* Found DB in the SDR. */ sdr_exit_xn(ionsdr); } oK(_iondbObject(&iondbObject)); oK(_ionConstants()); /* Open ION shared-memory partition. */ ionwmParms.wmKey = parms->wmKey; ionwmParms.wmSize = parms->wmSize; ionwmParms.wmAddress = parms->wmAddress; ionwmParms.wmName = ION_SM_NAME; if (_ionwm(&ionwmParms) == NULL) { putErrmsg("ION memory configuration failed.", NULL); return -1; } if (_ionvdb(&ionvdbName) == NULL) { putErrmsg("ION can't initialize vdb.", NULL); return -1; } ionRedirectMemos(); return 0; }
static IonVdb *_ionvdb(char **name) { static IonVdb *vdb = NULL; PsmAddress vdbAddress; PsmAddress elt; Sdr sdr; PsmPartition ionwm; if (name) { if (*name == NULL) /* Terminating. */ { vdb = NULL; return vdb; } /* Attaching to volatile database. */ ionwm = _ionwm(NULL); if (psm_locate(ionwm, *name, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", NULL); return vdb; } if (elt) { vdb = (IonVdb *) psp(ionwm, vdbAddress); return vdb; } /* ION volatile database doesn't exist yet. */ sdr = _ionsdr(NULL); sdr_begin_xn(sdr); /* Just to lock memory. */ vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb)); if (vdbAddress == 0) { sdr_exit_xn(sdr); putErrmsg("No space for volatile database.", NULL); return NULL; } vdb = (IonVdb *) psp(ionwm, vdbAddress); memset((char *) vdb, 0, sizeof(IonVdb)); if ((vdb->nodes = sm_list_create(ionwm)) == 0 || (vdb->neighbors = sm_list_create(ionwm)) == 0 || (vdb->probes = sm_list_create(ionwm)) == 0 || psm_catlg(ionwm, *name, vdbAddress) < 0) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", NULL); return NULL; } vdb->deltaFromUTC = (_ionConstants())->deltaFromUTC; sdr_exit_xn(sdr); /* Unlock memory. */ } return vdb; }