Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'hypervisor' of scm.gforge.inria.fr:/gitroot/simgrid/simgrid into hypervisor
[simgrid.git] / src / simix / smx_vm.c
1 /* Copyright (c) 2007-2012. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "smx_private.h"
8 #include "xbt/sysdep.h"
9 #include "xbt/log.h"
10 #include "xbt/dict.h"
11 #include "mc/mc.h"
12
13 //If you need to log some stuffs, just uncomment these two lines and uses XBT_DEBUG for instance
14 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_vm, simix, "Logging specific to SIMIX (vms)");
15
16 /* **** create a VM **** */
17
18 /**
19  * \brief Internal function to create a SIMIX host.
20  * \param name name of the host to create
21  * \param data some user data (may be NULL)
22  */
23 smx_host_t SIMIX_vm_create(const char *name, smx_host_t ind_phys_host)
24 {
25
26   smx_host_priv_t smx_host = xbt_new0(s_smx_host_priv_t, 1);
27   s_smx_process_t proc;
28
29   // TODO check why we do not have any VM here and why we have the host_proc_hookup  ?
30
31   /* Host structure */
32   smx_host->data = NULL;
33   smx_host->process_list =
34       xbt_swag_new(xbt_swag_offset(proc, host_proc_hookup));
35
36   /* Update global variables */
37   xbt_lib_set(host_lib,name,SIMIX_HOST_LEVEL,smx_host);
38
39   /* Create surf associated resource */
40   // TODO change phys_host into the right workstation surf model
41   surf_vm_workstation_model->extension.vm_workstation.create(name, ind_phys_host);
42
43   return xbt_lib_get_elm_or_null(host_lib, name);
44 }
45
46
47 smx_host_t SIMIX_pre_vm_create(smx_simcall_t simcall, const char *name, smx_host_t ind_phys_host){
48   return SIMIX_vm_create(name, ind_phys_host);
49 }
50
51
52 static int get_host_property_as_integer(smx_host_t host, const char *name)
53 {
54   xbt_dict_t dict = simix_host_get_properties(host);
55
56   char *value = xbt_dict_get_or_null(dict, name);
57   return atoi(value);
58 }
59
60
61
62 /* **** start a VM **** */
63 static int __can_be_started(smx_host_t vm)
64 {
65         // TODO add checking code related to overcommitment or not.
66
67   int overcommit = get_host_property_as_integer("OverCommit");
68   int core_nb = get_host_property_as_integer("CORE_NB");
69   int mem_cap = get_host_property_as_integer("MEM_CAP");
70   int net_cap = get_host_property_as_integer("NET_CAP");
71
72   /* we need to get other VM objects on this physical host. */
73
74
75
76         return 1;
77 }
78
79 void SIMIX_vm_start(smx_host_t ind_vm)
80 {
81   //TODO only start the VM if you can
82   if (__can_be_started(ind_vm))
83     SIMIX_vm_set_state(ind_vm, msg_vm_state_running);
84   else
85     THROWF(vm_error, 0, "The VM %s cannot be started", SIMIX_host_get_name(ind_vm));
86 }
87
88 void SIMIX_pre_vm_start(smx_simcall_t simcall, smx_host_t ind_vm)
89 {
90   SIMIX_vm_start(ind_vm);
91 }
92
93 /* ***** set/get state of a VM ***** */
94 void SIMIX_vm_set_state(smx_host_t ind_vm, int state)
95 {
96   surf_vm_workstation_model->extension.vm_workstation.set_state(ind_vm, state);
97 }
98
99 void SIMIX_pre_vm_set_state(smx_host_t ind_vm, int state)
100 {
101   SIMIX_vm_set_state(ind_vm, state);
102 }
103
104 int SIMIX_vm_get_state(smx_host_t ind_vm)
105 {
106   return surf_vm_workstation_model->extension.vm_workstation.get_state(ind_vm);
107 }
108
109 int SIMIX_pre_vm_get_state(smx_host_t ind_vm)
110 {
111   return SIMIX_vm_get_state(ind_vm);
112 }
113
114
115 /**
116  * \brief Function to migrate a SIMIX VM host. 
117  *
118  * \param host the vm host to migrate (a smx_host_t)
119  */
120 void SIMIX_vm_migrate(smx_host_t ind_vm, smx_host_t ind_dst_pm)
121 {
122   /* TODO: check state */
123
124   /* TODO: Using the variable of the MSG layer is not clean. */
125   SIMIX_vm_set_state(ind_vm, msg_vm_state_migrating);
126
127   /* jump to vm_ws_migrate(). this will update the vm location. */
128   surf_vm_workstation_model->extension.vm_workstation.migrate(ind_vm, ind_dst_pm);
129
130   SIMIX_vm_set_state(ind_vm, msg_vm_state_running);
131 }
132
133 void SIMIX_pre_vm_migrate(smx_simcall_t simcall, smx_host_t ind_vm, smx_host_t ind_dst_pm){
134    SIMIX_vm_migrate(ind_vm, ind_dst_pm);
135 }
136
137
138 /**
139  * \brief Function to get the physical host of the given the SIMIX VM host.
140  *
141  * \param host the vm host to get_phys_host (a smx_host_t)
142  */
143 const char *SIMIX_vm_get_phys_host(smx_host_t ind_vm)
144 {
145   /* jump to vm_ws_get_phys_host(). this will return the vm name. */
146   return surf_vm_workstation_model->extension.vm_workstation.get_phys_host(ind_vm);
147 }
148
149 const char *SIMIX_pre_vm_get_phys_host(smx_simcall_t simcall, smx_host_t ind_vm){
150   return SIMIX_vm_get_phys_host(ind_vm);
151 }
152
153
154 /**
155  * \brief Function to suspend a SIMIX VM host. This function stops the exection of the
156  * VM. All the processes on this VM will pause. The state of the VM is
157  * preserved on memory. We can later resume it again.
158  *
159  * \param host the vm host to suspend (a smx_host_t)
160  */
161 void SIMIX_vm_suspend(smx_host_t ind_vm)
162 {
163   /* TODO: check state */
164
165   XBT_DEBUG("%lu processes in the VM", xbt_swag_size(SIMIX_host_priv(ind_vm)->process_list));
166
167   smx_process_t smx_process, smx_process_safe;
168   xbt_swag_foreach_safe(smx_process, smx_process_safe, SIMIX_host_priv(ind_vm)->process_list) {
169          XBT_DEBUG("suspend %s", SIMIX_host_get_name(ind_vm));
170          /* FIXME: calling a simcall from the SIMIX layer is strange. */
171          simcall_process_suspend(smx_process);
172   }
173
174   /* TODO: Using the variable of the MSG layer is not clean. */
175   SIMIX_vm_set_state(ind_vm, msg_vm_state_suspended);
176 }
177
178 void SIMIX_pre_vm_suspend(smx_simcall_t simcall, smx_host_t ind_vm){
179    SIMIX_vm_suspend(ind_vm);
180 }
181
182
183 /**
184  * \brief Function to resume a SIMIX VM host. This function restart the execution of the
185  * VM. All the processes on this VM will run again. 
186  *
187  * \param host the vm host to resume (a smx_host_t)
188  */
189 void SIMIX_vm_resume(smx_host_t ind_vm)
190 {
191   /* TODO: check state */
192
193   XBT_DEBUG("%lu processes in the VM", xbt_swag_size(SIMIX_host_priv(ind_vm)->process_list));
194
195   smx_process_t smx_process, smx_process_safe;
196   xbt_swag_foreach_safe(smx_process, smx_process_safe, SIMIX_host_priv(ind_vm)->process_list) {
197          XBT_DEBUG("resume %s", SIMIX_host_get_name(ind_vm));
198          /* FIXME: calling a simcall from the SIMIX layer is strange. */
199          simcall_process_resume(smx_process);
200   }
201
202   /* TODO: Using the variable of the MSG layer is not clean. */
203   SIMIX_vm_set_state(ind_vm, msg_vm_state_running);
204 }
205
206 void SIMIX_pre_vm_resume(smx_simcall_t simcall, smx_host_t ind_vm){
207    SIMIX_vm_resume(ind_vm);
208 }
209
210
211 /**
212  * \brief Function to save a SIMIX VM host.
213  * This function is the same as vm_suspend, but the state of the VM is saved to the disk, and not preserved on memory.
214  * We can later restore it again.
215  *
216  * \param host the vm host to save (a smx_host_t)
217  */
218 void SIMIX_vm_save(smx_host_t ind_vm)
219 {
220   /* TODO: check state */
221
222   XBT_DEBUG("%lu processes in the VM", xbt_swag_size(SIMIX_host_priv(ind_vm)->process_list));
223
224   /* TODO: do something at the surf level */
225
226   smx_process_t smx_process, smx_process_safe;
227   xbt_swag_foreach_safe(smx_process, smx_process_safe, SIMIX_host_priv(ind_vm)->process_list) {
228          XBT_DEBUG("save %s", SIMIX_host_get_name(ind_vm));
229          /* FIXME: calling a simcall from the SIMIX layer is strange. */
230          simcall_process_save(smx_process);
231   }
232
233   /* TODO: Using the variable of the MSG layer is not clean. */
234   SIMIX_vm_set_state(ind_vm, msg_vm_state_saved);
235 }
236
237 void SIMIX_pre_vm_save(smx_simcall_t simcall, smx_host_t ind_vm){
238   SIMIX_vm_save(ind_vm);
239 }
240
241
242 /**
243  * \brief Function to restore a SIMIX VM host. This function restart the execution of the
244  * VM. All the processes on this VM will run again. 
245  *
246  * \param host the vm host to restore (a smx_host_t)
247  */
248 void SIMIX_vm_restore(smx_host_t ind_vm)
249 {
250   /* TODO: check state */
251
252   XBT_DEBUG("%lu processes in the VM", xbt_swag_size(SIMIX_host_priv(ind_vm)->process_list));
253
254   /* TODO: do something at the surf level */
255
256   smx_process_t smx_process, smx_process_safe;
257   xbt_swag_foreach_safe(smx_process, smx_process_safe, SIMIX_host_priv(ind_vm)->process_list) {
258          XBT_DEBUG("restore %s", SIMIX_host_get_name(ind_vm));
259          /* FIXME: calling a simcall from the SIMIX layer is strange. */
260          simcall_process_restore(smx_process);
261   }
262
263   /* TODO: Using the variable of the MSG layer is not clean. */
264   SIMIX_vm_set_state(ind_vm, msg_vm_state_running);
265 }
266
267 void SIMIX_pre_vm_restore(smx_simcall_t simcall, smx_host_t ind_vm){
268   SIMIX_vm_restore(ind_vm);
269 }
270
271
272 /**
273  * \brief Function to shutdown a SIMIX VM host. This function powers off the
274  * VM. All the processes on this VM will be killed. But, the state of the VM is
275  * preserved on memory. We can later start it again.
276  *
277  * \param host the vm host to shutdown (a smx_host_t)
278  */
279 void SIMIX_vm_shutdown(smx_host_t ind_vm, smx_process_t issuer)
280 {
281   /* TODO: check state */
282
283   XBT_DEBUG("%lu processes in the VM", xbt_swag_size(SIMIX_host_priv(ind_vm)->process_list));
284
285   smx_process_t smx_process, smx_process_safe;
286   xbt_swag_foreach_safe(smx_process, smx_process_safe, SIMIX_host_priv(ind_vm)->process_list) {
287          XBT_DEBUG("kill %s", SIMIX_host_get_name(ind_vm));
288
289          SIMIX_process_kill(smx_process, issuer);
290   }
291
292   /* TODO: Using the variable of the MSG layer is not clean. */
293   SIMIX_vm_set_state(ind_vm, msg_vm_state_sleeping);
294 }
295
296 void SIMIX_pre_vm_shutdown(smx_simcall_t simcall, smx_host_t ind_vm){
297    SIMIX_vm_shutdown(ind_vm, simcall->issuer);
298 }
299
300
301 /**
302  * \brief Function to destroy a SIMIX VM host.
303  *
304  * \param host the vm host to destroy (a smx_host_t)
305  */
306 void SIMIX_vm_destroy(smx_host_t ind_vm)
307 {
308   /* this code basically performs a similar thing like SIMIX_host_destroy() */
309
310   xbt_assert((ind_vm != NULL), "Invalid parameters");
311   const char *hostname = SIMIX_host_get_name(ind_vm);
312
313   smx_host_priv_t host_priv = SIMIX_host_priv(ind_vm);
314
315   /* this will call the registered callback function, i.e., SIMIX_host_destroy().  */
316   xbt_lib_unset(host_lib, hostname, SIMIX_HOST_LEVEL);
317
318   /* jump to vm_ws_destroy(). The surf level resource will be freed. */
319   surf_vm_workstation_model->extension.vm_workstation.destroy(ind_vm);
320 }
321
322 void SIMIX_pre_vm_destroy(smx_simcall_t simcall, smx_host_t ind_vm){
323    SIMIX_vm_destroy(ind_vm);
324 }