[IMPROVE] Implement different kind of probes
[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 // Check whether functions are equal. If so, returns first argument, otherwise - NULL
272 static struct probe_list_t *probes_equal(struct probe_list_t *first, struct probe_list_t *second)
273 {
274         if (first->size != second->size)
275                 return NULL;
276
277         if (first->func->func_addr != second->func->func_addr)
278                 return NULL;
279
280         if (first->func->probe_type != second->func->probe_type)
281                 return NULL;
282
283         return first;
284 }
285
286 static struct probe_list_t *find_probe(struct data_list_t *where, struct probe_list_t *probe)
287 {
288         struct probe_list_t *p ;
289         for (p = where->list; p != NULL; p = p->next)
290                 if (probes_equal(p, probe))
291                         break;
292
293         return p;
294 }
295
296 // "from" will be destroyed after this call
297 static int data_list_move_with_hash(struct data_list_t **to, struct data_list_t **from, cmp_data_f cmp)
298 {
299
300         struct data_list_t *p = *from;
301         struct data_list_t *next = NULL;
302         struct data_list_t *sch = NULL;
303         while (p != NULL) {
304                 sch = data_list_find_data(*to, p, cmp);
305                 next = data_list_unlink_data(from, p);
306                 if (sch == NULL) {
307                         data_list_make_hash(p);
308                         data_list_append(to, p);
309                 } else {
310                         data_list_append_probes_hash(sch, p);
311                 }
312                 p = next;
313         }
314         return 1;
315 }
316
317 //---------------------------- collisions resolve ------------------------------
318
319 static int cmp_libs(struct data_list_t *el_1, struct data_list_t *el_2)
320 {
321         return (strcmp(
322                         ((struct lib_list_t *)el_1)->lib->bin_path,
323                         ((struct lib_list_t *)el_2)->lib->bin_path
324                         ) == 0);
325 }
326
327 ///////////////////////////////////////////////////////////////////////////
328 // function removes from new list all probes which are already installed
329 //
330 // cur - current state (lib list with probes)
331 // new - additional probes which were received with MSG_SWAP_INST_ADD msg
332 //       (lib list with probes)
333 // this function removes all probes which are present in cur and new list from
334 // new list so after this function call in new list will be only probes which are
335 // not present in cur list
336 static int resolve_collisions_for_add_msg(struct lib_list_t **cur, struct lib_list_t **new)
337 {
338         struct data_list_t *p = (struct data_list_t *)*new;
339         struct data_list_t *sch = NULL;
340
341         struct probe_list_t *pr = NULL;
342         struct probe_list_t *next_pr = NULL;
343
344         // remove collisions from list "new"
345         while (p != NULL) {
346                 sch = data_list_find_data((struct data_list_t *)*cur, p, cmp_libs);
347                 if (sch == NULL) {
348                         // lib not found in cur config
349                 } else {
350                         // lib found in cur config so resolve collisions
351                         pr = p->list;
352                         while (pr != NULL) {
353                                 // remove collisions
354                                 if (find_probe(sch, pr) != NULL) {
355                                         // probe already exist
356                                         // rm from new config
357                                         next_pr = probe_list_rm_element(p, pr);
358                                         pr = next_pr;
359                                 } else {
360                                         pr = pr->next;
361                                 }
362                         }
363
364                         // rm lib if it is empty
365                         if (p->list == NULL) {
366                                 p = data_list_rm_data((struct data_list_t **)new, p);
367                                 continue;
368                         }
369                 }
370                 p = p->next;
371         }
372         return 1;
373 }
374
375 ///////////////////////////////////////////////////////////////////////////
376 // function removes from cur list all probes which are in list "new"
377 //         and removes from "new" all probes which are not instaled
378 //
379 // cur - current state (lib list with probes)
380 // new - list for probes remove which were received with MSG_SWAP_INST_REMOVE msg
381 //
382 // this function removes all probes which are present in cur and new list from
383 // cur list and removes all probes which are present in new but not present in
384 // cur list so after this function call in new list will be only probes which are
385 // present in cur list
386 static int resolve_collisions_for_rm_msg(struct lib_list_t **cur, struct lib_list_t **new)
387 {
388         struct data_list_t *p = (struct data_list_t *)*new;
389         struct data_list_t *next_l = NULL;
390         struct data_list_t *sch = NULL;
391
392         struct probe_list_t *pr = NULL;
393         struct probe_list_t *next_pr = NULL;
394         struct probe_list_t *tmp = NULL;
395
396         // remove collisions from list "new"
397         while (p != NULL) {
398                 sch = data_list_find_data((struct data_list_t *)*cur, p, cmp_libs);
399                 if (sch == NULL) {
400                         //lib not found so no probes remove
401                         next_l = data_list_rm_data((struct data_list_t **)new, p);
402                 } else {
403                         //lib found so we need remove collisions
404                         pr = p->list;
405                         if (pr == NULL) {
406                                 // if rm probe list is empty that is mean we need
407                                 // to remove all probes on this lib
408                                 data_list_unlink_data((struct data_list_t **)cur, sch);
409                                 data_list_append((struct data_list_t **)new, sch);
410                                 next_l = data_list_rm_data((struct data_list_t **)cur, p);
411                         } else {
412                                 // lib is not empty so merge
413                                 while (pr != NULL) {
414                                         // remove collisions
415                                         if ((tmp = find_probe(sch, pr)) != NULL) {
416                                                 // probe found so remove probe
417                                                 // from cur state
418                                                 probe_list_rm_element(sch, tmp);
419                                                 pr = pr->next;
420                                         } else {
421                                                 // probe no found so remove it
422                                                 // from new state
423                                                 next_pr = probe_list_rm_element(p, pr);
424                                                 pr = next_pr;
425                                         }
426                                 }
427                                 // rm lib if it is empty
428                                 if (sch->list == NULL) {
429                                         data_list_rm_data((struct data_list_t **)cur, sch);
430                                 }
431                                 next_l = p->next;
432                         }
433                 }
434                 p = next_l;
435         }
436         return 1;
437 }
438
439 //--------------------------------------pack ----------------------------------
440
441 static char *pack_lib_head_to_array(char *to, void *data)
442 {
443         struct us_lib_inst_t *lib = data;
444         pack_str(to, lib->bin_path);
445         return to;
446 }
447
448 static char *pack_app_head_to_array(char *to, void *data)
449 {
450         struct app_info_t *app = data;
451         pack_int32(to, app->app_type);
452         pack_str(to, app->app_id);
453         pack_str(to, app->exe_path);
454         return to;
455 }
456
457 static char *pack_data_to_array(struct data_list_t *data, char *to, pack_head_t pack_head)
458 {
459         struct probe_list_t *p;
460
461         to = pack_head(to, data->data);
462         pack_int32(to, data->func_num);
463         for (p = data->list; p != NULL; p = p->next) {
464                 memcpy(to, p->func, p->size);
465                 to += p->size;
466         }
467         return to;
468 }
469
470 static char *pack_data_list_to_array(struct data_list_t *list, uint32_t *len, uint32_t *count, pack_head_t pack)
471 {
472         char *res = NULL;
473         char *to = NULL;
474         uint32_t size = 0;
475         uint32_t cnt = 0;
476         struct data_list_t *p = list;
477
478         for (p = list; p != NULL; p = p->next) {
479                 size += p->size;
480                 cnt++;
481         }
482
483         size += sizeof(uint32_t);
484         *len = size;
485         *count = cnt;
486
487         if (size != 0) {
488                 res = malloc(size);
489                 to = res;
490                 if (to != NULL) {
491                         pack_int32(to, cnt);
492                         for (p = list; p != NULL; p = p->next)
493                                 to = pack_data_to_array(p, to, pack);
494                 } else {
495                         LOGE("can not malloc buffer for data list packing\n");
496                 }
497         }
498         return res;
499 }
500
501 static char *pack_lib_list_to_array(struct lib_list_t *list, uint32_t *size, uint32_t *count)
502 {
503         return pack_data_list_to_array((struct data_list_t *)list, size,
504                                         count, pack_lib_head_to_array);
505 }
506
507 static char *pack_app_list_to_array(struct app_list_t *list, uint32_t *size, uint32_t *count)
508 {
509         return pack_data_list_to_array((struct data_list_t *)list, size,
510                                         count,  pack_app_head_to_array);
511 }
512
513 static int generate_msg(struct msg_t **msg, struct lib_list_t *lib_list, struct app_list_t *app_list)
514 {
515         uint32_t i,
516                  size = 0,
517                  libs_size = 0,
518                  apps_size = 0,
519                  libs_count = 0,
520                  apps_count = 0;
521         char     *p = NULL;
522
523         packed_lib_list = pack_lib_list_to_array(lib_list, &libs_size, &libs_count);
524         // print_buf(packed_lib_list, libs_size, "LIBS");
525
526         packed_app_list = pack_app_list_to_array(app_list, &apps_size, &apps_count);
527         // print_buf(packed_app_list, apps_size, "APPS");
528
529         size = apps_count * libs_size + apps_size;
530
531         LOGI("size = %d, apps= %d, libs = %d\n", size, apps_count, libs_count);
532
533         // add header size
534         *msg = malloc(size + sizeof(**msg));
535         memset(*msg, '*', size);
536
537         p = (char *)*msg;
538         pack_int32(p, 0);               // msg id
539         pack_int32(p, size);            // payload size
540         pack_int32(p, apps_count);
541
542         struct app_list_t *app = app_list;
543         char *app_p = packed_app_list + sizeof(((struct user_space_inst_t *)0)->app_num);
544
545         for (i = 0; i < apps_count; i++) {
546                 memcpy(p, app_p, app->size);
547                 p += app->size;
548                 memcpy(p, packed_lib_list, libs_size);
549                 p += libs_size;
550
551                 app_p += app->size;
552                 app = app->next;
553         }
554
555         free(packed_lib_list);
556         free(packed_app_list);
557
558         // print_buf((char *)*msg, size, "ANSWER");
559         return 1;
560 }
561
562 static void lock_lib_maps_message()
563 {
564         pthread_mutex_lock(&lib_inst_list_mutex);
565 }
566
567 static void unlock_lib_maps_message()
568 {
569         pthread_mutex_unlock(&lib_inst_list_mutex);
570 }
571
572 static void lock_lib_list()
573 {
574         pthread_mutex_lock(&lib_maps_message_mutex);
575 }
576
577 static void unlock_lib_list()
578 {
579         pthread_mutex_unlock(&lib_maps_message_mutex);
580 }
581
582 static void generate_maps_inst_msg(struct user_space_inst_t *us_inst)
583 {
584         lock_lib_maps_message();
585
586         struct lib_list_t *lib = us_inst->lib_inst_list;
587         struct app_list_t *app = us_inst->app_inst_list;
588         char *p, *resolved;
589         uint32_t total_maps_count = 0;
590         uint32_t total_len = sizeof(total_maps_count) + sizeof(*lib_maps_message);
591         char real_path_buf[PATH_MAX];
592
593         /* total message len calculate */
594         while (lib != NULL) {
595                 p = lib->lib->bin_path;
596                 total_len += strlen(p) + 1;
597                 total_maps_count++;
598                 LOGI("lib #%u <%s>\n", total_maps_count, p);
599                 lib = (struct lib_list_t *)lib->next;
600         }
601
602         while (app != NULL) {
603                 p = app->app->exe_path;
604                 resolved = realpath((const char *)p, real_path_buf);
605                 if (resolved != NULL) {
606                         total_len += strlen(real_path_buf) + 1;
607                         total_maps_count++;
608                         LOGI("app #%u <%s>\n", total_maps_count, resolved);
609                 } else {
610                         LOGE("cannot resolve bin path <%s>\n", p);
611                 }
612
613                 app = (struct app_list_t *)app->next;
614         }
615
616         if (lib_maps_message != NULL)
617                 free(lib_maps_message);
618
619         lib_maps_message = malloc(total_len);
620         lib_maps_message->type = MSG_MAPS_INST_LIST;
621         lib_maps_message->length = total_len;
622
623         /* pack data */
624         p = lib_maps_message->data;
625         pack_int32(p, total_maps_count);
626
627         lib = us_inst->lib_inst_list;
628         while (lib != NULL) {
629                 pack_str(p, lib->lib->bin_path);
630                 lib = (struct lib_list_t *)lib->next;
631         }
632
633         app = us_inst->app_inst_list;
634         while (app != NULL) {
635                 resolved = realpath(app->app->exe_path, real_path_buf);
636                 if (resolved != NULL)
637                         pack_str(p, real_path_buf);
638                 app = (struct app_list_t *)app->next;
639         }
640
641         LOGI("total_len = %u\n", total_len);
642         print_buf((char *)lib_maps_message, total_len, "lib_maps_message");
643
644         unlock_lib_maps_message();
645 }
646
647 void send_maps_inst_msg_to(struct target *t)
648 {
649         lock_lib_maps_message();
650         target_send_msg(t, (struct msg_target_t *)lib_maps_message);
651         unlock_lib_maps_message();
652 }
653
654 static void send_maps_inst_msg_to_all_targets()
655 {
656         lock_lib_maps_message();
657         target_send_msg_to_all(lib_maps_message);
658         unlock_lib_maps_message();
659 }
660
661 //-----------------------------------------------------------------------------
662 struct app_info_t *app_info_get_first(struct app_list_t **app_list)
663 {
664         *app_list = prof_session.user_space_inst.app_inst_list;
665         if (*app_list == NULL) {
666                 return NULL;
667         }
668
669         return (*app_list)->app;
670 }
671
672 struct app_info_t *app_info_get_next(struct app_list_t **app_list)
673 {
674         if (*app_list == NULL)
675                 return NULL;
676
677         if ((*app_list = (*app_list)->next) == NULL)
678                 return NULL;
679
680         return (*app_list)->app;
681 }
682
683 //-----------------------------------------------------------------------------
684 int msg_start(struct msg_buf_t *data, struct user_space_inst_t *us_inst,
685               struct msg_t **msg, enum ErrorCode *err)
686 {
687         int res = 0;
688         char *p = NULL;
689         *msg = NULL;
690
691         /* lock list access */
692         lock_lib_list();
693
694         if (!parse_app_inst_list(data, &us_inst->app_num, &us_inst->app_inst_list)) {
695                 *err = ERR_WRONG_MESSAGE_FORMAT;
696                 LOGE("parse app inst\n");
697                 res = 1;
698                 goto msg_start_exit;
699         }
700
701         generate_msg(msg, us_inst->lib_inst_list, us_inst->app_inst_list);
702
703         if (*msg != NULL) {
704                 p = (char *)*msg;
705                 pack_int32(p, NMSG_START);
706         } else {
707                 *err = ERR_CANNOT_START_PROFILING;
708                 res = 1;
709                 goto msg_start_exit;
710         }
711
712         generate_maps_inst_msg(us_inst);
713
714 msg_start_exit:
715         /* unlock list access */
716         unlock_lib_list();
717
718         return res;
719 }
720
721 int msg_swap_inst_add(struct msg_buf_t *data, struct user_space_inst_t *us_inst,
722                       struct msg_t **msg, enum ErrorCode *err)
723 {
724         int res = 0;
725         uint32_t lib_num = 0;
726         char *p = NULL;
727
728         *err = ERR_UNKNOWN;
729
730         /* lock list access */
731         lock_lib_list();
732
733         if (!parse_lib_inst_list(data, &lib_num, &us_inst->lib_inst_list)) {
734                 *err = ERR_WRONG_MESSAGE_FORMAT;
735                 LOGE("parse lib inst list fail\n");
736                 res = 1;
737                 goto msg_swap_inst_add_exit;
738         }
739         // rm probes from new if its presents in cur
740         if (!resolve_collisions_for_add_msg(&us_inst->lib_inst_list, &new_lib_inst_list)) {
741                 LOGE("resolve collision\n");
742                 res = 1;
743                 goto msg_swap_inst_add_exit;
744         };
745
746         // generate msg to send
747         if (us_inst->app_inst_list != NULL) {
748                 generate_msg(msg, new_lib_inst_list, us_inst->app_inst_list);
749                 p = (char *)*msg;
750                 pack_int32(p, NMSG_SWAP_INST_ADD);
751         }
752         // apply changes to cur state
753         if (!data_list_move_with_hash(
754                 (struct data_list_t **)&us_inst->lib_inst_list,
755                 (struct data_list_t **)&new_lib_inst_list,
756                 cmp_libs))
757         {
758                 LOGE("data move\n");
759                 res = 1;
760                 goto msg_swap_inst_add_exit;
761         };
762
763         // free new_list
764         free_data_list((struct data_list_t **)&new_lib_inst_list);
765         new_lib_inst_list = NULL;
766         *err = ERR_NO;
767
768         generate_maps_inst_msg(us_inst);
769         send_maps_inst_msg_to_all_targets();
770
771 msg_swap_inst_add_exit:
772         /* unlock list access */
773         unlock_lib_list();
774
775         return res;
776 }
777
778 int msg_swap_inst_remove(struct msg_buf_t *data, struct user_space_inst_t *us_inst,
779                          struct msg_t **msg, enum ErrorCode *err)
780 {
781         int res = 0;
782         uint32_t lib_num = 0;
783         char *p = NULL;
784         *err = ERR_UNKNOWN;
785
786         /* lock list access */
787         lock_lib_list();
788
789         if (!parse_lib_inst_list(data, &lib_num, &new_lib_inst_list)) {
790                 *err = ERR_WRONG_MESSAGE_FORMAT;
791                 LOGE("parse lib inst\n");
792                 res = 1;
793                 goto msg_swap_inst_remove_exit;
794         }
795
796         if (!resolve_collisions_for_rm_msg(&us_inst->lib_inst_list, &new_lib_inst_list)) {
797                 LOGE("resolve collisions\n");
798                 res = 1;
799                 goto msg_swap_inst_remove_exit;
800         }
801
802         if (us_inst->app_inst_list != NULL) {
803                 if (!generate_msg(msg, new_lib_inst_list, us_inst->app_inst_list)) {
804                         LOGE("generate msg\n");
805                         res = 1;
806                         goto msg_swap_inst_remove_exit;
807                 }
808                 p = (char *)*msg;
809                 pack_int32(p, NMSG_SWAP_INST_ADD);
810         }
811
812         free_data_list((struct data_list_t **)&new_lib_inst_list);
813         new_lib_inst_list = NULL;
814         *err = ERR_NO;
815
816         generate_maps_inst_msg(us_inst);
817         send_maps_inst_msg_to_all_targets();
818
819 msg_swap_inst_remove_exit:
820         /* unlock list access */
821         unlock_lib_list();
822
823         return res;
824 }
825
826 void msg_swap_free_all_data(struct user_space_inst_t *us_inst)
827 {
828         LOGI("new_lib_inst_list %p\n", new_lib_inst_list);
829         if (new_lib_inst_list != NULL) {
830                 LOGI("free new_lib_inst_list start\n");
831                 free_data_list(&new_lib_inst_list);
832                 new_lib_inst_list = NULL;
833                 LOGI("free new_lib_inst_list finish\n");
834         }
835
836         LOGI("us_inst->lib_inst_list %p\n", us_inst->lib_inst_list);
837         if (us_inst->lib_inst_list != NULL) {
838                 LOGI("free us_inst->lib_inst_list start\n");
839                 free_data_list(&us_inst->lib_inst_list);
840                 us_inst->lib_inst_list = NULL;
841                 LOGI("free us_isnt->lib_inst_list finish\n");
842         }
843
844         LOGI("us_inst->app_inst_list %p\n", us_inst->app_inst_list);
845         if (us_inst->app_inst_list != NULL) {
846                 LOGI("free us_inst->app_inst_list start\n");
847                 free_data_list(&us_inst->app_inst_list);
848                 LOGI("free us_inst->app_isnt_list finish\n");
849         }
850 }