[FIX] prevent issue
[platform/core/system/swap-manager.git] / daemon / buffer.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  * Nikita Kalyazin    <n.kalyazin@samsung.com>
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  * Contributors:
24  * - Samsung RnD Institute Russia
25  *
26  */
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <string.h>
34
35 #include "daemon.h"
36 #include "buffer.h"
37 #include "ioctl_commands.h"
38 #include "debug.h"
39
40 #define SUBBUF_SIZE 32 * 1024
41 #define SUBBUF_NUM 8
42
43 static int open_tasks_dev(void)
44 {
45         if (manager.fd.inst_tasks == NULL) {
46                 manager.fd.inst_tasks = fopen(INST_PID_FILENAME, "re");
47                 if (manager.fd.inst_tasks == NULL) {
48                         GETSTRERROR(errno, buf);
49                         LOGE("Cannot open tasks dev: %s\n", buf);
50                         return 1;
51                 }
52                 LOGI("tasks dev opened: %s, %d\n", BUF_FILENAME, manager.buf_fd);
53         } else {
54                 LOGW("tasks dev double open try: <%s>\n", INST_PID_FILENAME);
55         }
56
57         return 0;
58 }
59
60 static void close_tasks_dev(void)
61 {
62         LOGI("close tasks dev (%d)\n", manager.fd.inst_tasks);
63         if (manager.fd.inst_tasks != NULL) {
64                 fclose(manager.fd.inst_tasks);
65                 manager.fd.inst_tasks = NULL;
66         } else {
67                 LOGW("manager.fd.inst_tasks alredy closed or not opened\n");
68         }
69 }
70
71 static int open_buf_ctl(void)
72 {
73         manager.buf_fd = open(BUF_FILENAME, O_RDONLY | O_CLOEXEC);
74         if (manager.buf_fd == -1) {
75                 GETSTRERROR(errno, buf);
76                 LOGE("Cannot open buffer: %s\n", buf);
77                 return 1;
78         }
79         LOGI("buffer opened: %s, %d\n", BUF_FILENAME, manager.buf_fd);
80
81         manager.user_ev_fd = open(USER_EVENT_FILENAME, O_WRONLY | O_CLOEXEC);
82         if (manager.user_ev_fd == -1) {
83                 GETSTRERROR(errno, buf);
84                 LOGE("Cannot open user event sysfs file: %s\n", buf);
85                 return 1;
86         }
87         LOGI("user event sysfs file opened: %s, %d\n", USER_EVENT_FILENAME,
88              manager.user_ev_fd);
89
90         return 0;
91 }
92
93 static void close_buf_ctl(void)
94 {
95         LOGI("close buffer (%d)\n", manager.buf_fd);
96         close(manager.buf_fd);
97
98         LOGI("close user event sysfs file (%d)\n", manager.user_ev_fd);
99         close(manager.user_ev_fd);
100 }
101
102 static int insert_buf_modules(void)
103 {
104         if (system("cd /opt/swap/sdk && ./start.sh")) {
105                 LOGE("Cannot insert swap modules\n");
106                 return -1;
107         }
108
109         return 0;
110 }
111
112 int init_buf(void)
113 {
114         struct buffer_initialize init = {
115                 .size = SUBBUF_SIZE,
116                 .count = SUBBUF_NUM,
117         };
118
119         if (insert_buf_modules() != 0) {
120                 LOGE("Cannot insert buffer modules\n");
121                 return 1;
122         }
123
124         if (open_buf_ctl() != 0) {
125                 LOGE("Cannot open buffer\n");
126                 return 1;
127         }
128
129         if (ioctl(manager.buf_fd, SWAP_DRIVER_BUFFER_INITIALIZE, &init) == -1) {
130                 GETSTRERROR(errno, buf);
131                 LOGE("Cannot init buffer: %s\n", buf);
132                 return 1;
133         }
134
135         if (open_tasks_dev() != 0) {
136                 GETSTRERROR(errno, buf);
137                 LOGE("Cannot open tasks: %s\n", buf);
138                 return 1;
139         }
140
141         return 0;
142 }
143
144 void exit_buf(void)
145 {
146         LOGI("Uninit driver (%d)\n", manager.buf_fd);
147         if (ioctl(manager.buf_fd, SWAP_DRIVER_BUFFER_UNINITIALIZE) == -1) {
148                 GETSTRERROR(errno, buf);
149                 LOGW("Cannot uninit driver: %s\n", buf);
150         }
151
152         close_buf_ctl();
153         close_tasks_dev();
154 }
155
156 void flush_buf(void)
157 {
158         if (ioctl(manager.buf_fd, SWAP_DRIVER_FLUSH_BUFFER) == -1) {
159                 GETSTRERROR(errno, buf);
160                 LOGW("Cannot send flush to driver: %s\n", buf);
161         }
162 }
163
164 void wake_up_buf(void)
165 {
166         if (ioctl(manager.buf_fd, SWAP_DRIVER_WAKE_UP) == -1) {
167                 GETSTRERROR(errno, buf);
168                 LOGW("Cannot send wake up to driver: %s\n", buf);
169         }
170 }
171
172 int write_to_buf(struct msg_data_t *msg)
173 {
174         uint32_t total_len = MSG_DATA_HDR_LEN + msg->len;
175
176         if (write(manager.user_ev_fd, msg, total_len) == -1) {
177                 GETSTRERROR(errno, buf);
178                 LOGE("write to buf (user_ev_fd=%d, msg=%p, len=%d) %s\n",
179                      manager.user_ev_fd, msg, total_len, buf);
180                 return 1;
181         }
182         return 0;
183 }