tizen 2.3 release
[kernel/api/system-resource.git] / src / resourced / init.c
1 /*
2  * resourced
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 /**
21  * @file init.c
22  * @desc Resourced initialization
23  *
24  **/
25
26 #include "const.h"
27 #include "counter.h"
28 #include "edbus-handler.h"
29 #include "cgroup.h"
30 #include "init.h"
31 #include "macro.h"
32 #include "module-data.h"
33 #include "proc-main.h"
34 #include "proc-monitor.h"
35 #include "swap-common.h"
36 #include "trace.h"
37 #include "version.h"
38
39 #include <Ecore.h>
40 #include <getopt.h>
41 #include <signal.h>
42
43 static struct daemon_opts opts = { 1,
44                                    1,
45                                    1,
46                                    COUNTER_UPDATE_PERIOD,
47                                    FLUSH_PERIOD,
48                                    RESOURCED_DEFAULT_STATE,
49                                    0};
50
51 #define SWAP_MAX_ARG_SIZE 16
52
53 static char swap_arg[SWAP_ARG_END][SWAP_MAX_ARG_SIZE] = { "swapoff",
54                                     "swapon",};
55
56 static void print_root_usage()
57 {
58         puts("You must be root to start it.");
59 }
60
61 static void print_usage()
62 {
63         puts("resourced [Options]");
64         puts("       Application options:");
65         printf
66             ("-u [--update-period] - time interval for updating,"
67              " %d by default\n", opts.update_period);
68         printf
69             ("-f [--flush-period] - time interval for storing data at database,"
70              "%d by default\n", opts.flush_period);
71         printf("-s [--start-daemon] - start as daemon, %d by default\n",
72                opts.start_daemon);
73         puts("-v [--version] - program version");
74         puts("-h [--help] - application help");
75         printf("-c string [--swapcontrol=string] - control swap policy and "
76                "select sting %s, %s by default\n",
77                swap_arg[SWAP_OFF], swap_arg[SWAP_ON]);
78 }
79
80 static void print_version()
81 {
82         printf("Version number: %d.%d.%d\n",
83                 MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION);
84 }
85
86 static int parse_cmd(int argc, char **argv)
87 {
88         const char *optstring = ":hvu:s:f:cw";
89         const struct option options[] = {
90                 {"help", no_argument, 0, 'h'},
91                 {"version", no_argument, 0, 'v'},
92                 {"update-period", required_argument, 0, 'u'},
93                 {"flush-period", required_argument, 0, 'f'},
94                 {"start-daemon", required_argument, 0, 's'},
95                 {"swapcontrol", required_argument, 0, 'c'},
96                 {"enable-watchodg", no_argument, 0, 'w'},
97                 {0, 0, 0, 0}
98         };
99         int longindex, retval, i;
100
101         while ((retval =
102                 getopt_long(argc, argv, optstring, options, &longindex)) != -1)
103                 switch (retval) {
104                 case 'h':
105                 case '?':
106                         print_usage();
107                         return RESOURCED_ERROR_FAIL;
108                 case 'v':
109                         print_version();
110                         return RESOURCED_ERROR_FAIL;
111                 case 'u':
112                         opts.update_period = atoi(optarg);
113                         break;
114                 case 'f':
115                         opts.flush_period = atoi(optarg);
116                         break;
117                 case 's':
118                         opts.start_daemon = atoi(optarg);
119                         break;
120                 case 'c':
121                         for (i = 0; i < SWAP_ARG_END; i++)
122                                 if (optarg && !strncmp(optarg, swap_arg[i],
123                                                        SWAP_MAX_ARG_SIZE)) {
124                                         opts.enable_swap = i;
125                                         _D("argment swaptype = %s",
126                                            swap_arg[i]);
127                                         break;
128                                 }
129                         break;
130                 case 'o':
131                         break;
132                 case 'w':
133                         proc_set_watchdog_state(PROC_WATCHDOG_ENABLE);
134                         break;
135                 default:
136                         printf("Unknown option %c\n", (char)retval);
137                         print_usage();
138                         return RESOURCED_ERROR_FAIL;
139                 }
140         return RESOURCED_ERROR_NONE;
141 }
142
143 static int assert_root(void)
144 {
145         if (getuid() != 0) {
146                 print_root_usage();
147                 return RESOURCED_ERROR_FAIL;
148         }
149         return RESOURCED_ERROR_NONE;
150 }
151
152 static void sig_term_handler(int sig)
153 {
154         struct shared_modules_data *shared_data = get_shared_modules_data();
155
156         opts.state |= RESOURCED_FORCIBLY_QUIT_STATE;
157         _SD("sigterm or sigint received");
158         if (shared_data && shared_data->carg && shared_data->carg->ecore_timer) {
159                 /* save data on exit, it's impossible to do in fini
160                  * module function, due it executes right after ecore stopped */
161                 reschedule_count_timer(shared_data->carg, 0);
162
163                 /* Another way it's introduce another timer and quit main loop
164                  * in it with waiting some event. */
165                 sleep(TIME_TO_SAFE_DATA);
166         }
167
168         ecore_main_loop_quit();
169 }
170
171 static void add_signal_handler(void)
172 {
173         signal(SIGTERM, sig_term_handler);
174         signal(SIGINT, sig_term_handler);
175 }
176
177 int resourced_init(struct daemon_arg *darg)
178 {
179         int ret_code;
180
181         ret_value_msg_if(darg == NULL, RESOURCED_ERROR_INVALID_PARAMETER,
182                          "Invalid daemon argument\n");
183         ret_code = assert_root();
184         ret_value_if(ret_code < 0, RESOURCED_ERROR_FAIL);
185         ecore_init();
186         darg->opts = &opts;
187         ret_code = parse_cmd(darg->argc, darg->argv);
188         ret_value_msg_if(ret_code < 0, RESOURCED_ERROR_FAIL,
189                          "Error parse cmd arguments\n");
190         _D("argment swaptype = %s", swap_arg[opts.enable_swap]);
191         add_signal_handler();
192         edbus_init();
193         return RESOURCED_ERROR_NONE;
194 }
195
196 int resourced_deinit(struct daemon_arg *darg)
197 {
198         ecore_shutdown();
199         edbus_exit();
200         ret_value_msg_if(darg == NULL, RESOURCED_ERROR_INVALID_PARAMETER,
201                          "Invalid daemon argument\n");
202         return RESOURCED_ERROR_NONE;
203 }
204
205 void set_daemon_net_block_state(const enum traffic_restriction_type rst_type,
206         const struct counter_arg *carg)
207 {
208         ret_msg_if(carg == NULL,
209                 "Please provide valid counter arg!");
210
211         if (rst_type == RST_SET)
212                 opts.state |= RESOURCED_NET_BLOCKED_STATE; /* set bit */
213         else {
214                 opts.state &=(~RESOURCED_NET_BLOCKED_STATE); /* nulify bit */
215                 ecore_timer_thaw(carg->ecore_timer);
216         }
217 }