Apply requirement for gcov automation
[platform/core/system/libstorage.git] / src / storage-external.c
index 980c94b..3ffcf4a 100755 (executable)
 #include <sys/statvfs.h>
 #include <vconf.h>
 #include <tzplatform_config.h>
+#include <libsyscommon/list.h>
 
 #include "common.h"
-#include "list.h"
 #include "log.h"
 #include "storage-external-dbus.h"
 
-static dd_list *cb_list[STORAGE_CALLBACK_MAX];
+#define EXTERNAL_STORAGE_PATH  "/run/storaged/external-storage"
+#define EXTENDED_INTERNAL_PATH "/run/storaged/extended-internal-sd"
+#define PATH_LEN               55
+
+#define LUKS_NAME "crypto_LUKS"
+
+static GList *cb_list[STORAGE_CALLBACK_MAX];
 
 static int storage_ext_get_dev_state(storage_ext_device *dev,
                enum storage_ext_state blk_state,
@@ -58,6 +64,9 @@ static int storage_ext_get_dev_state(storage_ext_device *dev,
                default:
                        return -EINVAL;
                }
+       case STORAGE_EXT_BLOCKED:
+               *state = STORAGE_STATE_UNMOUNTABLE;
+               return 0;
        default:
                return -EINVAL;
        }
