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/libgdbus.h>
27 #include <libsyscommon/common.h>
31 #include "storage-internal.h"
32 #include "storage-external-dbus.h"
34 #define FORMAT_TIMEOUT (120*1000)
35 #define USER_PARTITION "user"
36 #define CONTAINER_USER_PARTITION "contain-user"
39 Get compat path from origin Multi-user path
40 from TZ_USER_CONTENT/.. to /opt/usr/media/..
41 Input should be normalized path like /opt/usr/home/owner/media (TODO: internal normalization)
43 Why this API should be provided?
44 In multi-user environment, each user has own compat content direcotry.(/opt/usr/media)
45 However, although system daemon operates real path,
46 system daemon needs to provide compat path to App if the real path is converted.
49 #include <storage-internal.h>
52 if(storage_get_compat_internal_path(src, sizeof(dest), dest) < 0)
53 // cannot convert. use src path
55 // can convert. use dest path
57 //LCOV_EXCL_START Untested function
58 API int storage_get_compat_internal_path(const char* origin, int len, char* compat)
64 if (!compat || !origin) {
65 _E("Invalid parameter");
69 if (getuid() <= USER_UID_START) {
70 //LCOV_EXCL_START System Error
71 _E("Only apps and user session daemons are allowed "
72 "to use storage_get_compat_internal_path()");
77 // this API works on place where compat path is bind-mounted
78 if (!is_compat_bind_mount()) {
79 //LCOV_EXCL_START System Error
80 _E("No compat bind mount");
85 str = tzplatform_uid_getenv(getuid(), TZ_USER_CONTENT);
86 str_len = strlen(str);
87 if (strncmp(origin, str, str_len) != 0) {
88 _E("Failed to match TZ_USER_CONTENT");
92 r = snprintf(compat, len, "%s%s", COMPAT_DIR, origin + str_len);
94 //LCOV_EXCL_START System Error
95 _E("Failed to create new path");
105 Get Multi-user path from compat path
106 from /opt/usr/media/.. to TZ_USER_CONTENT/..
107 Input should be normalized path like /opt/usr/media (TODO: internal normalization)
109 Why this API should be provided?
110 In multi-user environment, each user has own compat content direcotry.(/opt/usr/media)
111 However, although some APIs send the compat path to system daemon,
112 system daemon should access real path.
115 #include <storage-internal.h>
118 if(storage_get_origin_internal_path(src, sizeof(dest), dest) < 0)
119 // cannot convert. use src path
121 // can convert. use dest path
123 API int storage_get_origin_internal_path(const char* compat, int len, char* origin)
128 if (!compat || !origin) {
129 _E("Invalid parameter");
133 if (getuid() <= USER_UID_START) {
134 //LCOV_EXCL_START System Error
135 _E("Only apps and user session daemons are allowed "
136 "to use storage_get_origin_internal_path()");
141 // this API works on place where compat path is bind-mounted
142 if (!is_compat_bind_mount()) {
143 //LCOV_EXCL_START System Error
144 _E("no compat bind mount");
149 compat_len = strlen(COMPAT_DIR);
150 if (strncmp(compat, COMPAT_DIR, compat_len) != 0) {
151 _E("failed to match COMPAT_DIR");
155 r = snprintf(origin, len, "%s%s", tzplatform_uid_getenv(getuid(), TZ_USER_CONTENT), compat + compat_len);
157 //LCOV_EXCL_START System Error
158 _E("failed to create new path");
166 API int storage_get_primary_sdcard(int *storage_id, char **path)
170 char *reply_mount_point = NULL;
173 if (!storage_id || !path)
174 return STORAGE_ERROR_INVALID_PARAMETER;
176 if (!storage_ext_is_supported())
177 return STORAGE_ERROR_NOT_SUPPORTED;
179 dbus_handle_h dbus_handle = gdbus_get_connection(G_BUS_TYPE_SYSTEM, true);
180 if (dbus_handle == NULL) {
181 //LCOV_EXCL_START Dbus error
182 _E("Failed to get dbus connection");
183 return STORAGE_ERROR_OPERATION_FAILED;
187 ret_dbus = gdbus_priv_call_sync_with_reply(dbus_handle,
188 STORAGE_EXT_BUS_NAME,
189 STORAGE_EXT_PATH_MANAGER,
190 STORAGE_EXT_IFACE_MANAGER,
195 gdbus_free_connection(dbus_handle);
198 //LCOV_EXCL_START System Error
199 _E("Failed to get primary sdcard partition"); //LCOV_EXCL_LINE
200 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
204 if (!g_variant_get_safe(reply, "(issssssisibii)",
208 NULL, &reply_mount_point,
211 //LCOV_EXCL_START Dbus error
212 g_variant_unref(reply);
213 return STORAGE_ERROR_OPERATION_FAILED;
217 g_variant_unref(reply);
220 ret = STORAGE_ERROR_NO_DEVICE;
224 *path = strdup(reply_mount_point);
226 ret = STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
227 goto out; //LCOV_EXCL_LINE System Error
230 *storage_id = reply_id;
232 ret = STORAGE_ERROR_NONE;
234 g_free(reply_mount_point);
239 //LCOV_EXCL_START Internal API
240 API int storage_get_storage_level(const char *path, char **level)
245 return STORAGE_ERROR_INVALID_PARAMETER;
247 ret_level = storage_ext_get_storage_level(path, level);
248 if (ret_level == -ENOMEM)
249 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
250 else if (ret_level == -EINVAL)
251 return STORAGE_ERROR_INVALID_PARAMETER;
252 else if (ret_level < 0)
253 return STORAGE_ERROR_OPERATION_FAILED;
255 return STORAGE_ERROR_NONE;
257 //LCOV_EXCL_STOP Internal API
259 //LCOV_EXCL_START Not called callback
260 static void mount_mmc_cb(GVariant *var, void *user_data, GError *err)
262 struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
265 _D("mount_mmc_cb called");
268 _E("no message [%s]", err->message);
273 g_variant_get(var, "(i)", &mmc_ret);
275 _I("Mount State : %d", mmc_ret);
279 g_variant_unref(var);
280 (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
284 //LCOV_EXCL_START Internal API
285 API int storage_request_mount_mmc(struct mmc_contents *mmc_data)
287 void (*mount_cb)(GVariant *, void *, GError *) = NULL;
293 if (mmc_data && mmc_data->mmc_cb) {
294 _I("Mount callback exists");
295 mount_cb = mount_mmc_cb;
299 ret_val = storage_get_primary_sdcard(&id, &path);
300 if (ret_val != STORAGE_ERROR_NONE)
305 ret_val = gdbus_call_async_with_reply(STORAGE_EXT_BUS_NAME,
306 STORAGE_EXT_PATH_MANAGER,
307 STORAGE_EXT_IFACE_MANAGER,
309 g_variant_new("(is)", id, ""),
314 _I("Mount Request %s", ret_val == 0 ? "Success" : "Failed");
316 if (ret_val == -ENOMEM)
317 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
319 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
321 return STORAGE_ERROR_NONE;
323 //LCOV_EXCL_STOP Internal API
325 //LCOV_EXCL_START Not called callback
326 static void unmount_mmc_cb(GVariant *var, void *user_data, GError *err)
328 struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
331 _D("unmount_mmc_cb called");
334 _E("no message [%s]", err->message);
339 g_variant_get(var, "(i)", &mmc_ret);
341 _I("Unmount State : %d", mmc_ret);
345 g_variant_unref(var);
346 (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
350 //LCOV_EXCL_START Internal API
351 API int storage_request_unmount_mmc(struct mmc_contents *mmc_data, int option)
353 void (*unmount_cb)(GVariant *, void *, GError *) = NULL;
359 if (option < 0 || option > 1)
360 return STORAGE_ERROR_INVALID_PARAMETER;
362 if (mmc_data && mmc_data->mmc_cb) {
363 _I("Unmount callback exists");
364 unmount_cb = unmount_mmc_cb;
368 ret_val = storage_get_primary_sdcard(&id, &path);
369 if (ret_val != STORAGE_ERROR_NONE)
374 ret_val = gdbus_call_async_with_reply(STORAGE_EXT_BUS_NAME,
375 STORAGE_EXT_PATH_MANAGER,
376 STORAGE_EXT_IFACE_MANAGER,
378 g_variant_new("(ii)", id, option),
383 _I("Unmount Request %s", ret_val == 0 ? "Success" : "Failed");
385 if (ret_val == -ENOMEM)
386 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
388 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
390 return STORAGE_ERROR_NONE;
394 //LCOV_EXCL_START Not called callback
395 static void format_mmc_cb(GVariant *var, void *user_data, GError *err)
397 struct mmc_contents *mmc_data = (struct mmc_contents*)user_data;
400 _D("format_mmc_cb called");
403 _E("no message [%s]", err->message);
408 g_variant_get(var, "(i)", &mmc_ret);
410 _I("Format State : %d", mmc_ret);
414 g_variant_unref(var);
415 (mmc_data->mmc_cb)(mmc_ret, mmc_data->user_data);
419 //LCOV_EXCL_START Internal API
420 API int storage_request_format_mmc(struct mmc_contents *mmc_data)
422 return storage_format_mmc(mmc_data, 1);
426 //LCOV_EXCL_START Internal API
427 API int storage_format_mmc(struct mmc_contents *mmc_data, int option)
429 void (*format_cb)(GVariant *, void *, GError *) = NULL;
435 if (option < 0 || option > 1)
436 return STORAGE_ERROR_INVALID_PARAMETER;
438 if (mmc_data && mmc_data->mmc_cb) {
439 _I("Format callback exists");
440 format_cb = format_mmc_cb;
444 ret_val = storage_get_primary_sdcard(&id, &path);
445 if (ret_val != STORAGE_ERROR_NONE)
450 ret_val = gdbus_call_async_with_reply(STORAGE_EXT_BUS_NAME,
451 STORAGE_EXT_PATH_MANAGER,
452 STORAGE_EXT_IFACE_MANAGER,
454 g_variant_new("(ii)", id, option),
459 _I("Format Request %s", ret_val == 0 ? "Success" : "Failed");
461 if (ret_val == -ENOMEM)
462 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE System Error
464 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
466 return STORAGE_ERROR_NONE;
470 //LCOV_EXCL_START Internal API
471 API int storage_is_mounted_opt_usr(storage_part_mount_e *mounted)
473 blkid_cache cache = NULL;
474 blkid_dev_iterate iter;
478 char *user_label = syscommon_is_container()? CONTAINER_USER_PARTITION: USER_PARTITION;
481 return STORAGE_ERROR_INVALID_PARAMETER;
483 _D("Find user partition label: %s", user_label);
484 ret_val = blkid_get_cache(&cache, NULL);
486 _E("Failed to get cache"); //LCOV_EXCL_LINE
487 *mounted = STORAGE_PART_ERROR; //LCOV_EXCL_LINE
488 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
491 ret_val = blkid_probe_all(cache);
493 _E("Failed to probe all block devices"); //LCOV_EXCL_LINE
494 *mounted = STORAGE_PART_ERROR; //LCOV_EXCL_LINE
495 return STORAGE_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
498 iter = blkid_dev_iterate_begin(cache);
500 _E("Failed to get iterate"); //LCOV_EXCL_LINE
501 *mounted = STORAGE_PART_ERROR; //LCOV_EXCL_LINE
502 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
505 ret_val = blkid_dev_set_search(iter, "LABEL", user_label);
506 if (blkid_dev_next(iter, &dev) == 0) {
507 dev = blkid_verify(cache, dev);
510 _D("Partition for user data is found(LABEL=%s)", user_label);
513 blkid_dev_iterate_end(iter);
516 iter = blkid_dev_iterate_begin(cache);
518 _E("Failed to get iterate"); //LCOV_EXCL_LINE
519 *mounted = STORAGE_PART_ERROR; //LCOV_EXCL_LINE
520 return STORAGE_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
523 ret_val = blkid_dev_set_search(iter, "PARTLABEL", user_label);
524 if (blkid_dev_next(iter, &dev) == 0) {
525 dev = blkid_verify(cache, dev);
528 _D("Partition for user data is found(PARTLABEL=%s)", user_label);
531 blkid_dev_iterate_end(iter);
534 blkid_put_cache(cache);
537 ret_val = mount_check(tzplatform_getenv(TZ_SYS_USER));
539 *mounted = STORAGE_PART_MOUNTED;
541 *mounted = STORAGE_PART_NOT_MOUNTED;
543 *mounted = STORAGE_PART_NOT_SUPPORTED;
545 return STORAGE_ERROR_NONE;