Initialize Tizen 2.3
[framework/system/deviced.git] / src / mmc / ext4.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
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 #include <stdio.h>
21 #include <stdlib.h>
22 #include <limits.h>
23 #include <vconf.h>
24 #include <signal.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <errno.h>
28
29 #include "core/common.h"
30 #include "core/devices.h"
31 #include "core/log.h"
32 #include "mmc-handler.h"
33
34 #define FS_EXT4_NAME    "ext4"
35
36 #define FS_EXT4_SMACK_LABEL " /usr/bin/mmc-smack-label"
37
38 struct popup_data {
39         char *name;
40         char *key;
41         char *value;
42 };
43
44 static const char *ext4_arg[] = {
45         "/sbin/mkfs.ext4",
46         NULL, NULL,
47 };
48
49 static const char *ext4_check_arg[] = {
50         "/sbin/fsck.ext4",
51         "-f", "-y", NULL, NULL,
52 };
53
54 static struct fs_check ext4_info = {
55         FS_TYPE_EXT4,
56         "ext4",
57         0x438,
58         2,
59         {0x53, 0xef},
60 };
61
62 static int mmc_popup_pid;
63
64 static bool ext4_match(const char *devpath)
65 {
66         char buf[4];
67         int fd, r;
68
69         fd = open(devpath, O_RDONLY);
70         if (fd < 0) {
71                 _E("failed to open fd(%s) : %s", devpath, strerror(errno));
72                 return false;
73         }
74
75         /* check fs type with magic code */
76         r = lseek(fd, ext4_info.offset, SEEK_SET);
77         if (r < 0)
78                 goto error;
79
80         r = read(fd, buf, 2);
81         if (r < 0)
82                 goto error;
83
84         _D("mmc search magic : 0x%2x, 0x%2x", buf[0],buf[1]);
85         if (memcmp(buf, ext4_info.magic, ext4_info.magic_sz))
86                 goto error;
87
88         close(fd);
89         _D("MMC type : %s", ext4_info.name);
90         return true;
91
92 error:
93         close(fd);
94         _E("failed to match with ext4(%s)", devpath);
95         return false;
96 }
97
98 static int ext4_check(const char *devpath)
99 {
100         int argc;
101         argc = ARRAY_SIZE(ext4_check_arg);
102         ext4_check_arg[argc - 2] = devpath;
103         return run_child(argc, ext4_check_arg);
104 }
105
106 static int mmc_check_smack(const char *mount_point)
107 {
108         char buf[NAME_MAX] = {0,};
109
110         snprintf(buf, sizeof(buf), "%s", mount_point);
111         launch_evenif_exist(FS_EXT4_SMACK_LABEL, buf);
112
113         vconf_set_int(VCONFKEY_SYSMAN_MMC_STATUS, VCONFKEY_SYSMAN_MMC_MOUNTED);
114         vconf_set_int(VCONFKEY_SYSMAN_MMC_MOUNT, VCONFKEY_SYSMAN_MMC_MOUNT_COMPLETED);
115         if (mmc_popup_pid > 0) {
116                 _E("will be killed mmc-popup(%d)", mmc_popup_pid);
117                 kill(mmc_popup_pid, SIGTERM);
118         }
119         return 0;
120 }
121
122 static int check_smack_popup(void)
123 {
124         int ret = -1;
125         int val = -1;
126         struct popup_data *params;
127         static const struct device_ops *apps = NULL;
128
129         ret = vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &val);
130         if (val == 1 || ret != 0) {
131                 if (apps == NULL) {
132                         apps = find_device("apps");
133                         if (apps == NULL)
134                                 return 0;
135                 }
136                 params = malloc(sizeof(struct popup_data));
137                 if (params == NULL) {
138                         _E("Malloc failed");
139                         return -1;
140                 }
141                 params->name = MMC_POPUP_NAME;
142                 params->key = MMC_POPUP_APP_KEY;
143                 params->value = MMC_POPUP_SMACK_VALUE;
144                 apps->init(params);
145                 free(params);
146         }
147
148         return 0;
149 }
150
151 static int ext4_mount(bool smack, const char *devpath, const char *mount_point)
152 {
153         int r, retry = RETRY_COUNT;
154
155         do {
156                 r = mount(devpath, mount_point, "ext4", 0, NULL);
157                 if (!r) {
158                         _D("Mounted mmc card [ext4]");
159                         if (smack) {
160                                 check_smack_popup();
161                                 mmc_check_smack(mount_point);
162                         }
163                         return 0;
164                 }
165                 usleep(100000);
166         } while (r < 0 && errno == ENOENT && retry-- > 0);
167
168         return -errno;
169 }
170
171 static int ext4_format(const char *devpath)
172 {
173         int argc;
174         argc = ARRAY_SIZE(ext4_arg);
175         ext4_arg[argc - 2] = devpath;
176         return run_child(argc, ext4_arg);
177 }
178
179 static const struct mmc_fs_ops ext4_ops = {
180         .type = FS_TYPE_EXT4,
181         .name = "ext4",
182         .match = ext4_match,
183         .check = ext4_check,
184         .mount = ext4_mount,
185         .format = ext4_format,
186 };
187
188 static void __CONSTRUCTOR__ module_init(void)
189 {
190         add_fs(&ext4_ops);
191 }
192 /*
193 static void __DESTRUCTOR__ module_exit(void)
194 {
195         remove_fs(&ext4_ops);
196 }
197 */