X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/frsh.git/blobdiff_plain/9456992d630b02e0852e728f24eba1d9baa34884..28701c2f9105e32ee3a1cf43eb6f7090f7f7cf78:/fres/cbroker/fcb.c diff --git a/fres/cbroker/fcb.c b/fres/cbroker/fcb.c index 7f74dab..4aa3ec0 100644 --- a/fres/cbroker/fcb.c +++ b/fres/cbroker/fcb.c @@ -286,28 +286,24 @@ get_res_key(const struct fres_contract *contract, struct res_key *key) /** * Fills in an array of fcb_contracts according to requests submited - * to negotiate_contracts(). For every contract in @a contracts, there - * is one fcb_contract in @a fcb_contracts array. + * by an application through negotiate_contracts() or + * negotiate_transaction(). For every contract in @a contracts, there + * is allocated one fcb_contract in @a fcb_contracts array. * * @param fcb * @param fcb_contracts Where to store pointers to fcb_contracts - * @param resource Resource for which negotiation is being done. - * @param app Application which requests negotiation - * @param contracts Contracts submited to negotiate_contracts() + * @param contracts Contracts submited for negotiation * @param num Number of contracts in contracts (which is the same as the number in fcb_contracts). * * @return Zero on success, non-zero error code on error. */ static int prepare_fcb_contracts(struct fcb *fcb, struct fcb_contract *fcb_contracts[], - struct resource **resource, - forb_server_id *app, struct fres_contract *contracts[], int num) { unsigned i; struct fcb_contract *fc; - struct res_alloc *ra; - struct res_key key, key2 = {-1,-1}; + struct res_key key; for (i=0; irequested_contract = c; + } + return 0; +} + +/** + * Ensure that all contracts belong to the same resource and find + * resource allocators for the contracts. + * + * @param fcb + * @param fcb_contracts Array of fcb_contracts prepared by prepare_fcb_contracts() + * @param num Number of contracts in @a fcb_contracts + * @param resource Resource for which negotiation is being done. + * @param app Application which requests negotiation + */ +static int +check_and_setup_resource(struct fcb *fcb, struct fcb_contract *fcb_contracts[], + struct resource **resource, + forb_server_id *app, + int num) +{ + unsigned i; + struct res_alloc *ra; + struct res_key key, key2 = {-1,-1}; + + for (i=0; irequested_contract; + if (fres_contract_get_num_blocks(c) == 0) { + /* Cancelation */ + get_res_key(fc->user_contract, &key); + log_contract("Cancelation request", i, fc->user_contract); + } else { + /* (Re)Negotiation */ + if (!get_res_key(c, &key)) { + return FRSH_ERR_RESOURCE_ID_INVALID; + } + } /* Check that all contracts are for the same resource */ if (i==0) { key2 = key; @@ -356,22 +389,21 @@ prepare_fcb_contracts(struct fcb *fcb, struct fcb_contract *fcb_contracts[], key.type, key.id); return FRES_ERR_NO_RESOURCE_MANAGER; } + /* Find allocator for this request */ + ra = fcb_alloc_find(*resource, app); + if (!ra) { + char str[60]; + forb_server_id_to_string(str, app, sizeof(str)); + ul_logerr("No resource allocator found for %d.%d and %s\n", + (*resource)->key.type, (*resource)->key.id, str); + return FRES_ERR_NO_RESOURCE_ALLOCATOR; + } } else if (key.type != key2.type || key.id != key2.id) { ul_logerr("Contract #%d differs in resource!\n", i); return FRSH_ERR_RESOURCE_ID_INVALID; } - - /* Find allocator for this request */ - ra = fcb_alloc_find(*resource, app); - if (!ra) { - char str[60]; - forb_server_id_to_string(str, app, sizeof(str)); - ul_logerr("No resource allocator found for %d.%d and %s\n", - (*resource)->key.type, (*resource)->key.id, str); - return FRES_ERR_NO_RESOURCE_ALLOCATOR; - } fc->ra = ra; } return 0; @@ -591,6 +623,21 @@ err: return ret; } +void +free_fcb_contracts(struct fcb_contract *fcb_contracts[], int num) +{ + int i; + struct fcb_contract *fc; + for (i=0; iuser_contract) { + fc->requested_contract = NULL; /* Destroyed by FORB */ + fcb_contract_destroy(fc); + } + } + free(fcb_contracts); +} + CORBA_long negotiate_contracts(fres_contract_broker obj, const fres_contract_ptr_seq* contracts, @@ -605,6 +652,7 @@ negotiate_contracts(fres_contract_broker obj, struct fcb_contract **fcb_contracts, *fc; unsigned i; fres_contract_id_seq commit_ids; + int num = contracts->_length; /* Prepare output sequence for the case we return eariler with * an error */ @@ -617,25 +665,29 @@ negotiate_contracts(fres_contract_broker obj, forb_get_req_source(obj, &app); - fcb_contracts = malloc(sizeof(fcb_contracts[0])*contracts->_length); + fcb_contracts = malloc(sizeof(fcb_contracts[0])*num); if (!fcb_contracts) { ret = errno; goto err; } - memset(fcb_contracts, 0, sizeof(fcb_contracts[0])*contracts->_length); + memset(fcb_contracts, 0, sizeof(fcb_contracts[0])*num); - ret = prepare_fcb_contracts(fcb, fcb_contracts, &resource, - &app, contracts->_buffer, contracts->_length); + ret = prepare_fcb_contracts(fcb, fcb_contracts, + contracts->_buffer, num); + if (ret) + goto err_free_fcb_contracts; + ret = check_and_setup_resource(fcb, fcb_contracts, &resource, + &app, num); if (ret) goto err_free_fcb_contracts; struct reservation_list rl; prepare_reservation_list(resource, - fcb_contracts, contracts->_length, + fcb_contracts, num, &rl); /* Allocate all the needed memory before doing reservation. If - * there is no enough memory, it has no sense to call resource + * there is not enough memory, it has no sense to call resource * manager. */ if (!forb_sequence_alloc_buf(&commit_ids, rl.length)) { ret = errno; @@ -672,7 +724,7 @@ negotiate_contracts(fres_contract_broker obj, /* Add new contracts to our fcb database for later * reference. Canceled contracts are removed below. */ - for (i=0; i_length; i++) { + for (i=0; iuser_contract) { @@ -706,12 +758,12 @@ negotiate_contracts(fres_contract_broker obj, /* Return IDs and delete canceled contracts from out database */ - if (!forb_sequence_alloc_buf(*ids_out, contracts->_length)) { + if (!forb_sequence_alloc_buf(*ids_out, num)) { ev->major = FORB_EX_NO_MEMORY; goto err_cancel_contracts; } - (*ids_out)->_length = contracts->_length; - for (i=0; i_length; i++) { + (*ids_out)->_length = num; + for (i=0; iid; @@ -732,14 +784,7 @@ err_cancel_contracts: err_cancel_reservation: fres_resource_manager_cancel_reservations(resource->mng, &commit_ids, ev); err_free_fcb_contracts: - for (i=0; i_length; i++) { - fc = fcb_contracts[i]; - if (fc && !fc->user_contract) { - fcb_contracts[i]->requested_contract = NULL; /* Destroyed by FORB */ - fcb_contract_destroy(fcb_contracts[i]); - } - } - free(fcb_contracts); + free_fcb_contracts(fcb_contracts, num); err: return ret; } @@ -908,12 +953,35 @@ negotiate_transaction(fres_contract_broker _obj, const fres_transaction_t* transaction, CORBA_Environment *ev) { + struct fcb *fcb = o2fcb(_obj); + struct fcb_contract **fcb_contracts; + const fres_contract_ptr_seq* contracts = &transaction->contracts; + int num = contracts->_length; + int ret; + + fcb_contracts = malloc(sizeof(*fcb_contracts)*num); + if (!fcb_contracts) { + ret = errno; + goto err; + } + memset(fcb_contracts, 0, sizeof(*fcb_contracts)*num); + + ret = prepare_fcb_contracts(fcb, fcb_contracts, + contracts->_buffer, num); + if (ret) + goto err_free_fcb_contracts; + return FRSH_ERR_NOT_IMPLEMENTED; +err_free_fcb_contracts: + free_fcb_contracts(fcb_contracts, num); +err: + return ret; } CORBA_long wait_transaction(fres_contract_broker _obj, const CORBA_char * name, + fres_transaction_t** transaction, CORBA_Environment *ev) { return FRSH_ERR_NOT_IMPLEMENTED;