Android虚拟SD卡

转载:

基于fuse文件系统的android sdcard存储方案

一、init进程启动

init.xxx.rc

#modify by tank
    export EXTERNAL_STORAGE /storage/sdcard0

    mkdir /data/media 0775 media_rw media_rw
    chown media_rw media_rw /data/media
    mkdir /storage/sdcard0 0700 system system
    mkdir /storage/sdcard1 0700 system system    
    symlink /storage/sdcard0 /sdcard
    symlink /storage/sdcard0 /mnt/sdcard

    # sd card mount point
#    mkdir /mnt/media_rw/sdcard0 0700 media_rw media_rw
#
#    # sd card fuse mount point
#    mkdir /mnt/sdcard 0000 system system
#    symlink /mnt/sdcard /sdcard
#end tank

# service for sd card access
#service fuse_sdcard0 /system/bin/sdcard -u 1023 -g 1023 -d /mnt/media_rw/sdcard0 /mnt/sdcard
#   class core
#modify by tank
# virtual sdcard daemon running as media_rw (1023)
service fuse_sdcard /system/bin/sdcard -u 1023 -g 1023 -d /data/media /storage/sdcard0
    class main
#end tank
二、看sdcard进程

sdcard空间不足

struct fuse {
    pthread_mutex_t lock;

    __u64 next_generation;
    int fd;
    derive_t derive;
    bool split_perms;
    gid_t write_gid;
    struct node root;
    char obbpath[PATH_MAX];
    //add by tank
    uint64_t free_size;
    uint64_t limit_size;
    //end tank
    Hashmap* package_to_appid;
    Hashmap* appid_with_rw;
};

static int handle_write(struct fuse* fuse, struct fuse_handler* handler,
        const struct fuse_in_header* hdr, const struct fuse_write_in* req,
        const void* buffer)
{
    struct fuse_write_out out;
    struct handle *h = id_to_ptr(req->fh);
    int res;
    __u8 aligned_buffer[req->size] __attribute__((__aligned__(PAGESIZE)));
//add by tank for limit write  to fuse sdcard when data space not enough
    TRACE("fuse->root.name:%s\n",fuse->root.name);
    if(!strncmp( fuse->root.name,"/data",strlen("/data"))){
        struct statfs stat;
        if (statfs(fuse->root.name, &stat) < 0) {
             ALOGE("get %s fs status fail \n",fuse->root.name);
             fuse->free_size =0;
             return -errno;
        } else {
             pthread_mutex_lock(&fuse->lock);
             TRACE("statfs stat.f_bfree: %lld, stat.f_bsize: %d\n", stat.f_bfree, stat.f_bsize);
             fuse->free_size = stat.f_bfree*stat.f_bsize;
             fuse->limit_size = stat.f_blocks*stat.f_bsize*0.1;//limit size 1/10 of the total size
             TRACE("statfs fuse->limit_size: %lld", fuse->limit_size);
             pthread_mutex_unlock(&fuse->lock);
        }
        TRACE("[fuse_debug] fuse.free_size 1 = %lld,root name =%s \n",fuse->free_size,fuse->root.name);
        pthread_mutex_lock(&fuse->lock);
        fuse->free_size -=req->size;
        pthread_mutex_unlock(&fuse->lock);
        TRACE("[fuse_debug] fuse.free_size 2 = %lld\n",fuse->free_size);
        if(fuse->free_size <=  fuse->limit_size ){
             errno = ENOSPC;
             ERROR("[fuse_debug] Oops fuse.free_size = %ld, less than internal sdcard free size threshold ,no space for write!!!!\n",fuse->free_size);
             return -errno;
        }
    }
//end tank
    if (req->flags & O_DIRECT) {
        memcpy(aligned_buffer, buffer, req->size);
        buffer = (const __u8*) aligned_buffer;
    }

    TRACE("[%d] WRITE %p(%d) %u@%"PRIu64"\n", handler->token,
            h, h->fd, req->size, req->offset);
    res = pwrite64(h->fd, buffer, req->size, req->offset);
    if (res < 0) {
        return -errno;
    }
    out.size = res;
    fuse_reply(fuse, hdr->unique, &out, sizeof(out));
    return NO_STATUS;
}
三、MountSerice

frameworks/base/services/core/java/com/android/server/MountService.java

private void readStorageListLocked() {
  if (emulated) {
    // For devices with emulated storage, we create separate
    // volumes for each known user.
    mEmulatedTemplate = new StorageVolume(null, descriptionId, true, false, true, mtpReserve, false, maxFileSize, null);
    final UserManagerService userManager = UserManagerService.getInstance();
    for (UserInfo user : userManager.getUsers(false)) {
      createEmulatedVolumeForUserLocked(user.getUserHandle());
    }
  } else {
      // add by tank
      if (description == null) {
        Slog.e(TAG, "Missing storage path or description in readStorageList");
      } 
      else {
        if (primary) {
          // do not add a physical primary volume when the external storage is emulated
          if (isExternalStorageEmulated()) {
            continue;
          }
          final StorageVolume volume = new StorageVolume(new File(Environment.getExternalStorageDirectory().getPath()),
                                        descriptionId, primary, true, false, mtpReserve,
                                        allowMassStorage, maxFileSize, null);
          addVolumeLocked(volume);
          if(path != null && path.equals("/storage/sdcard0")){
            Slog.d(TAG,"###### TCL fuse sdcard state set ");
            mVolumeStates.put(volume.getPath(), Environment.MEDIA_MOUNTED);
          } else {
              // Until we hear otherwise, treat as unmounted
              mVolumeStates.put(volume.getPath(), Environment.MEDIA_UNMOUNTED);
              volume.setState(Environment.MEDIA_UNMOUNTED);
          }
        } else {
            mSecondStorageTemplate = new StorageVolume(null, descriptionId, primary, true,
            false, mtpReserve, allowMassStorage, maxFileSize, null);
        }
      }
      // end tank
    }
}

logcat -s MountService

MountService.java中sd卡路径有如下xml获得:

frameworks/base/core/res/res/xml/storage_list.xml

<StorageList xmlns:android="http://schemas.android.com/apk/res/android">
<!-- modify by tank storage mount 2015-04-02
    <storage android:emulated="true"
             android:storageDescription="@string/storage_sd_card" />

    <storage android:mountPoint="/mnt/sdcard"
             android:storageDescription="@string/storage_sd_card"
             android:primary="true" />
-->
    <storage android:storageDescription="@string/storage_usb"
             android:primary="false" />

    <storage 
    	android:mountPoint="/storage/sdcard0"
	android:storageDescription="@string/storage_sd_card"
    	android:removable="false"
	android:primary="true"
	android:maxFileSize="4096" />
<!--end tank-->
</StorageList>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值