2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <sys/types.h>
24 #include <tzplatform_config.h>
26 #include <libsyscommon/dbus-system.h>
30 #include "storage-internal.h"
31 #include "storage-external-dbus.h"
33 #define FORMAT_TIMEOUT (120*1000)
34 #define USER_PARTITION "user"
37 Get compat path from origin Multi-user path
38 from TZ_USER_CONTENT/.. to /opt/usr/media/..
39 Input should be normalized path like /opt/usr/home/owner/media (TODO: internal normalization)
41 Why this API should be provided?
42 In multi-user environment, each user has own compat content direcotry.(/opt/usr/media)
43 However, although system daemon operates real path,
44 system daemon needs to provide compat path to App if the real path is converted.
47 #include <storage-internal.h>
50 if(storage_get_compat_internal_path(src, sizeof(dest), dest) < 0)
51 // cannot convert. use src path
53 // can convert. use dest path
55 //LCOV_EXCL_START Untested function
56 API int storage_get_compat_internal_path(const char* origin, int len, char* compat)
62 if (!compat || !origin) {
63 _E("Invalid parameter");
67 if (getuid() <= USER_UID_START) {
68 //LCOV_EXCL_START System Error
69 _E("Only apps and user session daemons are allowed "
70 "to use storage_get_compat_internal_path()");
75 // this API works on place where compat path is bind-mounted
76 if (!is_compat_bind_mount()) {
77 //LCOV_EXCL_START System Error
78 _E("No compat bind mount");
83 str = tzplatform_uid_getenv(getuid(), TZ_USER_CONTENT);
84 str_len = strlen(str);
85 if (strncmp(origin, str, str_len) != 0) {
86 _E("Failed to match TZ_USER_CONTENT");
90 r = snprintf(compat, len, "%s%s", COMPAT_DIR, origin + str_len);
92 //LCOV_EXCL_START System Error
93 _E("Failed to create new path");
103 Get Multi-user path from compat path
104 from /opt/usr/media/.. to TZ_USER_CONTENT/..
105 Input should be normalized path like /opt/usr/media (TODO: internal normalization)
107 Why this API should be provided?
108 In multi-user environment, each user has own compat content direcotry.(/opt/usr/media)
109 However, although some APIs send the compat path to system daemon,
110 system daemon should access real path.
113 #include <storage-internal.h>
116 if(storage_get_origin_internal_path(src, sizeof(dest), dest) < 0)
117 // cannot convert. use src path
119 // can convert. use dest path
121 API int storage_get_origin_internal_path(const char* compat, int len, char* origin)
126 if (!compat || !origin) {
127 _E("Invalid parameter");
131 if (getuid() <= USER_UID_START) {
132 //LCOV_EXCL_START System Error
133 _E("Only apps and user session daemons are allowed "
134 "to use storage_get_origin_internal_path()");
139 // this API works on place where compat path is bind-mounted
140 if (!is_compat_bind_mount()) {
141 //LCOV_EXCL_START System Error
142 _E("no compat bind mount");
147 compat_len = strlen(COMPAT_DIR);
148 if (strncmp(compat, COMPAT_DIR, compat_len) != 0) {
149 _E("failed to match COMPAT_DIR");
153 r = snprintf(origin, len, "%s%s", tzplatform_uid_getenv(getuid(), TZ_USER_CONTENT), compat + compat_len);
155 //LCOV_EXCL_START System Error
156 _E("failed to create new path");
164 API int storage_get_primary_sdcard(int *storage_id, char **path)
168 char *reply_mount_point = NULL;
171 if (!storage_id || !path)
172 return STORAGE_ERROR_INVALID_PARAMETER;
174 if (!storage_ext_is_supported())
175 return STORAGE_ERROR_NOT_SUPPORTED;
177 ret_dbus = dbus_handle_method_sync_with_reply_var(STORAGE_EXT_BUS_NAME,
178 STORAGE_EXT_PATH_MANAGER,
179 STORAGE_EXT_IFACE_MANAGER,
184 //LCOV_EXCL_START System Error
185 _E("Failed to get primary sdcard partition"); //LCOV_EXCL_LINE
186 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
190 if (!g_variant_get_safe(reply, "(issssssisibii)",
194 NULL, &reply_mount_point,
197 g_variant_unref(reply);
198 return STORAGE_ERROR_OPERATION_FAILED;
201 g_variant_unref(reply);
204 ret = STORAGE_ERROR_NO_DEVICE;
208 *path = strdup(reply_mount_point);
210 ret = STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
214 *storage_id = reply_id;
216 ret = STORAGE_ERROR_NONE;
218 g_free(reply_mount_point);
223 API int storage_get_storage_level(const char *path, char **level)
228 return STORAGE_ERROR_INVALID_PARAMETER;
230 ret_level = storage_ext_get_storage_level(path, level);
231 if (ret_level == -ENOMEM)
232 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
233 else if (ret_level == -EINVAL)
234 return STORAGE_ERROR_INVALID_PARAMETER;
235 else if (ret_level < 0)
236 return STORAGE_ERROR_OPERATION_FAILED;
238 return STORAGE_ERROR_NONE;
241 //LCOV_EXCL_START Not called callback
242 static void mount_mmc_cb(GVariant *var, void *user_data, GError *err)
244 struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
247 _D("mount_mmc_cb called");
250 _E("no message [%s]", err->message);
255 g_variant_get(var, "(i)", &mmc_ret);
257 _I("Mount State : %d", mmc_ret);
261 g_variant_unref(var);
262 (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
266 API int storage_request_mount_mmc(struct mmc_contents *mmc_data)
268 void (*mount_cb)(GVariant *, void *, GError *) = NULL;
274 if (mmc_data && mmc_data->mmc_cb) {
275 _I("Mount callback exists");
276 mount_cb = mount_mmc_cb;
280 ret_val = storage_get_primary_sdcard(&id, &path);
281 if (ret_val != STORAGE_ERROR_NONE)
283 //LCOV_EXCL_START System Error
288 ret_val = dbus_handle_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
289 STORAGE_EXT_PATH_MANAGER,
290 STORAGE_EXT_IFACE_MANAGER,
292 g_variant_new("(is)", id, ""),
297 _I("Mount Request %s", ret_val == 0 ? "Success" : "Failed");
299 if (ret_val == -ENOMEM)
300 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
302 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
304 return STORAGE_ERROR_NONE;
307 //LCOV_EXCL_START Not called callback
308 static void unmount_mmc_cb(GVariant *var, void *user_data, GError *err)
310 struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
313 _D("unmount_mmc_cb called");
316 _E("no message [%s]", err->message);
321 g_variant_get(var, "(i)", &mmc_ret);
323 _I("Unmount State : %d", mmc_ret);
327 g_variant_unref(var);
328 (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
332 API int storage_request_unmount_mmc(struct mmc_contents *mmc_data, int option)
334 void (*unmount_cb)(GVariant *, void *, GError *) = NULL;
340 if (option < 0 || option > 1)
341 return STORAGE_ERROR_INVALID_PARAMETER;
343 if (mmc_data && mmc_data->mmc_cb) {
344 _I("Unmount callback exists");
345 unmount_cb = unmount_mmc_cb;
349 ret_val = storage_get_primary_sdcard(&id, &path);
350 if (ret_val != STORAGE_ERROR_NONE)
352 //LCOV_EXCL_START System Error
357 ret_val = dbus_handle_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
358 STORAGE_EXT_PATH_MANAGER,
359 STORAGE_EXT_IFACE_MANAGER,
361 g_variant_new("(ii)", id, option),
366 _I("Unmount Request %s", ret_val == 0 ? "Success" : "Failed");
368 if (ret_val == -ENOMEM)
369 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
371 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
373 return STORAGE_ERROR_NONE;
376 //LCOV_EXCL_START Not called callback
377 static void format_mmc_cb(GVariant *var, void *user_data, GError *err)
379 struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
382 _D("format_mmc_cb called");
385 _E("no message [%s]", err->message);
390 g_variant_get(var, "(i)", &mmc_ret);
392 _I("Format State : %d", mmc_ret);
396 g_variant_unref(var);
397 (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
401 API int storage_request_format_mmc(struct mmc_contents *mmc_data)
403 return storage_format_mmc(mmc_data, 1);
406 API int storage_format_mmc(struct mmc_contents *mmc_data, int option)
408 void (*format_cb)(GVariant *, void *, GError *) = NULL;
414 if (option < 0 || option > 1)
415 return STORAGE_ERROR_INVALID_PARAMETER;
417 if (mmc_data && mmc_data->mmc_cb) {
418 _I("Format callback exists");
419 format_cb = format_mmc_cb;
423 ret_val = storage_get_primary_sdcard(&id, &path);
424 if (ret_val != STORAGE_ERROR_NONE)
426 //LCOV_EXCL_START System Error
431 ret_val = dbus_handle_method_async_with_reply_var(STORAGE_EXT_BUS_NAME,
432 STORAGE_EXT_PATH_MANAGER,
433 STORAGE_EXT_IFACE_MANAGER,
435 g_variant_new("(ii)", id, option),
440 _I("Format Request %s", ret_val == 0 ? "Success" : "Failed");
442 if (ret_val == -ENOMEM)
443 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
445 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
447 return STORAGE_ERROR_NONE;
450 API int storage_is_mounted_opt_usr(storage_part_mount_e *mounted)
452 blkid_cache cache = NULL;
453 blkid_dev_iterate iter;
459 return STORAGE_ERROR_INVALID_PARAMETER;
461 ret_val = blkid_get_cache(&cache, NULL);
463 _E("Failed to get cache"); //LCOV_EXCL_LINE
464 *mounted = STORAGE_PART_ERROR; //LCOV_EXCL_LINE
465 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
468 ret_val = blkid_probe_all(cache);
470 _E("Failed to probe all block devices"); //LCOV_EXCL_LINE
471 *mounted = STORAGE_PART_ERROR; //LCOV_EXCL_LINE
472 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
475 iter = blkid_dev_iterate_begin(cache);
477 _E("Failed to get iterate"); //LCOV_EXCL_LINE
478 *mounted = STORAGE_PART_ERROR; //LCOV_EXCL_LINE
479 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
482 ret_val = blkid_dev_set_search(iter, "LABEL", USER_PARTITION);
483 if (blkid_dev_next(iter, &dev) == 0) {
484 dev = blkid_verify(cache, dev);
487 _D("Partition for user data is found(LABEL=user)");
490 blkid_dev_iterate_end(iter);
493 iter = blkid_dev_iterate_begin(cache);
495 _E("Failed to get iterate"); //LCOV_EXCL_LINE
496 *mounted = STORAGE_PART_ERROR; //LCOV_EXCL_LINE
497 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
500 ret_val = blkid_dev_set_search(iter, "PARTLABEL", USER_PARTITION);
501 if (blkid_dev_next(iter, &dev) == 0) {
502 dev = blkid_verify(cache, dev);
505 _D("Partition for user data is found(PARTLABEL=user)");
508 blkid_dev_iterate_end(iter);
511 blkid_put_cache(cache);
514 ret_val = mount_check(tzplatform_getenv(TZ_SYS_USER));
516 *mounted = STORAGE_PART_MOUNTED;
518 *mounted = STORAGE_PART_NOT_MOUNTED;
520 *mounted = STORAGE_PART_NOT_SUPPORTED;
522 return STORAGE_ERROR_NONE;