[REFACTOR] encapsulate target struct (part 1)
[platform/core/system/swap-manager.git] / daemon / da_inst.c
1 /*
2  *  DA manager
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Cherepanov Vitaliy <v.cherepanov@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  * Contributors:
23  * - Samsung RnD Institute Russia
24  *
25  */
26
27 // TODO check memory (malloc, free)
28
29 #include <stdint.h>
30 #include <sys/types.h>
31 #include <linux/limits.h>
32
33 #include "da_inst.h"
34 #include "da_protocol.h"
35 #include "da_protocol_inst.h"
36 #include "debug.h"
37 #include "daemon.h"
38
39 struct lib_list_t *new_lib_inst_list = NULL;
40
41 uint32_t app_count = 0;
42 char *packed_app_list = NULL;
43 char *packed_lib_list = NULL;
44
45 static struct _msg_target_t *lib_maps_message = NULL;
46 static pthread_mutex_t lib_inst_list_mutex = PTHREAD_MUTEX_INITIALIZER;
47 static pthread_mutex_t lib_maps_message_mutex = PTHREAD_MUTEX_INITIALIZER;
48
49 uint32_t libs_count;
50
51 //----------------------------------- lists ----------------------------------
52
53 static int data_list_add_probe_to_hash(struct data_list_t *to, struct probe_list_t *probe)
54 {
55         // TODO add hash
56         return 0;
57 }
58
59 // create hash for lib
60 static int data_list_make_hash(struct data_list_t *what)
61 {
62         struct probe_list_t *p;
63
64         for (p = what->list; p != NULL; p = p->next)
65                 data_list_add_probe_to_hash(what, p);
66         return 0;
67 }
68
69 //------------ create - destroy
70 static struct data_list_t *new_data(void)
71 {
72         struct data_list_t *lib = malloc(sizeof(*lib));
73         lib->next = NULL;
74         lib->prev = NULL;
75         lib->hash = 0;
76         lib->size = 0;
77         lib->list = NULL;
78         return lib;
79 }
80
81 struct lib_list_t *new_lib(void)
82 {
83         struct lib_list_t *lib = (struct lib_list_t *)new_data();
84         lib->lib = malloc(sizeof(*lib->lib));
85         memset(lib->lib, 0, sizeof(*lib->lib));
86         return lib;
87 }
88
89 struct app_list_t *new_app(void)
90 {
91         struct app_list_t *app = (struct app_list_t *)new_data();
92         app->app = malloc(sizeof(*app->app));
93         memset(app->app, 0, sizeof(*app->app));
94         return app;
95 }
96
97 struct probe_list_t *new_probe(void)
98 {
99         struct probe_list_t *probe = malloc(sizeof(*probe));
100         probe->next = NULL;
101         probe->prev = NULL;
102         probe->size = 0;
103         probe->func = NULL;
104         return probe;
105 }
106
107 static void free_probe_element(struct probe_list_t *probe)
108 {
109         free(probe->func);
110         free(probe);
111 }
112
113 static void free_data_element(struct data_list_t *lib)
114 {
115         free(lib->data);
116         free(lib);
117 }
118
119 static void free_probe_list(struct probe_list_t *probe)
120 {
121         struct probe_list_t *next;
122         while (probe != NULL) {
123                 next = probe->next;
124                 free_probe_element(probe);
125                 probe = next;
126         }
127 }
128
129 static void free_data(struct data_list_t *lib)
130 {
131         free_probe_list(lib->list);
132         free_data_element(lib);
133 }
134
135 void free_data_list(struct data_list_t **data)
136 {
137         struct data_list_t *next;
138         while (*data != NULL) {
139                 next = (*data)->next;
140                 free_data(*data);
141                 *data = next;
142         }
143 }
144
145 //------------- add - remove
146 int data_list_append(struct data_list_t **to, struct data_list_t *from)
147 {
148         struct data_list_t *p = NULL;
149         if (*to == NULL) {
150                 // empty list
151                 *to = from;
152         } else {
153                 p = *to;
154                 *to = from;
155                 from->next = (void *)p;
156                 p->prev = (void *)from;
157         }
158         return 0;
159 }
160
161
162 static int data_list_append_probes_hash(struct data_list_t *to, struct data_list_t *from)
163 {
164         struct probe_list_t *p = from->list;
165         struct probe_list_t *last = p;
166
167         to->size += p->size;
168         to->func_num += from->func_num;
169         for (p = from->list; p != NULL; p = p->next) {
170                 data_list_add_probe_to_hash(to, p);
171                 last = p;
172         }
173
174         last->next = to->list;
175         to->list->prev = last;
176         to->list = from->list;
177
178         return 1;
179 }
180
181 int probe_list_append(struct data_list_t *to, struct probe_list_t *from)
182 {
183         struct probe_list_t **list = &(to->list);
184         struct probe_list_t *p = NULL;
185         uint32_t num = 0;
186         if (*list == NULL) {
187                 // empty list
188                 *list = from;
189         } else {
190                 p = *list;
191                 *list = from;
192                 from->next = (void *)p;
193                 p->prev = (void *)from;
194         }
195         to->size += from->size;
196
197         num = 0;
198         for (p = from; p != NULL; p = p->next)
199                 num++;
200         to->func_num += num;
201         return 0;
202 }
203
204 static struct probe_list_t *probe_list_rm_element(struct data_list_t *list, struct probe_list_t *element)
205 {
206         struct probe_list_t *prev = element->prev;
207         struct probe_list_t *next = element->next;
208
209         if (prev != NULL)
210                 prev->next = next;
211         else
212                 list->list = next;
213
214         if (next != NULL)
215                 next->prev = prev;
216
217         list->size -= element->size;
218
219         list->func_num--;
220         free_probe_element(element);
221         return next;
222 }
223
224 static struct data_list_t *data_list_unlink_data(struct data_list_t **list, struct data_list_t *element)
225 {
226         struct data_list_t *prev = element->prev;
227         struct data_list_t *next = element->next;
228
229         if (prev != NULL)
230                 /* prev != null, next == null */
231                 /* prev != null, next != null */
232                 prev->next = next;
233         else
234                 /* prev == null, next == null */
235                 /* prev == null, next != null */
236                 *list = next;
237
238         if (next != NULL)
239                 next->prev = (struct lib_list_t *)prev;
240
241         element->prev = NULL;
242         element->next = NULL;
243
244         return next;
245 }
246
247 static struct data_list_t *data_list_rm_data(struct data_list_t **list, struct data_list_t *element)
248 {
249         struct data_list_t *next = NULL;
250
251         next = data_list_unlink_data(list, element);
252         free_data_element(element);
253
254         return next;
255 }
256
257 // find
258 static struct data_list_t *data_list_find_data(struct data_list_t *whered, struct data_list_t *whatd, cmp_data_f cmp)
259 {
260         struct data_list_t *where;
261         struct data_list_t *what = whatd;
262         for (where = whered; where != NULL; where = where->next) {
263                 if (where->hash == what->hash) {
264                         if (cmp(where, what))
265                                 return where;
266                 }
267         }
268         return NULL;
269 }
270
271 static struct probe_list_t *find_probe(struct data_list_t *where, struct probe_list_t *probe)
272 {
273         struct probe_list_t *p ;
274         for (p = where->list; p != NULL; p = p->next)
275                 if (p->size == probe->size)
276                         if (p->func->func_addr == probe->func->func_addr)
277                                 if (strcmp(p->func->args, probe->func->args) == 0)
278                                         break;
279
280         return p;
281 }
282
283 // "from" will be destroyed after this call
284 static int data_list_move_with_hash(struct data_list_t **to, struct data_list_t **from, cmp_data_f cmp)
285 {
286
287         struct data_list_t *p = *from;
288         struct data_list_t *next = NULL;
289         struct data_list_t *sch = NULL;
290         while (p != NULL) {
291                 sch = data_list_find_data(*to, p, cmp);
292                 next = data_list_unlink_data(from, p);
293                 if (sch == NULL) {
294                         data_list_make_hash(p);
295                         data_list_append(to, p);
296                 } else {
297                         data_list_append_probes_hash(sch, p);
298                 }
299                 p = next;
300         }
301         return 1;
302 }
303
304 //---------------------------- collisions resolve ------------------------------
305
306 static int cmp_libs(struct data_list_t *el_1, struct data_list_t *el_2)
307 {
308         return (strcmp(
309                         ((struct lib_list_t *)el_1)->lib->bin_path,
310                         ((struct lib_list_t *)el_2)->lib->bin_path
311                         ) == 0);
312 }
313
314 ///////////////////////////////////////////////////////////////////////////
315 // function removes from new list all probes which are already installed
316 //
317 // cur - current state (lib list with probes)
318 // new - additional probes which were received with MSG_SWAP_INST_ADD msg
319 //       (lib list with probes)
320 // this function removes all probes which are present in cur and new list from
321 // new list so after this function call in new list will be only probes which are
322 // not present in cur list
323 static int resolve_collisions_for_add_msg(struct lib_list_t **cur, struct lib_list_t **new)
324 {
325         struct data_list_t *p = (struct data_list_t *)*new;
326         struct data_list_t *sch = NULL;
327
328         struct probe_list_t *pr = NULL;
329         struct probe_list_t *next_pr = NULL;
330
331         // remove collisions from list "new"
332         while (p != NULL) {
333                 sch = data_list_find_data((struct data_list_t *)*cur, p, cmp_libs);
334                 if (sch == NULL) {
335                         // lib not found in cur config
336                 } else {
337                         // lib found in cur config so resolve collisions
338                         pr = p->list;
339                         while (pr != NULL) {
340                                 // remove collisions
341                                 if (find_probe(sch, pr) != NULL) {
342                                         // probe already exist
343                                         // rm from new config
344                                         next_pr = probe_list_rm_element(p, pr);
345                                         pr = next_pr;
346                                 } else {
347                                         pr = pr->next;
348                                 }
349                         }
350
351                         // rm lib if it is empty
352                         if (p->list == NULL) {
353                                 p = data_list_rm_data((struct data_list_t **)new, p);
354                                 continue;
355                         }
356                 }
357                 p = p->next;
358         }
359         return 1;
360 }
361
362 ///////////////////////////////////////////////////////////////////////////
363 // function removes from cur list all probes which are in list "new"
364 //         and removes from "new" all probes which are not instaled
365 //
366 // cur - current state (lib list with probes)
367 // new - list for probes remove which were received with MSG_SWAP_INST_REMOVE msg
368 //
369 // this function removes all probes which are present in cur and new list from
370 // cur list and removes all probes which are present in new but not present in
371 // cur list so after this function call in new list will be only probes which are
372 // present in cur list
373 static int resolve_collisions_for_rm_msg(struct lib_list_t **cur, struct lib_list_t **new)
374 {
375         struct data_list_t *p = (struct data_list_t *)*new;
376         struct data_list_t *next_l = NULL;
377         struct data_list_t *sch = NULL;
378
379         struct probe_list_t *pr = NULL;
380         struct probe_list_t *next_pr = NULL;
381         struct probe_list_t *tmp = NULL;
382
383         // remove collisions from list "new"
384         while (p != NULL) {
385                 sch = data_list_find_data((struct data_list_t *)*cur, p, cmp_libs);
386                 if (sch == NULL) {
387                         //lib not found so no probes remove
388                         next_l = data_list_rm_data((struct data_list_t **)new, p);
389                 } else {
390                         //lib found so we need remove collisions
391                         pr = p->list;
392                         if (pr == NULL) {
393                                 // if rm probe list is empty that is mean we need
394                                 // to remove all probes on this lib
395                                 data_list_unlink_data((struct data_list_t **)cur, sch);
396                                 data_list_append((struct data_list_t **)new, sch);
397                                 next_l = data_list_rm_data((struct data_list_t **)cur, p);
398                         } else {
399                                 // lib is not empty so merge
400                                 while (pr != NULL) {
401                                         // remove collisions
402                                         if ((tmp = find_probe(sch, pr)) != NULL) {
403                                                 // probe found so remove probe
404                                                 // from cur state
405                                                 probe_list_rm_element(sch, tmp);
406                                                 pr = pr->next;
407                                         } else {
408                                                 // probe no found so remove it
409                                                 // from new state
410                                                 next_pr = probe_list_rm_element(p, pr);
411                                                 pr = next_pr;
412                                         }
413                                 }
414                                 // rm lib if it is empty
415                                 if (sch->list == NULL) {
416                                         data_list_rm_data((struct data_list_t **)cur, sch);
417                                 }
418                                 next_l = p->next;
419                         }
420                 }
421                 p = next_l;
422         }
423         return 1;
424 }
425
426 //--------------------------------------pack ----------------------------------
427
428 static char *pack_lib_head_to_array(char *to, void *data)
429 {
430         struct us_lib_inst_t *lib = data;
431         pack_str(to, lib->bin_path);
432         return to;
433 }
434
435 static char *pack_app_head_to_array(char *to, void *data)
436 {
437         struct app_info_t *app = data;
438         pack_int32(to, app->app_type);
439         pack_str(to, app->app_id);
440         pack_str(to, app->exe_path);
441         return to;
442 }
443
444 static char *pack_data_to_array(struct data_list_t *data, char *to, pack_head_t pack_head)
445 {
446         struct probe_list_t *p;
447
448         to = pack_head(to, data->data);
449         pack_int32(to, data->func_num);
450         for (p = data->list; p != NULL; p = p->next) {
451                 memcpy(to, p->func, p->size);
452                 to += p->size;
453         }
454         return to;
455 }
456
457 static char *pack_data_list_to_array(struct data_list_t *list, uint32_t *len, uint32_t *count, pack_head_t pack)
458 {
459         char *res = NULL;
460         char *to = NULL;
461         uint32_t size = 0;
462         uint32_t cnt = 0;
463         struct data_list_t *p = list;
464
465         for (p = list; p != NULL; p = p->next) {
466                 size += p->size;
467                 cnt++;
468         }
469
470         size += sizeof(uint32_t);
471         *len = size;
472         *count = cnt;
473
474         if (size != 0) {
475                 res = malloc(size);
476                 to = res;
477                 if (to != NULL) {
478                         pack_int32(to, cnt);
479                         for (p = list; p != NULL; p = p->next)
480                                 to = pack_data_to_array(p, to, pack);
481                 } else {
482                         LOGE("can not malloc buffer for data list packing\n");
483                 }
484         }
485         return res;
486 }
487
488 static char *pack_lib_list_to_array(struct lib_list_t *list, uint32_t *size, uint32_t *count)
489 {
490         return pack_data_list_to_array((struct data_list_t *)list, size,
491                                         count, pack_lib_head_to_array);
492 }
493
494 static char *pack_app_list_to_array(struct app_list_t *list, uint32_t *size, uint32_t *count)
495 {
496         return pack_data_list_to_array((struct data_list_t *)list, size,
497                                         count,  pack_app_head_to_array);
498 }
499
500 static int generate_msg(struct msg_t **msg, struct lib_list_t *lib_list, struct app_list_t *app_list)
501 {
502         uint32_t i,
503                  size = 0,
504                  libs_size = 0,
505                  apps_size = 0,
506                  libs_count = 0,
507                  apps_count = 0;
508         char     *p = NULL;
509
510         packed_lib_list = pack_lib_list_to_array(lib_list, &libs_size, &libs_count);
511         // print_buf(packed_lib_list, libs_size, "LIBS");
512
513         packed_app_list = pack_app_list_to_array(app_list, &apps_size, &apps_count);
514         // print_buf(packed_app_list, apps_size, "APPS");
515
516         size = apps_count * libs_size + apps_size;
517
518         LOGI("size = %d, apps= %d, libs = %d\n", size, apps_count, libs_count);
519
520         // add header size
521         *msg = malloc(size + sizeof(**msg));
522         memset(*msg, '*', size);
523
524         p = (char *)*msg;
525         pack_int32(p, 0);               // msg id
526         pack_int32(p, size);            // payload size
527         pack_int32(p, apps_count);
528
529         struct app_list_t *app = app_list;
530         char *app_p = packed_app_list + sizeof(((struct user_space_inst_t *)0)->app_num);
531
532         for (i = 0; i < apps_count; i++) {
533                 memcpy(p, app_p, app->size);
534                 p += app->size;
535                 memcpy(p, packed_lib_list, libs_size);
536                 p += libs_size;
537
538                 app_p += app->size;
539                 app = app->next;
540         }
541
542         free(packed_lib_list);
543         free(packed_app_list);
544
545         // print_buf((char *)*msg, size, "ANSWER");
546         return 1;
547 }
548
549 static void lock_lib_maps_message()
550 {
551         pthread_mutex_lock(&lib_inst_list_mutex);
552 }
553
554 static void unlock_lib_maps_message()
555 {
556         pthread_mutex_unlock(&lib_inst_list_mutex);
557 }
558
559 static void lock_lib_list()
560 {
561         pthread_mutex_lock(&lib_maps_message_mutex);
562 }
563
564 static void unlock_lib_list()
565 {
566         pthread_mutex_unlock(&lib_maps_message_mutex);
567 }
568
569 static void generate_maps_inst_msg(struct user_space_inst_t *us_inst)
570 {
571         lock_lib_maps_message();
572
573         struct lib_list_t *lib = us_inst->lib_inst_list;
574         struct app_list_t *app = us_inst->app_inst_list;
575         char *p, *resolved;
576         uint32_t total_maps_count = 0;
577         uint32_t total_len = sizeof(total_maps_count) + sizeof(*lib_maps_message);
578         char real_path_buf[PATH_MAX];
579
580         /* total message len calculate */
581         while (lib != NULL) {
582                 p = lib->lib->bin_path;
583                 total_len += strlen(p) + 1;
584                 total_maps_count++;
585                 LOGI("lib #%u <%s>\n", total_maps_count, p);
586                 lib = (struct lib_list_t *)lib->next;
587         }
588
589         while (app != NULL) {
590                 p = app->app->exe_path;
591                 resolved = realpath((const char *)p, real_path_buf);
592                 if (resolved != NULL) {
593                         total_len += strlen(real_path_buf) + 1;
594                         total_maps_count++;
595                         LOGI("app #%u <%s>\n", total_maps_count, resolved);
596                 } else {
597                         LOGE("cannot resolve bin path <%s>\n", p);
598                 }
599
600                 app = (struct app_list_t *)app->next;
601         }
602
603         if (lib_maps_message != NULL)
604                 free(lib_maps_message);
605
606         lib_maps_message = malloc(total_len);
607         lib_maps_message->type = MSG_MAPS_INST_LIST;
608         lib_maps_message->length = total_len;
609
610         /* pack data */
611         p = lib_maps_message->data;
612         pack_int32(p, total_maps_count);
613
614         lib = us_inst->lib_inst_list;
615         while (lib != NULL) {
616                 pack_str(p, lib->lib->bin_path);
617                 lib = (struct lib_list_t *)lib->next;
618         }
619
620         app = us_inst->app_inst_list;
621         while (app != NULL) {
622                 resolved = realpath(app->app->exe_path, real_path_buf);
623                 if (resolved != NULL)
624                         pack_str(p, real_path_buf);
625                 app = (struct app_list_t *)app->next;
626         }
627
628         LOGI("total_len = %u\n", total_len);
629         print_buf((char *)lib_maps_message, total_len, "lib_maps_message");
630
631         unlock_lib_maps_message();
632 }
633
634 void send_maps_inst_msg_to(struct target *t)
635 {
636         lock_lib_maps_message();
637         target_send_msg(t, (struct msg_target_t *)lib_maps_message);
638         unlock_lib_maps_message();
639 }
640
641 static void send_maps_inst_msg_to_all_targets()
642 {
643         lock_lib_maps_message();
644         target_send_msg_to_all(lib_maps_message);
645         unlock_lib_maps_message();
646 }
647
648 //-----------------------------------------------------------------------------
649 struct app_info_t *app_info_get_first(struct app_list_t **app_list)
650 {
651         *app_list = prof_session.user_space_inst.app_inst_list;
652         if (*app_list == NULL) {
653                 return NULL;
654         }
655
656         return (*app_list)->app;
657 }
658
659 struct app_info_t *app_info_get_next(struct app_list_t **app_list)
660 {
661         if (*app_list == NULL)
662                 return NULL;
663
664         if ((*app_list = (*app_list)->next) == NULL)
665                 return NULL;
666
667         return (*app_list)->app;
668 }
669
670 //-----------------------------------------------------------------------------
671 int msg_start(struct msg_buf_t *data, struct user_space_inst_t *us_inst,
672               struct msg_t **msg, enum ErrorCode *err)
673 {
674         int res = 0;
675         char *p = NULL;
676         *msg = NULL;
677
678         /* lock list access */
679         lock_lib_list();
680
681         if (!parse_app_inst_list(data, &us_inst->app_num, &us_inst->app_inst_list)) {
682                 *err = ERR_WRONG_MESSAGE_FORMAT;
683                 LOGE("parse app inst\n");
684                 res = 1;
685                 goto msg_start_exit;
686         }
687
688         generate_msg(msg, us_inst->lib_inst_list, us_inst->app_inst_list);
689
690         if (*msg != NULL) {
691                 p = (char *)*msg;
692                 pack_int32(p, NMSG_START);
693         } else {
694                 *err = ERR_CANNOT_START_PROFILING;
695                 res = 1;
696                 goto msg_start_exit;
697         }
698
699         generate_maps_inst_msg(us_inst);
700
701 msg_start_exit:
702         /* unlock list access */
703         unlock_lib_list();
704
705         return res;
706 }
707
708 int msg_swap_inst_add(struct msg_buf_t *data, struct user_space_inst_t *us_inst,
709                       struct msg_t **msg, enum ErrorCode *err)
710 {
711         int res = 0;
712         uint32_t lib_num = 0;
713         char *p = NULL;
714
715         *err = ERR_UNKNOWN;
716
717         /* lock list access */
718         lock_lib_list();
719
720         if (!parse_lib_inst_list(data, &lib_num, &us_inst->lib_inst_list)) {
721                 *err = ERR_WRONG_MESSAGE_FORMAT;
722                 LOGE("parse lib inst list fail\n");
723                 res = 1;
724                 goto msg_swap_inst_add_exit;
725         }
726         // rm probes from new if its presents in cur
727         if (!resolve_collisions_for_add_msg(&us_inst->lib_inst_list, &new_lib_inst_list)) {
728                 LOGE("resolve collision\n");
729                 res = 1;
730                 goto msg_swap_inst_add_exit;
731         };
732
733         // generate msg to send
734         if (us_inst->app_inst_list != NULL) {
735                 generate_msg(msg, new_lib_inst_list, us_inst->app_inst_list);
736                 p = (char *)*msg;
737                 pack_int32(p, NMSG_SWAP_INST_ADD);
738         }
739         // apply changes to cur state
740         if (!data_list_move_with_hash(
741                 (struct data_list_t **)&us_inst->lib_inst_list,
742                 (struct data_list_t **)&new_lib_inst_list,
743                 cmp_libs))
744         {
745                 LOGE("data move\n");
746                 res = 1;
747                 goto msg_swap_inst_add_exit;
748         };
749
750         // free new_list
751         free_data_list((struct data_list_t **)&new_lib_inst_list);
752         new_lib_inst_list = NULL;
753         *err = ERR_NO;
754
755         generate_maps_inst_msg(us_inst);
756         send_maps_inst_msg_to_all_targets();
757
758 msg_swap_inst_add_exit:
759         /* unlock list access */
760         unlock_lib_list();
761
762         return res;
763 }
764
765 int msg_swap_inst_remove(struct msg_buf_t *data, struct user_space_inst_t *us_inst,
766                          struct msg_t **msg, enum ErrorCode *err)
767 {
768         int res = 0;
769         uint32_t lib_num = 0;
770         char *p = NULL;
771         *err = ERR_UNKNOWN;
772
773         /* lock list access */
774         lock_lib_list();
775
776         if (!parse_lib_inst_list(data, &lib_num, &new_lib_inst_list)) {
777                 *err = ERR_WRONG_MESSAGE_FORMAT;
778                 LOGE("parse lib inst\n");
779                 res = 1;
780                 goto msg_swap_inst_remove_exit;
781         }
782
783         if (!resolve_collisions_for_rm_msg(&us_inst->lib_inst_list, &new_lib_inst_list)) {
784                 LOGE("resolve collisions\n");
785                 res = 1;
786                 goto msg_swap_inst_remove_exit;
787         }
788
789         if (us_inst->app_inst_list != NULL) {
790                 if (!generate_msg(msg, new_lib_inst_list, us_inst->app_inst_list)) {
791                         LOGE("generate msg\n");
792                         res = 1;
793                         goto msg_swap_inst_remove_exit;
794                 }
795                 p = (char *)*msg;
796                 pack_int32(p, NMSG_SWAP_INST_ADD);
797         }
798
799         free_data_list((struct data_list_t **)&new_lib_inst_list);
800         new_lib_inst_list = NULL;
801         *err = ERR_NO;
802
803         generate_maps_inst_msg(us_inst);
804         send_maps_inst_msg_to_all_targets();
805
806 msg_swap_inst_remove_exit:
807         /* unlock list access */
808         unlock_lib_list();
809
810         return res;
811 }
812
813 void msg_swap_free_all_data(struct user_space_inst_t *us_inst)
814 {
815         LOGI("new_lib_inst_list %p\n", new_lib_inst_list);
816         if (new_lib_inst_list != NULL) {
817                 LOGI("free new_lib_inst_list start\n");
818                 free_data_list(&new_lib_inst_list);
819                 new_lib_inst_list = NULL;
820                 LOGI("free new_lib_inst_list finish\n");
821         }
822
823         LOGI("us_inst->lib_inst_list %p\n", us_inst->lib_inst_list);
824         if (us_inst->lib_inst_list != NULL) {
825                 LOGI("free us_inst->lib_inst_list start\n");
826                 free_data_list(&us_inst->lib_inst_list);
827                 us_inst->lib_inst_list = NULL;
828                 LOGI("free us_isnt->lib_inst_list finish\n");
829         }
830
831         LOGI("us_inst->app_inst_list %p\n", us_inst->app_inst_list);
832         if (us_inst->app_inst_list != NULL) {
833                 LOGI("free us_inst->app_inst_list start\n");
834                 free_data_list(&us_inst->app_inst_list);
835                 LOGI("free us_inst->app_isnt_list finish\n");
836         }
837 }