4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Garima Shrivastava<garima.s@samsung.com>
7 * Jyotsna Dhumale <jyotsna.a@samsung.com>
8 * Venkatesha Sarpangala <sarpangala.v@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
29 #include "app2sd_internals.h"
31 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
32 #define DMCRYPT_ITER_TIME 50
33 #define DMCRYPT_KEY_LEN 128
36 static int _app2sd_make_directory(const char *path, uid_t uid)
40 mode_t mode = DIR_PERMS;
42 struct passwd *pwd_result;
43 char buf[1024] = { 0, };
45 ret = _app2sd_delete_directory(path);
47 _E("unable to delete (%s), errno(%d)", path, errno);
48 return APP2EXT_ERROR_DELETE_DIRECTORY;
51 ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pwd_result);
52 if (ret != 0 || pwd_result == NULL) {
53 _E("get uid failed(%d)", ret);
54 return APP2EXT_ERROR_ACCESS_FILE;
56 _D("uid(%d), gid(%d)", uid, pwd.pw_gid);
58 /* create directory */
59 ret = mkdir(path, mode);
61 if (errno != EEXIST) {
62 _E("create directory failed," \
63 " error no is (%d)", errno);
64 return APP2EXT_ERROR_CREATE_DIRECTORY;
68 fd = open(path, O_RDONLY|O_DIRECTORY);
70 _E("can't open path(%s)", path);
71 return APP2EXT_ERROR_OPEN_DIR;
74 ret = fchmod(fd, 0755);
76 _E("change file permission error");
78 return APP2EXT_ERROR_ACCESS_FILE;
81 ret = fchown(fd, uid, pwd.pw_gid);
83 _E("change file owner error");
85 return APP2EXT_ERROR_ACCESS_FILE;
90 return APP2EXT_SUCCESS;
93 char *_app2sd_find_associated_device_node(const char *loopback_device)
95 char *ret_result = NULL;
98 char dev[FILENAME_MAX] = { 0, };
101 result = (char *)_app2sd_find_associated_device(loopback_device);
102 if (result == NULL) {
103 _D("there is no the associated file (%s)", loopback_device);
107 /* process the string*/
108 snprintf(dev, sizeof(dev), "%s", result);
110 if (strstr(dev, "dev") == NULL) {
111 _E("unable to find the associated file");
115 char *saveptr = NULL;
116 ret_result = strtok_r(dev, delims, &saveptr);
118 devnode = strdup(ret_result);
126 char *_app2sd_create_loopdevice_node(void)
128 char *ret_result = NULL;
129 mode_t mode = DIR_PERMS;
131 int ret = APP2EXT_SUCCESS;
135 result = (char *)_app2sd_find_free_device();
136 _D("find_free_device(%s)", result);
138 /* validate the result */
139 if (result == NULL || strstr(result, "/dev") == NULL) {
140 _D("no device found, creating device node");
147 char dev_path[BUF_SIZE] = { 0, };
148 snprintf(dev_path, sizeof(dev_path), "/dev/loop%d", count);
149 while ((fp = fopen(dev_path, "r+")) != NULL) {
151 snprintf(dev_path, sizeof(dev_path), "/dev/loop%d", count);
152 _D("next dev path for checking is (%s)",
156 _D("device node candidate is (%s)", dev_path);
158 dev_node = makedev(DEV_MAJOR, count);
159 ret = mknod(dev_path, S_IFBLK | mode, dev_node);
161 _E("error while creating the device node: errno is (%d)",
165 ret_result = (char *)malloc(strlen(dev_path) + 1);
166 if (ret_result == NULL) {
167 _E("unable to allocate memory");
170 memset(ret_result, '\0', strlen(dev_path) + 1);
171 memcpy(ret_result, dev_path, strlen(dev_path));
173 ret_result = (char *)malloc(strlen(result) + 1);
174 if (ret_result == NULL) {
180 memset(ret_result, '\0', strlen(result) + 1);
181 if (strlen(result) > 0)
182 memcpy(ret_result, result, strlen(result) - 1);
191 char *_app2sd_do_loopback_encryption_setup(const char *pkgid,
192 const char *loopback_device, uid_t uid)
194 int ret = APP2EXT_SUCCESS;
197 char *device_node = NULL;
200 _E("invalid argument");
204 /* get password for loopback encryption */
205 ret = _app2sd_initialize_db();
207 _E("app2sd db initialize failed");
211 if ((passwd = _app2sd_get_password_from_db(pkgid, uid)) == NULL) {
212 passwd = (char *)_app2sd_generate_password();
213 if (NULL == passwd) {
214 _E("unable to generate password");
217 if ((ret = _app2sd_set_info_in_db(pkgid,
218 passwd, loopback_device, uid)) < 0) {
219 _E("unable to save info");
227 /* get free device node*/
228 device_node = _app2sd_create_loopdevice_node();
229 if (NULL == device_node) {
232 _E("unable to find free loopback node");
236 _D("device_node (%s)", device_node);
238 result = (char *)_app2sd_encrypt_device(device_node,
239 loopback_device, passwd);
240 if (result == NULL) {
241 _E("encryption failed");
246 _D("result (%s)", result);
255 char *_app2sd_do_loopback_duplicate_encryption_setup(const char *pkgid,
256 const char *temp_pkgid, const char *temp_loopback_device,
257 char *passwd, uid_t uid)
260 char *device_node = NULL;
262 if (pkgid == NULL || temp_pkgid == NULL ||
263 temp_loopback_device == NULL || passwd == NULL) {
264 _E("invalid argument");
268 /* get free device node*/
269 device_node = _app2sd_create_loopdevice_node();
270 if (NULL == device_node) {
271 _E("unable to find free loopback node");
274 result = (char *)_app2sd_encrypt_device(device_node,
275 temp_loopback_device, passwd);
276 if (result == NULL) {
277 _E("encryption failed");
280 if (strlen(result) == 0) {
285 _E("error is (%s)", result);
295 int _app2sd_remove_loopback_encryption_setup(const char *loopback_device)
297 int ret = APP2EXT_SUCCESS;
299 char *dev_node = NULL;
301 if ((dev_node = _app2sd_find_associated_device_node(loopback_device))
303 _E("Unable to find the association");
304 ret = APP2EXT_ERROR_FIND_ASSOCIATED_DEVICE_NODE;
307 result = (char *)_app2sd_detach_loop_device(dev_node);
308 if (result == NULL) {
309 _E("error in detaching");
310 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
324 int _app2sd_remove_all_loopback_encryption_setups(const char *loopback_device)
326 int ret = APP2EXT_SUCCESS;
328 char *dev_node = NULL;
331 _app2sd_find_associated_device_node(loopback_device))
333 _E("finish to find the association");
334 ret = APP2EXT_SUCCESS;
338 _D("find node (%s)", dev_node);
340 result = (char *)_app2sd_detach_loop_device(dev_node);
341 if (result == NULL) {
342 _E("error in detaching");
343 ret = APP2EXT_ERROR_DETACH_LOOPBACK_DEVICE;
358 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
359 int _app2sd_dmcrypt_setup_device(const char *pkgid,
360 const char *loopback_device, bool is_dup, uid_t uid)
362 int ret = APP2EXT_SUCCESS;
364 char dmcrypt_setup_cmd[BUF_SIZE] = { 0, };
365 char err_buf[BUF_SIZE] = { 0, };
367 if (pkgid == NULL || loopback_device == NULL) {
368 _E("invalid argument");
369 return APP2EXT_ERROR_INVALID_ARGUMENTS;
372 /* get password for dmcrypt encryption */
373 ret = _app2sd_initialize_db();
375 _E("app2sd db initialize failed");
376 return APP2EXT_ERROR_DB_INITIALIZE;
379 passwd = _app2sd_get_password_from_db(pkgid, uid);
380 if (passwd == NULL) {
382 _E("no password found for (%s)", pkgid);
383 return APP2EXT_ERROR_SQLITE_REGISTRY;
385 passwd = (char *)_app2sd_generate_password();
386 if (NULL == passwd) {
387 _E("unable to generate password\n");
388 return APP2EXT_ERROR_PASSWD_GENERATION;
390 if ((ret = _app2sd_set_info_in_db(pkgid, passwd,
391 loopback_device, uid)) < 0) {
392 _E("unable to save password");
395 return APP2EXT_ERROR_SQLITE_REGISTRY;
400 snprintf(dmcrypt_setup_cmd, sizeof(dmcrypt_setup_cmd),
401 "/bin/echo '%s' | /sbin/cryptsetup -q -i %d " \
402 "-c aes-cbc-lmk -s %d --align-payload=8 luksFormat %s",
403 passwd, DMCRYPT_ITER_TIME, DMCRYPT_KEY_LEN, loopback_device);
405 ret = system(dmcrypt_setup_cmd);
407 strerror_r(errno, err_buf, sizeof(err_buf));
408 _E("Error setting up dmcrypt on app2sd file, " \
409 "error(%s), ret(%d)", err_buf, ret);
414 return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
425 int _app2sd_dmcrypt_open_device(const char *pkgid, const char *loopback_device,
426 bool is_dup, uid_t uid, char **dev_node)
428 int ret = APP2EXT_SUCCESS;
430 char dmcrypt_open_cmd[BUF_SIZE] = { 0, };
431 char dev_name[BUF_SIZE] = { 0, };
432 char buf[BUF_SIZE] = { 0, };
435 if (pkgid == NULL || loopback_device == NULL) {
436 _E("invalid argument");
437 return APP2EXT_ERROR_INVALID_ARGUMENTS;
441 snprintf(dev_name, sizeof(dev_name), "%s.new_%d", pkgid, uid);
443 snprintf(dev_name, sizeof(dev_name), "%s_%d", pkgid, uid);
445 /* get password for dmcrypt encryption */
446 ret = _app2sd_initialize_db();
448 _E("app2sd db initialize failed");
449 return APP2EXT_ERROR_DB_INITIALIZE;
452 passwd = _app2sd_get_password_from_db(pkgid, uid);
453 if (passwd == NULL) {
454 _E("no password found for [%s]", pkgid);
455 return APP2EXT_ERROR_SQLITE_REGISTRY;
458 if (_app2sd_check_is_luks_device(loopback_device) == 0) {
459 _W("legacy image format!");
460 snprintf(dmcrypt_open_cmd, sizeof(dmcrypt_open_cmd),
461 "/bin/echo '%s' | /sbin/cryptsetup " \
462 "-M plain -c aes-cbc-plain -h plain open %s %s",
463 passwd, loopback_device, dev_name);
465 snprintf(dmcrypt_open_cmd, sizeof(dmcrypt_open_cmd),
466 "/bin/echo '%s' | /sbin/cryptsetup -q luksOpen %s %s",
467 passwd, loopback_device, dev_name);
471 ret = system(dmcrypt_open_cmd);
473 strerror_r(errno, buf, sizeof(buf));
474 _E("error opening dmcrypt device, error: [%s]", buf);
475 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
478 snprintf(buf, sizeof(buf), "/dev/mapper/%s", dev_name);
480 *dev_node = (char *)calloc(len + 1, sizeof(char));
481 if (*dev_node == NULL) {
482 _E("memory alloc failed");
483 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
485 snprintf(*dev_node, len + 1, "%s", buf);
490 int _app2sd_dmcrypt_close_device(const char *pkgid, uid_t uid)
492 int ret = APP2EXT_SUCCESS;
493 char dev_node[BUF_SIZE] = { '\0' };
494 char dmcrypt_close_cmd[BUF_SIZE] = { '\0' };
495 char err_buf[BUF_SIZE] = { '\0' };
496 char *t_dev_node = NULL;
499 _E("invalid argument\n");
500 return APP2EXT_ERROR_INVALID_ARGUMENTS;
503 t_dev_node = _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
505 _W("no associated device node(%s_%d) found", pkgid, uid);
506 return APP2EXT_ERROR_DMCRYPT_DEVICE_UNAVAILABLE;
512 snprintf(dev_node, sizeof(dev_node), "/dev/mapper/%s_%d", pkgid, uid);
513 snprintf(dmcrypt_close_cmd, sizeof(dmcrypt_close_cmd),
514 "/sbin/cryptsetup -q luksClose %s", dev_node);
515 ret = system(dmcrypt_close_cmd);
517 strerror_r(errno, err_buf, sizeof(err_buf));
518 _E("error closing dmcrypt on app2sd file,"\
519 " error: [%s]", err_buf);
520 return APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
526 char *_app2sd_find_associated_dmcrypt_device_node(const char *pkgid, uid_t uid)
528 char *dev_node = NULL;
529 char buf[BUF_SIZE] = { 0, };
532 snprintf(buf, sizeof(buf), "/dev/mapper/%s_%d", pkgid, uid);
534 dev_node = (char *)calloc(len + 1, sizeof(char));
535 if (dev_node == NULL) {
536 _E("memory alloc failed");
539 snprintf(dev_node, len + 1, "%s", buf);
541 if (access(dev_node, F_OK) == 0) {
542 _D("device_node: (%s)", dev_node);
545 _D("can not access dev_node(%s), errno(%d)", dev_node, errno);
553 char *_app2sd_dmcrypt_duplicate_encryption_setup(const char *pkgid,
554 const char *temp_loopback_device, uid_t uid)
556 int ret = APP2EXT_SUCCESS;
557 char *device_node = NULL;
559 if (pkgid == NULL || temp_loopback_device == NULL) {
560 _E("invalid argument\n");
564 ret = _app2sd_dmcrypt_setup_device(pkgid, temp_loopback_device, true, uid);
566 _E("dmcrypt setup device error(%d)", ret);
570 ret = _app2sd_dmcrypt_open_device(pkgid, temp_loopback_device, true,
573 _E("dmcrypt open device error");
581 int _app2sd_create_loopback_device(const char *pkgid,
582 const char *loopback_device, int size)
584 int ret = APP2EXT_SUCCESS;
585 char command[FILENAME_MAX] = { 0, };
586 char buff[BUF_SIZE] = { 0, };
589 if (NULL == pkgid || size <= 0) {
590 _E("invalid argument");
591 return APP2EXT_ERROR_INVALID_ARGUMENTS;
593 snprintf(command, sizeof(command), "of=%s", loopback_device);
594 snprintf(buff, sizeof(buff), "count=%d", size);
596 const char *argv1[] = { "/bin/dd", "if=/dev/zero",
597 command, "bs=1M", buff, NULL };
599 if ((fp = fopen(loopback_device, "r+")) != NULL) {
600 _W("encrypted file already exists (%s)",
603 return APP2EXT_ERROR_PKG_EXISTS;
606 ret = _xsystem(argv1);
608 _E("command (%s) failed, ret(%d), errno(%d)", command, ret, errno);
613 int _app2sd_delete_loopback_device(const char *loopback_device)
615 int ret = APP2EXT_SUCCESS;
617 ret = unlink(loopback_device);
619 if (errno == ENOENT) {
620 _W("unable to access file (%s)", loopback_device);
622 _E("unable to delete (%s)", loopback_device);
623 return APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
627 return APP2EXT_SUCCESS;
630 int _app2sd_create_file_system(const char *device_path)
632 int ret = APP2EXT_SUCCESS;
634 char err_buf[1024] = {0,};
636 if (device_path == NULL) {
638 return APP2EXT_ERROR_INVALID_ARGUMENTS;
641 /* Format the filesystem [create a filesystem]*/
642 const char *argv[] = { "/sbin/mkfs.ext4", device_path, NULL };
643 fp = fopen(device_path, "r+");
645 strerror_r(errno, err_buf, sizeof(err_buf));
646 _E("unable to access (%s) error is (%d, %s)",
647 device_path, errno, err_buf);
648 return APP2EXT_ERROR_ACCESS_FILE;
652 ret = _xsystem(argv);
654 strerror_r(errno, err_buf, sizeof(err_buf));
655 _E("creating file system failed, error is (%s)",
657 return APP2EXT_ERROR_CREATE_FS;
662 static int _app2sd_create_dir_with_link(const char *application_path,
663 const char *pkgid, const char *dir_name, uid_t uid)
665 int ret = APP2EXT_SUCCESS;
666 char app_dir_mmc_path[FILENAME_MAX] = { 0, };
667 char app_dir_path[FILENAME_MAX] = { 0, };
669 snprintf(app_dir_mmc_path, sizeof(app_dir_mmc_path), "%s/.mmc/%s",
670 application_path, dir_name);
671 snprintf(app_dir_path, sizeof(app_dir_path), "%s/%s",
672 application_path, dir_name);
674 ret = _app2sd_make_directory(app_dir_mmc_path, uid);
676 _E("create directory failed");
677 return APP2EXT_ERROR_CREATE_DIRECTORY;
680 if ((ret = symlink(app_dir_mmc_path,
681 app_dir_path)) < 0) {
682 if (errno == EEXIST) {
683 _D("file with symlink name present (%s)",
686 _E("symbolic link creation "
687 "failed, error no is (%d)", errno);
688 return APP2EXT_ERROR_CREATE_SYMLINK;
692 return APP2EXT_SUCCESS;
695 static int _app2sd_create_directory_entry(const char *application_path,
696 const char *pkgid, GList *dir_list, uid_t uid)
698 int ret = APP2EXT_SUCCESS;
700 app2ext_dir_details *dir_detail = NULL;
702 list = g_list_first(dir_list);
704 dir_detail = (app2ext_dir_details *)list->data;
705 if (dir_detail && dir_detail->name
706 && dir_detail->type == APP2EXT_DIR_RO) {
707 ret = _app2sd_create_dir_with_link(application_path,
708 pkgid, dir_detail->name, uid);
712 list = g_list_next(list);
714 return APP2EXT_SUCCESS;
717 int _app2sd_mount_app_content(const char *application_path, const char *pkgid,
718 const char *dev, int mount_type, GList *dir_list,
719 app2sd_cmd cmd, uid_t uid)
721 int ret = APP2EXT_SUCCESS;
723 char app_mmc_path[FILENAME_MAX] = { 0, };
724 char temp_path[FILENAME_MAX] = { 0, };
725 char err_buf[1024] = {0,};
726 struct timespec time = {
728 .tv_nsec = 1000 * 1000 * 200
732 _E("input param is NULL (%s)",
734 return APP2EXT_ERROR_INVALID_ARGUMENTS;
737 /* check directory existence */
738 fd = open(application_path, O_RDONLY|O_DIRECTORY);
740 _E("path(%s) error(%d)", application_path, errno);
741 return APP2EXT_ERROR_OPEN_DIR;
745 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
747 fd = open(app_mmc_path, O_RDONLY|O_DIRECTORY);
749 _E("path(%s) error(%d)", app_mmc_path, errno);
750 return APP2EXT_ERROR_OPEN_DIR;
754 nanosleep(&time, NULL); /* 200ms sleep */
755 _D("give a delay for mount");
757 switch (mount_type) {
759 if ((ret = mount(dev, app_mmc_path, FS_TYPE,
760 MS_MGC_VAL | MS_RDONLY | MS_NOSUID, NULL)) < 0) {
761 _E("read only mount failed, " \
763 "dev is (%s) path is (%s)",
764 errno, dev, app_mmc_path);
765 ret = APP2EXT_ERROR_MOUNT;
769 if ((ret = mount(dev, app_mmc_path, FS_TYPE,
770 MS_MGC_VAL | MS_NOSUID, NULL)) < 0) {
771 _E("read write mount failed, " \
772 "errono is (%d)", errno);
773 ret = APP2EXT_ERROR_MOUNT;
776 case MOUNT_TYPE_RW_NOEXEC:
777 if ((ret = mount(dev, app_mmc_path, FS_TYPE,
778 MS_MGC_VAL | MS_NOEXEC | MS_NOSUID, NULL)) < 0) {
779 _E("rwnx mount failed " \
780 "errono is (%d)", errno);
781 ret = APP2EXT_ERROR_MOUNT;
784 case MOUNT_TYPE_RD_REMOUNT:
785 if ((ret = mount(dev, app_mmc_path, FS_TYPE,
786 MS_MGC_VAL | MS_RDONLY | MS_REMOUNT | MS_NOSUID,
788 _E("read remount failed "
789 "errono is (%d)", errno);
790 ret = APP2EXT_ERROR_MOUNT;
793 case MOUNT_TYPE_RW_REMOUNT:
794 if ((ret = mount(dev, app_mmc_path, FS_TYPE,
795 MS_MGC_VAL | MS_REMOUNT | MS_NOSUID, NULL)) < 0) {
796 _E("read write remount failed "
797 "errono(%d), errstr(%s)", errno,
798 strerror_r(errno, err_buf, sizeof(err_buf)));
799 ret = APP2EXT_ERROR_MOUNT;
803 _E("invalid mount type");
807 if (cmd == APP2SD_PRE_INSTALL || cmd == APP2SD_MOVE_APP_TO_MMC ||
808 cmd == APP2SD_PRE_UPGRADE) {
809 ret = _app2sd_create_directory_entry(application_path,
810 pkgid, dir_list, uid);
813 if (mount_type != MOUNT_TYPE_RD &&
814 mount_type != MOUNT_TYPE_RD_REMOUNT) {
815 /* change lost+found permission */
816 snprintf(temp_path, sizeof(temp_path), "%s/lost+found",
818 ret = _app2sd_make_directory(temp_path, uid);
820 _E("create directory(%s) failed", temp_path);
821 return APP2EXT_ERROR_CREATE_DIRECTORY;
828 int _app2sd_unmount_app_content(const char *application_path)
830 int ret = APP2EXT_SUCCESS;
831 char app_mmc_path[FILENAME_MAX] = { 0, };
832 char err_buf[1024] = {0,};
834 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
836 if ((ret = umount(app_mmc_path)) < 0) {
837 strerror_r(errno, err_buf, sizeof(err_buf));
838 _D("unable to umount the dir, ret(%d) error(%d, %s)",
839 ret, errno, err_buf);
845 static int _app2sd_move_to_archive(const char *src_path, const char *arch_path)
847 int ret = APP2EXT_SUCCESS;
849 ret = _app2sd_copy_dir(src_path, arch_path);
850 if (ret && ret != APP2EXT_ERROR_ACCESS_FILE) {
851 char err_buf[1024] = {0,};
852 strerror_r(errno, err_buf, sizeof(err_buf));
853 _E("unable to copy from (%s) to (%s), err is (%s)",
854 src_path, arch_path, err_buf);
855 return APP2EXT_ERROR_MOVE;
858 ret = _app2sd_delete_directory((char *)src_path);
860 _E("unable to delete (%s)", src_path);
861 return APP2EXT_ERROR_DELETE_DIRECTORY;
867 static int _app2sd_move_app_to_external(const char *pkgid, GList *dir_list,
868 uid_t uid, char *mmc_path, char **image_path)
870 int ret = APP2EXT_SUCCESS;
871 mode_t mode = DIR_PERMS;
872 char temp_dir_path[FILENAME_MAX] = { 0, };
873 char app_mmc_path[FILENAME_MAX] = { 0, };
874 char app_archive_path[FILENAME_MAX] = { 0, };
875 char application_path[FILENAME_MAX] = { 0, };
876 char loopback_device[FILENAME_MAX] = { 0, };
877 unsigned long long total_size = 0;
879 int reqd_disk_size = 0;
880 char *device_node = NULL;
881 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
884 int free_mmc_mem = 0;
887 app2ext_dir_details *dir_detail = NULL;
888 char err_buf[1024] = { 0,};
889 char *encoded_id = NULL;
891 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
892 if (encoded_id == NULL)
893 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
895 snprintf(loopback_device, sizeof(loopback_device), "%s/%s/%s",
896 mmc_path, EXTIMG_DIR, encoded_id);
898 _app2sd_set_application_path(pkgid, uid, application_path,
899 sizeof(application_path));
901 /* check whether application is in external memory or not */
902 fp = fopen(loopback_device, "r+");
904 _W("Already %s entry is present in the SD Card, " \
905 "delete entry and go on without return", pkgid);
907 _app2sd_force_clean(pkgid, application_path, loopback_device, uid);
910 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
912 snprintf(app_archive_path, sizeof(app_archive_path), "%s/.archive",
915 ret = mkdir(app_mmc_path, mode);
917 if (errno != EEXIST) {
918 _E("unable to create directory for archiving," \
919 " error(%d)", errno);
920 return APP2EXT_ERROR_CREATE_DIRECTORY;
924 ret = mkdir(app_archive_path, mode);
926 if (errno != EEXIST) {
927 _E("unable to create directory for archiving," \
928 " error(%d)", errno);
929 return APP2EXT_ERROR_CREATE_DIRECTORY;
933 list = g_list_first(dir_list);
935 dir_detail = (app2ext_dir_details *)list->data;
936 if (dir_detail && dir_detail->name
937 && dir_detail->type == APP2EXT_DIR_RO) {
938 memset(temp_dir_path, '\0', sizeof(temp_dir_path));
939 snprintf(temp_dir_path, sizeof(temp_dir_path),
940 "%s/%s", application_path,
942 _D("cal size of app dirs, temp_dir_path(%s)",
945 _app2sd_calculate_dir_size(temp_dir_path);
947 list = g_list_next(list);
950 reqd_size = ((total_size) / (1024 * 1024)) + 2;
951 reqd_disk_size = reqd_size + ceil(reqd_size * 0.2);
953 /* find avialable free memory in the MMC card */
954 ret = _app2sd_get_available_free_memory(mmc_path, &free_mmc_mem);
956 _E("unable to get available free memory in MMC (%d)", ret);
957 return APP2EXT_ERROR_MMC_STATUS;
959 /* if avaialalbe free memory in MMC is less than
960 * required size + 5MB, return error
962 if (reqd_disk_size > free_mmc_mem) {
963 _E("insufficient memory in MMC for application installation (%d)",
965 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
967 /* create a loopback device */
968 ret = _app2sd_create_loopback_device(pkgid, loopback_device,
969 (reqd_disk_size + PKG_BUF_SIZE));
971 _E("loopback node creation failed");
975 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
976 ret = _app2sd_dmcrypt_setup_device(pkgid, loopback_device, false, uid);
978 _E("dmcrypt setup device error(%d)", ret);
979 return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
982 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device, false,
985 _E("dmcrypt open device error");
986 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
989 /* perform loopback encryption setup */
990 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
991 loopback_device, uid);
993 _E("loopback encryption setup failed");
994 return APP2EXT_ERROR_DO_LOSETUP;
996 _D("device_node (%s)", device_node);
997 /* check whether loopback device is associated with device node or not */
998 devi = _app2sd_find_associated_device_node(loopback_device);
1000 _E("finding associated device node failed");
1001 ret = APP2EXT_ERROR_DO_LOSETUP;
1008 /* format the loopback file system */
1009 ret = _app2sd_create_file_system(device_node);
1011 _E("create ext4 filesystem failed");
1012 ret = APP2EXT_ERROR_CREATE_FS;
1016 list = g_list_first(dir_list);
1018 dir_detail = (app2ext_dir_details *)list->data;
1019 if (dir_detail && dir_detail->name
1020 && dir_detail->type == APP2EXT_DIR_RO) {
1021 memset(temp_dir_path, '\0', FILENAME_MAX);
1022 snprintf(temp_dir_path, sizeof(temp_dir_path),
1023 "%s/%s", application_path,
1025 _D("app2archive, temp_dir_path(%s)",
1027 ret = _app2sd_move_to_archive(temp_dir_path,
1030 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1031 _E("unable to access (%s)",
1034 _E("unable to copy from (%s) to (%s)",
1041 list = g_list_next(list);
1044 /* mount the loopback encrypted pseudo device on application installation path
1045 * as with Read Write permission
1047 ret = _app2sd_mount_app_content(application_path, pkgid, device_node,
1048 MOUNT_TYPE_RW, dir_list, APP2SD_MOVE_APP_TO_MMC, uid);
1054 list = g_list_first(dir_list);
1056 dir_detail = (app2ext_dir_details *)list->data;
1057 if (dir_detail && dir_detail->name
1058 && dir_detail->type == APP2EXT_DIR_RO) {
1059 memset(temp_dir_path, '\0', sizeof(temp_dir_path));
1060 snprintf(temp_dir_path, sizeof(temp_dir_path),
1061 "%s/%s", app_archive_path,
1063 _D("archive2mmc, temp_dir_path(%s)",
1065 ret = _app2sd_copy_dir(temp_dir_path,
1068 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1069 _E("unable to access (%s)",
1073 err_buf, sizeof(err_buf));
1074 _E("unable to copy from (%s) to (%s)," \
1077 app_mmc_path, err_buf);
1081 ret = _app2sd_delete_directory(temp_dir_path);
1083 _E("unable to delete (%s)", temp_dir_path);
1087 list = g_list_next(list);
1090 ret = _app2sd_delete_directory(app_archive_path);
1092 _E("unable to delete (%s)", app_archive_path);
1093 ret = APP2EXT_ERROR_DELETE_DIRECTORY;
1097 *image_path = strdup(loopback_device);
1098 return APP2EXT_SUCCESS;
1110 static int _app2sd_move_app_to_internal(const char *pkgid, GList *dir_list,
1111 uid_t uid, char *mmc_path)
1113 int ret = APP2EXT_SUCCESS;
1114 mode_t mode = DIR_PERMS;
1115 char temp_dir_path[FILENAME_MAX] = { 0, };
1116 char app_mmc_path[FILENAME_MAX] = { 0, };
1117 char app_archive_path[FILENAME_MAX] = { 0, };
1118 char application_path[FILENAME_MAX] = { 0, };
1119 char loopback_device[FILENAME_MAX] = { 0, };
1120 char *device_node = NULL;
1123 app2ext_dir_details *dir_detail = NULL;
1125 int free_internal_mem = 0;
1126 unsigned long long temp = 0;
1127 char err_buf[1024] = {0,};
1128 char *encoded_id = NULL;
1130 encoded_id = _app2sd_get_encoded_name(pkgid, uid);
1131 if (encoded_id == NULL)
1132 return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
1134 snprintf(loopback_device, sizeof(loopback_device), "%s/%s/%s",
1135 mmc_path, EXTIMG_DIR, encoded_id);
1137 _app2sd_set_application_path(pkgid, uid, application_path,
1138 sizeof(application_path));
1140 /* check whether application is in external memory or not */
1141 fp = fopen(loopback_device, "r+");
1143 _E("application (%s) is not installed on SD Card",
1145 return APP2EXT_ERROR_FILE_ABSENT;
1151 /* find avialable free memory in the internal storage */
1152 ret = _app2sd_get_available_free_memory(INTERNAL_STORAGE_PATH,
1153 &free_internal_mem);
1155 _E("unable to get available free memory in internal (%d)",
1157 return APP2EXT_ERROR_MMC_STATUS;
1160 fp = fopen(loopback_device, "r+");
1162 _E("app entry is not present in SD card");
1163 return APP2EXT_ERROR_INVALID_PACKAGE;
1167 /* get installed app size*/
1168 temp = _app2sd_calculate_file_size(loopback_device);
1169 reqd_size = (int)((temp) / (1024 * 1024));
1170 _D("reqd size is (%d)", reqd_size);
1172 if (reqd_size == 0) {
1173 _E("app entry is not present in SD Card");
1174 return APP2EXT_ERROR_LOOPBACK_DEVICE_UNAVAILABLE;
1177 _I("reqd size: (%d)MB, free internal mem: (%d)MB",
1178 reqd_size, free_internal_mem);
1180 /* if avaialalbe free memory in internal storage is
1181 * less than required size, return error
1183 if (reqd_size > free_internal_mem) {
1184 _E("innsufficient memory in internal storage" \
1185 " for application installation (%d)", ret);
1186 return APP2EXT_ERROR_MMC_INSUFFICIENT_MEMORY;
1189 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1191 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1193 device_node = _app2sd_find_associated_device_node(loopback_device);
1195 if (NULL == device_node) {
1196 /* do loopback setup */
1197 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1198 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1199 false, uid, &device_node);
1201 _E("dmcrypt open device error(%d)", ret);
1202 return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1205 device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1206 loopback_device, uid);
1207 if (device_node == NULL) {
1208 _E("loopback encryption setup failed");
1209 return APP2EXT_ERROR_DO_LOSETUP;
1213 ret = _app2sd_mount_app_content(application_path,
1214 pkgid, device_node, MOUNT_TYPE_RW,
1215 dir_list, APP2SD_MOVE_APP_TO_PHONE, uid);
1218 ret = APP2EXT_ERROR_MOUNT_PATH;
1222 /* do re-mounting */
1223 ret = _app2sd_mount_app_content(application_path,
1224 pkgid, device_node, MOUNT_TYPE_RW_REMOUNT,
1225 dir_list, APP2SD_MOVE_APP_TO_PHONE, uid);
1227 _E("re-mount failed");
1228 ret = APP2EXT_ERROR_MOUNT_PATH;
1233 snprintf(app_mmc_path, sizeof(app_mmc_path), "%s/.mmc",
1235 snprintf(app_archive_path, sizeof(app_archive_path), "%s/.archive",
1238 ret = mkdir(app_archive_path, mode);
1240 if (errno != EEXIST) {
1241 _E("unable to create directory for archiving," \
1242 " error(%d)", errno);
1243 ret = APP2EXT_ERROR_CREATE_DIRECTORY;
1248 list = g_list_first(dir_list);
1250 dir_detail = (app2ext_dir_details *)list->data;
1251 if (dir_detail && dir_detail->name
1252 && dir_detail->type == APP2EXT_DIR_RO) {
1253 /* archiving code */
1254 memset(temp_dir_path, '\0', sizeof(temp_dir_path));
1255 snprintf(temp_dir_path, sizeof(temp_dir_path),
1256 "%s/%s", app_mmc_path,
1258 _D("mmc2archive, temp_dir_path(%s)", temp_dir_path);
1259 ret = _app2sd_copy_dir(temp_dir_path,
1262 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1263 _E("unable to access (%s)",
1267 err_buf, sizeof(err_buf));
1268 _E("unable to copy from (%s) to (%s),"
1271 app_archive_path, err_buf);
1276 /* delete the symbolic link files [bin, lib, res]*/
1277 memset(temp_dir_path, '\0', sizeof(temp_dir_path));
1278 snprintf(temp_dir_path, sizeof(temp_dir_path),
1279 "%s/%s", application_path,
1281 _D("unlink, temp_dir_path(%s)", temp_dir_path);
1282 ret = unlink(temp_dir_path);
1284 if (errno == ENOENT) {
1285 _W("directory (%s) does not exist",
1288 _E("unable to remove the symbolic link file (%s)," \
1289 " it is already unlinked",
1295 /* Copy content to destination */
1296 memset(temp_dir_path, '\0', sizeof(temp_dir_path));
1297 snprintf(temp_dir_path, sizeof(temp_dir_path),
1298 "%s/%s", app_archive_path,
1300 _D("archive2app, temp_dir_path(%s)", temp_dir_path);
1301 ret = _app2sd_copy_dir(temp_dir_path, application_path);
1303 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1304 _E("unable to access (%s)",
1308 err_buf, sizeof(err_buf));
1309 _E("unable to copy from (%s) to (%s) " \
1312 application_path, err_buf);
1317 list = g_list_next(list);
1320 _D("copying file completed");
1321 ret = _app2sd_unmount_app_content(application_path);
1323 _E("unable to unmount SD directory for app (%s)",
1326 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1327 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1329 _E("close dmcrypt device error(%d)", ret);
1331 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1333 _E("unable to detach loopback setup for (%s)",
1337 ret = _app2sd_delete_loopback_device(loopback_device);
1339 _E("unable to delete the loopback device for (%s)",
1342 ret = _app2sd_delete_directory(app_mmc_path);
1344 _E("unable to delete (%s)", app_mmc_path);
1346 ret = _app2sd_delete_directory(app_archive_path);
1348 _E("unable to delete (%s)", app_archive_path);
1350 /* remove passwrd from DB */
1351 ret = _app2sd_initialize_db();
1353 _E("app2sd db initialize failed");
1355 ret = _app2sd_remove_info_from_db(pkgid, uid);
1357 _E("cannot remove info from db");
1359 return APP2EXT_SUCCESS;
1370 int _app2sd_usr_move_app(const char *pkgid, app2ext_move_type move_type,
1371 GList *dir_list, uid_t uid, char *mmc_path, char **image_path)
1373 int ret = APP2EXT_SUCCESS;
1375 switch (move_type) {
1376 case APP2EXT_MOVE_TO_EXT:
1377 ret = _app2sd_move_app_to_external(pkgid, dir_list,
1378 uid, mmc_path, image_path);
1380 _E("move app to external memory failed(%d)", ret);
1384 case APP2EXT_MOVE_TO_PHONE:
1385 ret = _app2sd_move_app_to_internal(pkgid, dir_list,
1388 _E("move app to internal memory failed(%d)", ret);
1393 _E("invalid argument");
1394 return APP2EXT_ERROR_INVALID_ARGUMENTS;
1400 int _app2sd_copy_ro_content(const char *src, const char *dest, GList *dir_list)
1402 char path[FILENAME_MAX] = { 0, };
1403 int ret = APP2EXT_SUCCESS;
1405 app2ext_dir_details *dir_detail = NULL;
1407 list = g_list_first(dir_list);
1409 dir_detail = (app2ext_dir_details *)list->data;
1410 if (dir_detail && dir_detail->name
1411 && dir_detail->type == APP2EXT_DIR_RO) {
1412 memset((void *)&path, '\0', sizeof(path));
1413 snprintf(path, sizeof(path), "%s/%s", src,
1415 ret = _app2sd_copy_dir(path, dest);
1417 if (ret == APP2EXT_ERROR_ACCESS_FILE) {
1418 _E("unable to access (%s)", path);
1420 _E("unable to copy from (%s) " \
1421 "to (%s), errno is (%d)",
1423 return APP2EXT_ERROR_MOVE;
1427 list = g_list_next(list);
1430 return APP2EXT_SUCCESS;
1433 int _app2sd_duplicate_device(const char *pkgid,
1434 const char *loopback_device,
1435 const char *temp_pkgid,
1436 const char *temp_application_path,
1437 const char *temp_loopback_device,
1438 GList *dir_list, char *dev_node, int size,
1443 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
1445 char *result = NULL;
1446 char *passwd = NULL;
1449 /* create a new loopback device */
1450 ret = _app2sd_create_loopback_device(temp_pkgid,
1451 temp_loopback_device, (size + PKG_BUF_SIZE));
1453 _E("package already present");
1457 /* perform loopback encryption setup */
1458 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1459 dev_node = _app2sd_dmcrypt_duplicate_encryption_setup(pkgid,
1460 temp_loopback_device, uid);
1462 _E("dmcrypt duplicate encryption setup failed");
1463 _app2sd_delete_loopback_device(temp_loopback_device);
1464 return APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE;
1467 /* get password for loopback encryption */
1468 ret = _app2sd_initialize_db();
1470 _E("app2sd db initialize failed");
1471 return APP2EXT_ERROR_DB_INITIALIZE;
1474 if ((passwd = _app2sd_get_password_from_db(pkgid, uid)) == NULL) {
1475 passwd = (char *)_app2sd_generate_password();
1476 if (NULL == passwd) {
1477 _E("unable to generate password");
1478 return APP2EXT_ERROR_PASSWD_GENERATION;
1480 if ((ret = _app2sd_set_info_in_db(pkgid,
1481 passwd, loopback_device, uid)) < 0) {
1482 _E("unable to save info");
1485 return APP2EXT_ERROR_SQLITE_REGISTRY;
1490 dev_node = _app2sd_do_loopback_duplicate_encryption_setup(pkgid,
1491 temp_pkgid, temp_loopback_device, passwd, uid);
1493 _E("losetup failed, device node is (%s)", dev_node);
1494 _app2sd_delete_loopback_device(temp_loopback_device);
1497 return APP2EXT_ERROR_DO_LOSETUP;
1501 _D("duplicate setup SUCCESS");
1503 /* check whether loopback device is associated with
1504 * device node or not
1506 devi = _app2sd_find_associated_device_node(temp_loopback_device);
1508 _E("finding associated device node failed");
1509 err_res = APP2EXT_ERROR_DO_LOSETUP;
1512 _D("losetup SUCCESS");
1515 /* format the loopback file system */
1516 ret = _app2sd_create_file_system(dev_node);
1518 _E("creating fs failed");
1519 err_res = APP2EXT_ERROR_CREATE_FS;
1522 _D("create filesystem SUCCESS");
1524 /* do mounting for new dev*/
1525 ret = _app2sd_mount_app_content(temp_application_path, pkgid,
1526 dev_node, MOUNT_TYPE_RW, dir_list,
1527 APP2SD_PRE_UPGRADE, uid);
1529 _E("remount failed");
1530 err_res = APP2EXT_ERROR_MOUNT_PATH;
1534 #if !defined(TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION)
1541 return APP2EXT_SUCCESS;
1545 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1546 ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
1548 _E("close dmcrypt device error(%d)", ret);
1550 result = _app2sd_detach_loop_device(dev_node);
1556 _app2sd_delete_loopback_device(temp_loopback_device);
1564 int _app2sd_update_loopback_device_size(const char *pkgid,
1565 const char *loopback_device,
1566 const char *application_path,
1567 const char *temp_pkgid,
1568 const char *temp_loopback_device,
1569 const char *temp_application_path,
1570 int size, GList *dir_list,
1574 char *device_node = NULL;
1575 char *old_device_node = NULL;
1577 char app_mmc_path[FILENAME_MAX] = { 0, };
1578 char temp_app_mmc_path[FILENAME_MAX] = { 0, };
1580 ret = _app2sd_duplicate_device(pkgid, loopback_device,
1581 temp_pkgid, temp_application_path, temp_loopback_device,
1582 dir_list, device_node, size, uid);
1584 _E("creating duplicate device failed");
1588 /* get the associated device node for SD card applicatione */
1589 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1591 _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
1593 old_device_node = _app2sd_find_associated_device_node(loopback_device);
1595 if (NULL == old_device_node) {
1596 /* do loopback setup */
1597 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1598 ret = _app2sd_dmcrypt_open_device(pkgid, loopback_device,
1599 false, uid, &old_device_node);
1601 _E("dmcrypt open device error");
1602 err_res = APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
1606 old_device_node = _app2sd_do_loopback_encryption_setup(pkgid,
1607 loopback_device, uid);
1608 if (old_device_node == NULL) {
1609 _E("loopback encryption setup failed");
1610 err_res = APP2EXT_ERROR_DO_LOSETUP;
1615 ret = _app2sd_mount_app_content(application_path, pkgid,
1616 old_device_node, MOUNT_TYPE_RW, dir_list,
1617 APP2SD_PRE_UPGRADE, uid);
1619 _E("remount failed");
1620 err_res = APP2EXT_ERROR_MOUNT_PATH;
1623 /* do re-mounting */
1624 ret = _app2sd_mount_app_content(application_path, pkgid,
1625 old_device_node, MOUNT_TYPE_RW_REMOUNT, dir_list,
1626 APP2SD_PRE_UPGRADE, uid);
1628 _E("remount failed");
1629 err_res = APP2EXT_ERROR_MOUNT_PATH;
1633 snprintf(app_mmc_path, sizeof(app_mmc_path),
1634 "%s/.mmc", application_path);
1635 snprintf(temp_app_mmc_path, sizeof(temp_app_mmc_path),
1636 "%s/.mmc", temp_application_path);
1638 ret = _app2sd_copy_ro_content(app_mmc_path,
1639 temp_app_mmc_path, dir_list);
1641 _E("copy ro content failed");
1645 ret = _app2sd_unmount_app_content(application_path);
1647 _E("unable to unmount the SD application");
1648 err_res = APP2EXT_ERROR_UNMOUNT;
1651 ret = _app2sd_unmount_app_content(temp_application_path);
1653 _E("unable to unmount the SD application");
1654 err_res = APP2EXT_ERROR_UNMOUNT;
1658 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1659 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1661 _E("close dmcrypt device error(%d)", ret);
1662 err_res = APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1666 ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
1668 _E("close dmcrypt device error(%d)", ret);
1669 err_res = APP2EXT_ERROR_CLOSE_DMCRYPT_DEVICE;
1673 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1675 _E("unable to remove loopback setup");
1676 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1679 ret = _app2sd_remove_loopback_encryption_setup(temp_loopback_device);
1681 _E("unable to remove loopback setup");
1682 err_res = APP2EXT_ERROR_DELETE_LOOPBACK_DEVICE;
1687 ret = _app2sd_delete_directory(loopback_device);
1689 _E("unable to delete (%s)", loopback_device);
1690 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1694 ret = _app2sd_rename_dir(temp_loopback_device, loopback_device);
1696 _E("unable to rename (%s)", temp_loopback_device);
1697 err_res = APP2EXT_ERROR_MOVE;
1701 ret = _app2sd_delete_directory(temp_application_path);
1703 _E("unable to delete (%s)", temp_application_path);
1704 err_res = APP2EXT_ERROR_DELETE_DIRECTORY;
1708 return APP2EXT_SUCCESS;
1711 if (old_device_node) {
1712 free(old_device_node);
1713 old_device_node = NULL;
1716 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1717 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1719 _E("close dmcrypt device error(%d)", ret);
1721 ret = _app2sd_dmcrypt_close_device(temp_pkgid, uid);
1724 _E("close dmcrypt device error(%d)", ret);
1726 ret = _app2sd_remove_loopback_encryption_setup(loopback_device);
1728 _E("unable to remove loopback setup");
1730 ret = _app2sd_remove_loopback_encryption_setup(temp_loopback_device);
1732 _E("unable to remove loopback setup");
1735 _app2sd_delete_loopback_device(temp_loopback_device);
1737 ret = _app2sd_delete_directory(temp_application_path);
1739 _E("unable to delete (%s)", temp_application_path);
1744 int _app2sd_force_clean(const char *pkgid, const char *application_path,
1745 const char *loopback_device, uid_t uid)
1747 int ret = APP2EXT_SUCCESS;
1749 /* unmount the loopback encrypted pseudo device from the application installation path */
1750 ret = _app2sd_unmount_app_content(application_path);
1752 _W("unable to unmount the app content (%d)", ret);
1754 /* detach the loopback encryption setup for the application */
1755 #ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
1756 ret = _app2sd_dmcrypt_close_device(pkgid, uid);
1758 _W("close dmcrypt device error (%d)", ret);
1760 ret = _app2sd_remove_all_loopback_encryption_setups(loopback_device);
1762 _W("unable to detach the loopback encryption setup for the application");
1765 /* delete the loopback device from the SD card */
1766 ret = _app2sd_delete_loopback_device(loopback_device);
1768 _W("unable to detach the loopback encryption setup for the application");
1770 /* delete symlink */
1771 _app2sd_delete_symlink(application_path);
1773 /* remove passwrd from DB */
1774 ret = _app2sd_initialize_db();
1776 _W("app2sd db initialize failed");
1778 ret = _app2sd_remove_info_from_db(pkgid, uid);
1780 _W("cannot remove info from db");