1 #include <frm_generic.h>
4 #include <fres_sa_scenario.h>
7 UL_LOG_CUST(ulogd_frm);
8 ul_log_domain_t ulogd_frm = {UL_LOGL_MSG, "frm"};
11 struct fres_sa_scenario *reserved;
12 frm_adm_test_fnc_t admission_test;
16 #define object_to_frm(o) (struct frm_data*)forb_instance_data(o)
17 #define save_errno(cmd) do { int _e = errno; cmd; errno = _e; } while(0)
19 static CORBA_long reserve_contracts(fres_resource_manager obj,
20 const fres_contract_ptr_seq* contracts,
21 CORBA_Environment *ev)
23 struct frm_data *frm = object_to_frm(obj);
24 struct fres_sa_scenario *prospective;
28 ul_logmsg("reserve_contracts\n");
30 prospective = fres_sa_scenario_duplicate(frm->reserved);
31 if (!prospective) goto err;
32 for (i=0; i<contracts->_length; i++) {
33 struct fres_sa_contract *c;
34 c = fres_sa_contract_new();
36 c->status = FRES_SA_CONTRACT_NEW;
37 c->contract = fres_contract_duplicate(contracts->_buffer[i]);
38 if (!c->contract) goto err;
39 fres_sa_scenario_add_contract(prospective, c);
42 ret = frm->admission_test(prospective, frm->priv, &schedulable);
44 ul_logerr("admission_test failed: %d\n", ret);
49 struct fres_sa_contract *c;
50 fres_sa_scenario_for_each_contract(prospective, c) {
51 if (c->status == FRES_SA_CONTRACT_NEW) {
52 c->status = FRES_SA_CONTRACT_RESERVED;
55 fres_sa_scenario_destroy(frm->reserved);
56 frm->reserved = prospective;
58 fres_sa_scenario_destroy(prospective);
60 return schedulable ? 0 : 1;
62 fres_sa_scenario_destroy(prospective);
66 static void commit_contracts(fres_resource_manager obj,
67 const fres_contract_id_seq* ids,
68 fres_contract_ptr_seq** contracts_with_scheduling_data,
69 CORBA_Environment *ev)
71 struct frm_data *frm = object_to_frm(obj);
73 struct fres_sa_contract *c;
74 fres_contract_ptr_seq *contracts;
76 ul_logmsg("commit_contracts\n");
78 contracts = forb_malloc(sizeof(*contracts));
80 ev->major = FORB_EX_NO_MEMORY;
84 contracts->_buffer = CORBA_sequence_fres_contract_ptr_allocbuf(num);
85 CORBA_sequence_set_release(contracts, CORBA_TRUE);
86 contracts->_maximum = contracts->_length = num;
88 for (i=0; i < num; i++) {
89 c = fres_sa_scenario_find_contract(frm->reserved, &ids->_buffer[i]);
90 c->status = FRES_SA_CONTRACT_COMMITED;
91 contracts->_buffer[i] = c->contract;
94 *contracts_with_scheduling_data = contracts;
98 static void cancel_contracts(fres_resource_manager obj,
99 const fres_contract_id_seq* ids,
100 CORBA_Environment *ev)
103 struct frm_data *frm = object_to_frm(obj);
105 ul_logmsg("cancel_contracts\n");
107 for (i=0; i<ids->_length; i++) {
108 struct fres_sa_contract *c;
109 c = fres_sa_scenario_find_contract(frm->reserved, &ids->_buffer[i]);
112 fres_sa_scenario_del_contract(frm->reserved, c);
118 static const struct forb_fres_resource_manager_impl frm_impl = {
119 .reserve_contracts = reserve_contracts,
120 .commit_contracts = commit_contracts,
121 .cancel_contracts = cancel_contracts,
125 * Initializes and runs a generic resource manager. The only thing a
126 * caller has to supply is admission test function, which is passed in
127 * @a frm_data->admission_test.
129 * @param orb FORB object used to communicate with other components.
130 * @param admission_test Admission test function.
131 * @param priv Pointer to passed as priv parameter to frm_adm_test_fnc_t.
135 int frm_register_and_run(forb_orb orb, const struct fres_res_manager *res_manager)
137 fres_contract_broker fcb;
138 fres_resource_manager frm;
140 struct frm_data frm_data;
141 forb_executor_t executor;
144 memset(&frm_data, 0, sizeof(frm_data));
145 frm_data.admission_test = res_manager->admission_test;
146 frm_data.priv = res_manager->priv;
147 frm_data.reserved = fres_sa_scenario_new();
148 if (!frm_data.reserved) {
149 save_errno(ul_logerr("fres_sa_scenario_new failed\n"));
153 fcb = forb_resolve_reference(orb, fres_contract_broker_reg_name);
155 save_errno(ul_logerr("Could not find contract broker"));
159 frm = forb_fres_resource_manager_new(orb, &frm_impl, &frm_data);
161 save_errno(ul_logerr("forb_fres_resource_manager_new error"));
162 goto err_release_fcb;
165 /* Prepare executor before we register the resource manager
166 * with contract broker */
167 ret = forb_executor_init(&executor);
169 save_errno(ul_logerr("forb_executor_init failed"));
170 goto err_release_frm;
173 ret = forb_executor_register_object(&executor, frm);
175 save_errno(ul_logerr("forb_executor_register_object failed"));
179 /* Register resource manager */
180 ret = fres_contract_broker_register_manager(fcb,
181 res_manager->res_type,
184 if (forb_exception_occured(&env) || ret != 0) {
185 save_errno(ul_logerr("fres_contract_broker_register_manager exception\n"));
189 /* Start request processing */
190 ul_logmsg("Waiting for requests\n");
191 ret = forb_executor_run(&executor);
192 if (ret) goto err_executor;
196 forb_executor_destroy(&executor);
198 forb_object_release(frm);
200 forb_object_release(fcb);