@@ -73,7 +82,7 @@ int storage_ext_get_space(int storage_id,
        storage_ext_device *dev;
 
        if (storage_id < 0)
-               return -ENOTSUP;
+               return -ENODEV;
 
        dev = calloc(1, sizeof(storage_ext_device));
        if (!dev) {
@@ -96,10 +105,10 @@ int storage_ext_get_space(int storage_id,
        }
 
        if (state >= STORAGE_STATE_MOUNTED) {
-#ifndef __USE_FILE_OFFSET64
-               ret = storage_get_external_memory_size_with_path(dev->mount_point, &s);
-#else
+#ifdef __USE_FILE_OFFSET64
                ret = storage_get_external_memory_size64_with_path(dev->mount_point, &s);
+#else
+               ret = storage_get_external_memory_size_with_path(dev->mount_point, &s);
 #endif
                if (ret < 0) {
                        _E("Failed to get external memory size of (%s)(ret:%d)", dev->mount_point, ret); //LCOV_EXCL_LINE
@@ -123,30 +132,35 @@ out:
 
 int storage_ext_foreach_device_list(storage_device_supported_cb callback, void *user_data)
 {
-       int ret;
+       int ret_val;
        bool ret_cb;
-       dd_list *list = NULL, *elem;
+       GList *list = NULL, *elem;
        storage_ext_device *dev;
        storage_state_e state;
 
        if (!callback)
                return -EINVAL;
 
-       ret = storage_ext_get_list(&list);
-       if (ret < 0) {
+       ret_val = storage_ext_get_list(&list);
+       if (ret_val < 0) {
                _E("Failed to get external storage list from deviced (%d)", errno); //LCOV_EXCL_LINE
-               return ret;
+               return ret_val;
        }
 
-       DD_LIST_FOREACH(list, elem, dev) {
-               ret = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
-               if (ret < 0) {
-                       _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret); //LCOV_EXCL_LINE
+       SYS_G_LIST_FOREACH(list, elem, dev) {
+               ret_val = storage_ext_get_dev_state(dev, STORAGE_EXT_CHANGED, &state);
+               if (ret_val < 0) {
+                       _E("Failed to get storage state (devnode:%s, ret_val:%d)", dev->devnode, ret_val); //LCOV_EXCL_LINE
                        continue;
                }
 
-               ret_cb = callback(dev->storage_id, STORAGE_TYPE_EXTERNAL,
-                               state, dev->mount_point, user_data);
+               if (dev->type == STORAGE_EXT_MMC_EXTENDED_INTERNAL)
+                       ret_cb = callback(dev->storage_id,
+                                       STORAGE_TYPE_EXTENDED_INTERNAL,
+                                       state, dev->mount_point, user_data);
+               else
+                       ret_cb = callback(dev->storage_id, STORAGE_TYPE_EXTERNAL,
+                                       state, dev->mount_point, user_data);
                if (!ret_cb)
                        break;
        }
@@ -161,7 +175,7 @@ static int storage_ext_id_changed(storage_ext_device *dev, enum storage_ext_stat
 {
        enum storage_cb_type type = (enum storage_cb_type)data;
        struct storage_cb_info *cb_info;
-       dd_list *elem;
+       GList *elem;
        storage_state_e state;
        int ret;
 
@@ -177,7 +191,7 @@ static int storage_ext_id_changed(storage_ext_device *dev, enum storage_ext_stat
                return ret;
        }
 
-       DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_ID], elem, cb_info)
+       SYS_G_LIST_FOREACH(cb_list[STORAGE_CALLBACK_ID], elem, cb_info)
                cb_info->state_cb(cb_info->id, state, cb_info->user_data);
 
        return 0;
@@ -187,10 +201,11 @@ static int storage_ext_type_changed(storage_ext_device *dev, enum storage_ext_st
 {
        enum storage_cb_type type = (enum storage_cb_type)data;
        struct storage_cb_info *cb_info;
-       dd_list *elem;
+       GList *elem;
        storage_state_e state;
-       int ret;
+       int ret_val;
        storage_dev_e strdev;
+       storage_type_e storage_type;
        const char *fstype, *fsuuid, *mountpath;
 
        if (!dev)
@@ -199,17 +214,22 @@ static int storage_ext_type_changed(storage_ext_device *dev, enum storage_ext_st
        if (type != STORAGE_CALLBACK_TYPE)
                return -EINVAL;
 
-       ret = storage_ext_get_dev_state(dev, blk_state, &state);
-       if (ret < 0) {
-               _E("Failed to get storage state (devnode:%s, ret:%d)", dev->devnode, ret);
-               return ret;
+       ret_val = storage_ext_get_dev_state(dev, blk_state, &state);
+       if (ret_val < 0) {
+               _E("Failed to get storage state (devnode:%s, ret_val:%d)", dev->devnode, ret_val);
+               return ret_val;
        }
 
-       if (dev->type == STORAGE_EXT_SCSI)
+       if (dev->type == STORAGE_EXT_SCSI) {
                strdev = STORAGE_DEV_EXT_USB_MASS_STORAGE;
-       else if (dev->type == STORAGE_EXT_MMC)
+               storage_type = STORAGE_TYPE_EXTERNAL;
+       } else if (dev->type == STORAGE_EXT_MMC) {
                strdev = STORAGE_DEV_EXT_SDCARD;
-       else {
+               storage_type = STORAGE_TYPE_EXTERNAL;
+       } else if (dev->type == STORAGE_EXT_MMC_EXTENDED_INTERNAL) {
+               strdev = STORAGE_DEV_EXTENDED_INTERNAL;
+               storage_type = STORAGE_TYPE_EXTENDED_INTERNAL;
+       } else {
                _E("Invalid dev type (%d)", dev->type);
                return -EINVAL;
        }
@@ -218,11 +238,17 @@ static int storage_ext_type_changed(storage_ext_device *dev, enum storage_ext_st
        fsuuid = (dev->fs_uuid ? (const char *)dev->fs_uuid : "");
        mountpath = (dev->mount_point ? (const char *)dev->mount_point : "");
 
-       DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_TYPE], elem, cb_info)
+       if (!strncmp(fstype, LUKS_NAME, strlen(LUKS_NAME)))
+               storage_type = STORAGE_TYPE_EXTENDED_INTERNAL;
+
+       SYS_G_LIST_FOREACH(cb_list[STORAGE_CALLBACK_TYPE], elem, cb_info) {
+               if (cb_info->type != storage_type)
+                       continue;
                if (cb_info->type_cb)
                        cb_info->type_cb(dev->storage_id, strdev, state,
                                        fstype, fsuuid, mountpath, dev->primary,
                                        dev->flags, cb_info->user_data);
+       }
 
        return 0;
 }
@@ -233,13 +259,13 @@ static bool check_if_callback_exist(enum storage_cb_type type,
                struct storage_cb_info *info, struct storage_cb_info **cb_data)
 {
        struct storage_cb_info *cb_info;
-       dd_list *elem;
+       GList *elem;
 
        if (!info)
                return false;
 
        if (type == STORAGE_CALLBACK_ID) {
-               DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
+               SYS_G_LIST_FOREACH(cb_list[type], elem, cb_info) {
                        if (cb_info->id == info->id &&
                            cb_info->state_cb == info->state_cb) {
                                goto out;
@@ -248,7 +274,7 @@ static bool check_if_callback_exist(enum storage_cb_type type,
        }
 
        if (type == STORAGE_CALLBACK_TYPE) {
-               DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
+               SYS_G_LIST_FOREACH(cb_list[type], elem, cb_info) {
                        if (cb_info->type == info->type &&
                            cb_info->type_cb == info->type_cb)
                                goto out;
@@ -267,7 +293,7 @@ out:
 int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *info)
 {
        struct storage_cb_info *cb_info;
-       int n, ret;
+       int n, ret_val;
        storage_ext_changed_cb callback;
 
        if (!info)
@@ -285,10 +311,10 @@ int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *i
                return -EINVAL;
        }
 
-       n = DD_LIST_LENGTH(cb_list[type]);
+       n = SYS_G_LIST_LENGTH(cb_list[type]);
        if (n == 0) {
-               ret = storage_ext_register_device_change(callback, (void *)type);
-               if (ret < 0)
+               ret_val = storage_ext_register_device_change(callback, (void *)type);
+               if (ret_val < 0)
                        return -EPERM;
        }
 
@@ -303,7 +329,7 @@ int storage_ext_register_cb(enum storage_cb_type type, struct storage_cb_info *i
                return -errno;
 
        memcpy(cb_info, info, sizeof(struct storage_cb_info));
-       DD_LIST_APPEND(cb_list[type], cb_info);
+       SYS_G_LIST_APPEND(cb_list[type], cb_info);
 
        return 0;
 }
@@ -336,48 +362,99 @@ int storage_ext_unregister_cb(enum storage_cb_type type, struct storage_cb_info
 
        /* remove device callback from list (local) */
        if (cb_info) {
-               DD_LIST_REMOVE(cb_list[type], cb_info);
+               SYS_G_LIST_REMOVE(cb_list[type], cb_info);
                free(cb_info);
        }
 
        /* check if this callback is last element */
-       n = DD_LIST_LENGTH(cb_list[type]);
+       n = SYS_G_LIST_LENGTH(cb_list[type]);
        if (n == 0)
                storage_ext_unregister_device_change(callback);
 
        return 0;
 }
 
-int storage_ext_get_root(int storage_id, char *path, size_t len)
+int storage_ext_get_root(int storage_id, char *path, size_t len, bool *extendedinternal)
 {
+       FILE *fp;
        storage_ext_device *dev;
-       int ret;
+       char file_name[PATH_LEN];
+       char file_name2[PATH_LEN];
+       char *tmp;
+       int ret = 0;
 
        if (storage_id < 0)
-               return -ENOTSUP;
+               return -ENODEV;
 
        if (!path)
                return -EINVAL;
+       if (!extendedinternal)
+               return -EINVAL;
 
-       dev = calloc(1, sizeof(storage_ext_device));
-       if (!dev) {
+       snprintf(file_name, PATH_LEN, EXTERNAL_STORAGE_PATH"/%d", storage_id);
+       snprintf(file_name2, PATH_LEN, EXTENDED_INTERNAL_PATH"/%d", storage_id);
+
+       *extendedinternal = false;
+
+       if (access(file_name, R_OK) == 0) {
+               fp = fopen(file_name, "r");
+               if (!fp) {
+                       _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
+                       ret = -ENODEV;
+                       goto out;
+               }
+
+               tmp = fgets(path, len, fp);
+               fclose(fp);
+               if (!tmp) {
+                       ret = -ENODEV;
+                       _D("Failed to get path");
+                       goto out;
+               }
+               *extendedinternal = false;
+       } else if (access(file_name2, R_OK) == 0) {
+               fp = fopen(file_name2, "r");
+               if (!fp) {
+                       _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
+                       ret = -ENODEV;
+                       goto out;
+               }
+
+               tmp = fgets(path, len, fp);
+               fclose(fp);
+               if (!tmp) {
+                       ret = -ENODEV;
+                       _D("Failed to get path");
+                       goto out;
+               }
+               *extendedinternal = true;
+       } else {
+               dev = calloc(1, sizeof(storage_ext_device));
+               if (!dev) {
 //LCOV_EXCL_START System Error
-               _E("calloc failed");
-               return -ENOMEM;
+                       _E("calloc failed");
+                       return -ENOMEM;
 //LCOV_EXCL_STOP
-       }
+               }
 
-       ret = storage_ext_get_device_info(storage_id, dev);
-       if (ret < 0) {
-               _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
-               goto out;
+               ret = storage_ext_get_device_info(storage_id, dev);
+               if (ret < 0) {
+                       _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
+                       storage_ext_release_device(&dev);
+                       goto out;
+               }
+
+               snprintf(path, len, "%s", dev->mount_point);
+               if (dev->type == STORAGE_EXT_MMC_EXTENDED_INTERNAL)
+                       *extendedinternal = true;
+               else
+                       *extendedinternal = false;
+               storage_ext_release_device(&dev);
        }
 
-       snprintf(path, len, "%s", dev->mount_point);
        ret = 0;
 
 out:
-       storage_ext_release_device(&dev);
        return ret;
 }
 
@@ -387,7 +464,7 @@ int storage_ext_get_state(int storage_id, storage_state_e *state)
        int ret;
 
        if (storage_id < 0)
-               return -ENOTSUP;
+               return -ENODEV;
 
        if (!state)
                return -EINVAL;
@@ -410,14 +487,14 @@ int storage_ext_get_state(int storage_id, storage_state_e *state)
        if (ret < 0)
                _E("Failed to get state of storage id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
 
-out :
+out:
        storage_ext_release_device(&dev);
        return ret;
 }
 
 int storage_ext_get_primary_mmc_path(char *path, size_t len)
 {
-       dd_list *list = NULL, *elem;
+       GList *list = NULL, *elem;
        storage_ext_device *dev;
        int ret;
 
@@ -427,7 +504,7 @@ int storage_ext_get_primary_mmc_path(char *path, size_t len)
                return ret;
        }
 
-       DD_LIST_FOREACH(list, elem, dev) {
+       SYS_G_LIST_FOREACH(list, elem, dev) {
                if (dev->primary) {
                        snprintf(path, len, "%s", dev->mount_point);
                        ret = 0;