int Volume::formatVol() { if (getState() == Volume::State_NoMedia) { errno = ENODEV; return -1; } else if (getState() != Volume::State_Idle) { errno = EBUSY; return -1; } if (isMountpointMounted(getMountpoint())) { SLOGW("Volume is idle but appears to be mounted - fixing"); setState(Volume::State_Mounted); // mCurrentlyMountedKdev = XXX errno = EBUSY; return -1; } bool formatEntireDevice = (mPartIdx == -1); char devicePath[255]; dev_t diskNode = getDiskDevice(); dev_t partNode = MKDEV(MAJOR(diskNode), (formatEntireDevice ? 1 : mPartIdx)); setState(Volume::State_Formatting); int ret = -1; // Only initialize the MBR if we are formatting the entire device if (formatEntireDevice) { sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(diskNode), MINOR(diskNode)); if (initializeMbr(devicePath)) { SLOGE("Failed to initialize MBR (%s)", strerror(errno)); goto err; } } sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(partNode), MINOR(partNode)); #ifdef VOLD_EMMC_SHARES_DEV_MAJOR // If emmc and sdcard share dev major number, vold may pick // incorrectly based on partition nodes alone, formatting // the wrong device. Use device nodes instead. dev_t deviceNodes; getDeviceNodes((dev_t *) &deviceNodes, 1); sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes), MINOR(deviceNodes)); #endif if (mDebug) { SLOGI("Formatting volume %s (%s)", getLabel(), devicePath); } if (Fat::format(devicePath, 0)) { SLOGE("Failed to format (%s)", strerror(errno)); goto err; } ret = 0; err: setState(Volume::State_Idle); return ret; }
int Volume::mountVol() { dev_t deviceNodes[4]; int n, i, rc = 0; char errmsg[255]; const char* externalStorage = getenv("EXTERNAL_STORAGE"); bool primaryStorage = externalStorage && !strcmp(getMountpoint(), externalStorage); char decrypt_state[PROPERTY_VALUE_MAX]; char crypto_state[PROPERTY_VALUE_MAX]; char encrypt_progress[PROPERTY_VALUE_MAX]; int flags; property_get("vold.decrypt", decrypt_state, ""); property_get("vold.encrypt_progress", encrypt_progress, ""); /* Don't try to mount the volumes if we have not yet entered the disk password * or are in the process of encrypting. */ if ((getState() == Volume::State_NoMedia) || ((!strcmp(decrypt_state, "1") || encrypt_progress[0]) && primaryStorage)) { snprintf(errmsg, sizeof(errmsg), "Volume %s %s mount failed - no media", getLabel(), getMountpoint()); mVm->getBroadcaster()->sendBroadcast( ResponseCode::VolumeMountFailedNoMedia, errmsg, false); errno = ENODEV; return -1; } else if (getState() != Volume::State_Idle) { errno = EBUSY; if (getState() == Volume::State_Pending) { mRetryMount = true; } return -1; } if (isMountpointMounted(getMountpoint())) { SLOGW("Volume is idle but appears to be mounted - fixing"); setState(Volume::State_Mounted); // mCurrentlyMountedKdev = XXX return 0; } n = getDeviceNodes((dev_t *) &deviceNodes, 4); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } /* If we're running encrypted, and the volume is marked as encryptable and nonremovable, * and vold is asking to mount the primaryStorage device, then we need to decrypt * that partition, and update the volume object to point to it's new decrypted * block device */ property_get("ro.crypto.state", crypto_state, ""); flags = getFlags(); if (primaryStorage && ((flags & (VOL_NONREMOVABLE | VOL_ENCRYPTABLE))==(VOL_NONREMOVABLE | VOL_ENCRYPTABLE)) && !strcmp(crypto_state, "encrypted") && !isDecrypted()) { char new_sys_path[MAXPATHLEN]; char nodepath[256]; int new_major, new_minor; if (n != 1) { /* We only expect one device node returned when mounting encryptable volumes */ SLOGE("Too many device nodes returned when mounting %d\n", getMountpoint()); return -1; } if (cryptfs_setup_volume(getLabel(), MAJOR(deviceNodes[0]), MINOR(deviceNodes[0]), new_sys_path, sizeof(new_sys_path), &new_major, &new_minor)) { SLOGE("Cannot setup encryption mapping for %d\n", getMountpoint()); return -1; } /* We now have the new sysfs path for the decrypted block device, and the * majore and minor numbers for it. So, create the device, update the * path to the new sysfs path, and continue. */ snprintf(nodepath, sizeof(nodepath), "/dev/block/vold/%d:%d", new_major, new_minor); if (createDeviceNode(nodepath, new_major, new_minor)) { SLOGE("Error making device node '%s' (%s)", nodepath, strerror(errno)); } // Todo: Either create sys filename from nodepath, or pass in bogus path so // vold ignores state changes on this internal device. updateDeviceInfo(nodepath, new_major, new_minor); /* Get the device nodes again, because they just changed */ n = getDeviceNodes((dev_t *) &deviceNodes, 4); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } } for (i = 0; i < n; i++) { char devicePath[255]; sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]), MINOR(deviceNodes[i])); SLOGI("%s being considered for volume %s\n", devicePath, getLabel()); errno = 0; setState(Volume::State_Checking); if (Fat::check(devicePath)) { if (errno == ENODATA) { SLOGW("%s does not contain a FAT filesystem\n", devicePath); continue; } errno = EIO; /* Badness - abort the mount */ SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno)); setState(Volume::State_Idle); return -1; } /* * Mount the device on our internal staging mountpoint so we can * muck with it before exposing it to non priviledged users. */ errno = 0; int gid; if (primaryStorage) { // Special case the primary SD card. // For this we grant write access to the SDCARD_RW group. gid = AID_SDCARD_RW; } else { // For secondary external storage we keep things locked up. gid = AID_MEDIA_RW; } if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false, AID_SYSTEM, gid, 0702, true)) { SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno)); continue; } SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint()); protectFromAutorunStupidity(); // only create android_secure on primary storage if (primaryStorage && createBindMounts()) { SLOGE("Failed to create bindmounts (%s)", strerror(errno)); umount("/mnt/secure/staging"); setState(Volume::State_Idle); return -1; } /* * Now that the bindmount trickery is done, atomically move the * whole subtree to expose it to non priviledged users. */ if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) { SLOGE("Failed to move mount (%s)", strerror(errno)); umount("/mnt/secure/staging"); setState(Volume::State_Idle); return -1; } setState(Volume::State_Mounted); mCurrentlyMountedKdev = deviceNodes[i]; return 0; } SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel()); setState(Volume::State_Idle); return -1; }
int Volume::mountVol() { dev_t deviceNodes[4]; int n, i, rc = 0; char errmsg[255]; if (getState() == Volume::State_NoMedia) { snprintf(errmsg, sizeof(errmsg), "Volume %s %s mount failed - no media", getLabel(), getMountpoint()); mVm->getBroadcaster()->sendBroadcast( ResponseCode::VolumeMountFailedNoMedia, errmsg, false); errno = ENODEV; return -1; } else if (getState() != Volume::State_Idle) { errno = EBUSY; return -1; } if (isMountpointMounted(getMountpoint())) { SLOGW("Volume is idle but appears to be mounted - fixing"); setState(Volume::State_Mounted); // mCurrentlyMountedKdev = XXX return 0; } n = getDeviceNodes((dev_t *) &deviceNodes, 4); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } for (i = 0; i < n; i++) { char devicePath[255]; sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]), MINOR(deviceNodes[i])); SLOGI("%s being considered for volume %s\n", devicePath, getLabel()); errno = 0; setState(Volume::State_Checking); if (Fat::check(devicePath)) { if (errno == ENODATA) { SLOGW("%s does not contain a FAT filesystem\n", devicePath); continue; } errno = EIO; /* Badness - abort the mount */ SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno)); setState(Volume::State_Idle); return -1; } /* * Mount the device on our internal staging mountpoint so we can * muck with it before exposing it to non priviledged users. */ errno = 0; if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false, 1000, 1015, 0702, true)) { SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno)); continue; } SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint()); protectFromAutorunStupidity(); if (createBindMounts()) { SLOGE("Failed to create bindmounts (%s)", strerror(errno)); umount("/mnt/secure/staging"); setState(Volume::State_Idle); return -1; } /* * Now that the bindmount trickery is done, atomically move the * whole subtree to expose it to non priviledged users. */ if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) { SLOGE("Failed to move mount (%s)", strerror(errno)); umount("/mnt/secure/staging"); setState(Volume::State_Idle); return -1; } setState(Volume::State_Mounted); mCurrentlyMountedKdev = deviceNodes[i]; return 0; } SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel()); setState(Volume::State_Idle); return -1; }
int Volume::mountVol() { dev_t deviceNodes[MAX_SUP_PART]; // dev_t deviceNodes[4]; int n, i, curState, rc = 0; char errmsg[255]; const char* externalStorage = getenv("EXTERNAL_STORAGE"); bool primaryStorage = externalStorage && !strcmp(getMountpoint(), externalStorage); char decrypt_state[PROPERTY_VALUE_MAX]; char crypto_state[PROPERTY_VALUE_MAX]; char encrypt_progress[PROPERTY_VALUE_MAX]; int flags; property_get("vold.decrypt", decrypt_state, ""); property_get("vold.encrypt_progress", encrypt_progress, ""); /* Don't try to mount the volumes if we have not yet entered the disk password * or are in the process of encrypting. */ if ((getState() == Volume::State_NoMedia) || ((!strcmp(decrypt_state, "1") || encrypt_progress[0]) && primaryStorage)) { snprintf(errmsg, sizeof(errmsg), "Volume %s %s mount failed - no media", getLabel(), getMountpoint()); mVm->getBroadcaster()->sendBroadcast( ResponseCode::VolumeMountFailedNoMedia, errmsg, false); errno = ENODEV; return -1; } else if (getState() != Volume::State_Idle) { errno = EBUSY; if (getState() == Volume::State_Pending) { mRetryMount = true; } return -1; } if (isMountpointMounted(getMountpoint())) { SLOGW("Volume is idle but appears to be mounted - fixing"); setState(Volume::State_Mounted); // mCurrentlyMountedKdev = XXX return 0; } #ifdef MTK_SHARED_SDCARD if (IsEmmcStorage()) { setState(Volume::State_Mounted); return 0; } #endif // n = getDeviceNodes((dev_t *) &deviceNodes, 4); n = getDeviceNodes((dev_t *) &deviceNodes, MAX_SUP_PART); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } SLOGD("Found %d device nodes", n); #ifdef MTK_SD_REINIT_SUPPORT if (!IsEmmcStorage()) { SLOGD("Reinit SD card"); if (mVm->reinitExternalSD()){ SLOGD("Fail: reinitExternalSD()"); } } #endif /* If we're running encrypted, and the volume is marked as encryptable and nonremovable, * and vold is asking to mount the primaryStorage device, then we need to decrypt * that partition, and update the volume object to point to it's new decrypted * block device */ property_get("ro.crypto.state", crypto_state, ""); flags = getFlags(); if (primaryStorage && ((flags & (VOL_NONREMOVABLE | VOL_ENCRYPTABLE))==(VOL_NONREMOVABLE | VOL_ENCRYPTABLE)) && !strcmp(crypto_state, "encrypted") && !isDecrypted()) { char new_sys_path[MAXPATHLEN]; char nodepath[256]; int new_major, new_minor; if (n != 1) { /* We only expect one device node returned when mounting encryptable volumes */ SLOGE("Too many device nodes returned when mounting %d\n", getMountpoint()); return -1; } if (cryptfs_setup_volume(getLabel(), MAJOR(deviceNodes[0]), MINOR(deviceNodes[0]), new_sys_path, sizeof(new_sys_path), &new_major, &new_minor)) { SLOGE("Cannot setup encryption mapping for %d\n", getMountpoint()); return -1; } /* We now have the new sysfs path for the decrypted block device, and the * majore and minor numbers for it. So, create the device, update the * path to the new sysfs path, and continue. */ snprintf(nodepath, sizeof(nodepath), "/dev/block/vold/%d:%d", new_major, new_minor); if (createDeviceNode(nodepath, new_major, new_minor)) { SLOGE("Error making device node '%s' (%s)", nodepath, strerror(errno)); } // Todo: Either create sys filename from nodepath, or pass in bogus path so // vold ignores state changes on this internal device. updateDeviceInfo(nodepath, new_major, new_minor); /* Get the device nodes again, because they just changed */ n = getDeviceNodes((dev_t *) &deviceNodes, MAX_SUP_PART); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } } for (i = 0; i < n; i++) { char devicePath[255]; sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(deviceNodes[i]), MINOR(deviceNodes[i])); if (deviceNodes[i] == (dev_t)(-1)) { SLOGE("Partition '%s' is invalid dev_t. Skip mounting!", devicePath); continue; } SLOGI("%s being considered for volume %s\n", devicePath, getLabel()); errno = 0; setState(Volume::State_Checking); /* * If FS check failed, we should move on to next partition * instead of returning an error */ __CHECK_FAT_AGAIN: if (Fat::check(devicePath)) { #if 0 if (errno == ENODATA) { SLOGW("%s does not contain a FAT filesystem\n", devicePath); continue; } errno = EIO; /* Badness - abort the mount */ SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno)); setState(Volume::State_Idle); return -1; #else #ifdef MTK_EMMC_SUPPORT if ( mVm->isFirstBoot() && IsEmmcStorage()) { SLOGI("** This is first boot and internal sd is not formatted. Try to format it. (%s)\n", devicePath); if (Fat::format(devicePath, 0)) { SLOGE("Failed to format (%s)", strerror(errno)); } else { SLOGI("Format successfully. (%s)\n", devicePath); property_set("persist.first_boot", "0"); goto __CHECK_FAT_AGAIN; } } #endif SLOGW("%s failed FS checks, move on to next partition", devicePath); continue; #endif } #ifdef MTK_EMMC_SUPPORT else { if ( mVm->isFirstBoot() && IsEmmcStorage()) { property_set("persist.first_boot", "0"); } } #endif /* * Mount the device on our internal staging mountpoint so we can * muck with it before exposing it to non priviledged users. */ errno = 0; int gid; if (primaryStorage) { // Special case the primary SD card. // For this we grant write access to the SDCARD_RW group. gid = AID_SDCARD_RW; } else { // For secondary external storage we keep things locked up. /* Note: Change the google default setting from AID_MEDIA_RW to AID_SDCARD_RW. */ gid = AID_SDCARD_RW; } if (Fat::doMount(devicePath, "/mnt/secure/staging", false, false, false, AID_SYSTEM, gid, 0702, true)) { SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno)); // kill the process anyway Process::killProcessesWithOpenFiles("/mnt/secure/staging", 2); continue; } SLOGI("Device %s, target %s mounted @ /mnt/secure/staging", devicePath, getMountpoint()); SLOGI("PrimaryStory = %d, externalStorage = %s", primaryStorage, externalStorage); protectFromAutorunStupidity(); // only create android_secure on primary storage if (primaryStorage && createBindMounts()) { SLOGE("Failed to create bindmounts (%s)", strerror(errno)); umount("/mnt/secure/staging"); setState(Volume::State_Idle); return -1; } /* * Now that the bindmount trickery is done, atomically move the * whole subtree to expose it to non priviledged users. */ if (doMoveMount("/mnt/secure/staging", getMountpoint(), false)) { SLOGE("Failed to move mount (%s)", strerror(errno)); umount("/mnt/secure/staging"); setState(Volume::State_Idle); return -1; } setState(Volume::State_Mounted); mCurrentlyMountedKdev = deviceNodes[i]; return 0; } SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel()); spin_lock(&mStateLock); curState = getState(); if ((curState != Volume::State_NoMedia) && (curState != Volume::State_Mounted)) setState(Volume::State_Idle); if(curState == Volume::State_Mounted) { spin_unlock(&mStateLock); return 0; } spin_unlock(&mStateLock); return -1; }
int Volume::formatVol() { dev_t deviceNodes[MAX_SUP_PART]; int part_num; if (getState() == Volume::State_NoMedia) { errno = ENODEV; return -1; } else if (getState() != Volume::State_Idle) { errno = EBUSY; return -1; } if (isMountpointMounted(getMountpoint())) { SLOGW("Volume is idle but appears to be mounted - fixing"); setState(Volume::State_Mounted); // mCurrentlyMountedKdev = XXX errno = EBUSY; return -1; } bool formatEntireDevice = ((mPartIdx == -1) && (0 != getDeviceNumParts())); char devicePath[255]; dev_t diskNode = getDiskDevice(); //dev_t partNode = MKDEV(MAJOR(diskNode), (formatEntireDevice ? 1 : mPartIdx)); //part_num reserved for mutiple partition support // getDeviceNodes((dev_t *) &deviceNodes, MAX_SUP_PART); part_num = 1; dev_t partNode = deviceNodes[part_num - 1]; setState(Volume::State_Formatting); int ret = -1; // Only initialize the MBR if we are formatting the entire device if (formatEntireDevice) { sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(diskNode), MINOR(diskNode)); SLOGI("mDiskNumParts = %d\n", getDeviceNumParts()); if (initializeMbr(devicePath)) { SLOGE("Failed to initialize MBR (%s)", strerror(errno)); goto err; } } sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(partNode), MINOR(partNode)); SLOGI("mDiskNumParts = %d\n", getDeviceNumParts()); if (mDebug) { SLOGI("Formatting volume %s (%s)", getLabel(), devicePath); } if (Fat::format(devicePath, 0)) { SLOGE("Failed to format (%s)", strerror(errno)); goto err; } ret = 0; err: setState(Volume::State_Idle); return ret; }
vrpn_DevInput::vrpn_DevInput( const char* name, vrpn_Connection * cxn, const char *device_name, const char * type, int int_param ) : vrpn_Analog( name, cxn ) , vrpn_Button_Filter( name, cxn ) , d_fileDescriptor(-1) // None found yet, device broken. { int i; if (strcmp(type, "keyboard") == 0) { d_type = DEVICE_KEYBOARD; } else if (strcmp(type, "absolute") == 0) { d_type = DEVICE_MOUSE_ABSOLUTE; } else if (strcmp(type, "relative") == 0) { d_type = DEVICE_MOUSE_RELATIVE; } else { REPORT_ERROR("Third parameter must be keyboard, absolute or relative"); return; } vrpn_Button_Filter::num_buttons = 0; vrpn_Analog::num_channel = 0; switch (d_type) { case DEVICE_KEYBOARD: if ((int_param < 1) || (int_param >= vrpn_BUTTON_MAX_BUTTONS)) { REPORT_ERROR("In case of keyboard, the value must be between 1 and 256"); return; } vrpn_Button_Filter::num_buttons = int_param; break; case DEVICE_MOUSE_ABSOLUTE: vrpn_Analog::num_channel = REL_MAX; vrpn_Button_Filter::num_buttons = 0x50; d_absolute_min = 0; d_absolute_range = int_param; break; case DEVICE_MOUSE_RELATIVE: vrpn_Analog::num_channel = ABS_MAX; vrpn_Button_Filter::num_buttons = 0x50; break; }; // initialize the vrpn_Analog for( i = 0; i < vrpn_Analog::num_channel; i++) { vrpn_Analog::channel[i] = vrpn_Analog::last[i] = 0; } // initialize the vrpn_Button_Filter for( i = 0; i < vrpn_Button_Filter::num_buttons; i++) { vrpn_Button_Filter::buttons[i] = vrpn_Button_Filter::lastbuttons[i] = 0; } std::string node = getDeviceNodes(device_name); if (node.length() == 0) { char msg[4096]; sprintf(msg, "vrpn_DevInput::vrpn_DevInput(): Could not get device %s", device_name); REPORT_ERROR(msg); return; } d_fileDescriptor = open(node.c_str(), O_RDONLY); if(d_fileDescriptor < 0){ char msg[4096]; sprintf(msg, "vrpn_DevInput::vrpn_DevInput(): Could not open device %s (%s)", device_name, strerror(errno)); REPORT_ERROR(msg); return; } }
int Volume::mountVol() { dev_t deviceNodes[DirectVolume::MAX_PARTITIONS]; int n, i, rc = 0, curState; char errmsg[255]; int flags = getFlags(); /* we igore the setting of "VOL_PROVIDES_ASEC". if the storage is primary, then we will handle "Asec" */ //bool providesAsec = (flags & VOL_PROVIDES_ASEC) != 0; const char* externalStorage = getenv("EXTERNAL_STORAGE"); bool providesAsec = externalStorage && !strcmp(getFuseMountpoint(), externalStorage); // TODO: handle "bind" style mounts, for emulated storage char decrypt_state[PROPERTY_VALUE_MAX]; char crypto_state[PROPERTY_VALUE_MAX]; char encrypt_progress[PROPERTY_VALUE_MAX]; if (mPreState != Volume::State_Shared && mVm->isSomeVolumeShared()) { SLOGI("Some volume is State_Shared, force to share current volume, %s \n", getLabel()); return mVm->shareVolume(getLabel(), "ums"); } property_get("vold.decrypt", decrypt_state, ""); property_get("vold.encrypt_progress", encrypt_progress, ""); #ifdef MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT char *otgNodePath = getOtgNodePath(); #endif /* Don't try to mount the volumes if we have not yet entered the disk password * or are in the process of encrypting. */ if ((getState() == Volume::State_NoMedia) || ((!strcmp(decrypt_state, "trigger_restart_min_framework") || encrypt_progress[0]) && providesAsec)) { snprintf(errmsg, sizeof(errmsg), "Volume %s %s mount failed - no media", getLabel(), getFuseMountpoint()); mVm->getBroadcaster()->sendBroadcast( ResponseCode::VolumeMountFailedNoMedia, errmsg, false); errno = ENODEV; return -1; } else if (getState() != Volume::State_Idle) { errno = EBUSY; if (getState() == Volume::State_Pending) { mRetryMount = true; } return -1; } if (isMountpointMounted(getMountpoint())) { SLOGW("Volume is idle but appears to be mounted - fixing"); setState(Volume::State_Mounted); // mCurrentlyMountedKdev = XXX return 0; } #ifdef MTK_SHARED_SDCARD SLOGI("mountvol: IsEmmcStorage=%d", IsEmmcStorage()); if (IsEmmcStorage()) { property_set("ctl.start", "sdcard"); waitForServiceState("sdcard", "running"); setState(Volume::State_Mounted); return 0; } #endif n = getDeviceNodes((dev_t *) &deviceNodes, DirectVolume::MAX_PARTITIONS); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } SLOGD("Found %d device nodes", n); #ifndef MTK_EMULATOR_SUPPORT if (!IsEmmcStorage() && !strncmp(getLabel(), "sdcard", 6)) { #ifdef MTK_FAT_ON_NAND if( -1 == mLoopDeviceIdx){ #endif SLOGD("Reinit SD card"); if (mVm->reinitExternalSD()){ SLOGE("Fail: reinitExternalSD()"); /* Card inserted but fail to reinit, there is something wrong with this card */ errno = EIO; return -1; } #ifdef MTK_FAT_ON_NAND } #endif } #endif /* If we're running encrypted, and the volume is marked as encryptable and nonremovable, * and also marked as providing Asec storage, then we need to decrypt * that partition, and update the volume object to point to it's new decrypted * block device */ property_get("ro.crypto.state", crypto_state, ""); if (providesAsec && ((flags & (VOL_NONREMOVABLE | VOL_ENCRYPTABLE))==(VOL_NONREMOVABLE | VOL_ENCRYPTABLE)) && !strcmp(crypto_state, "encrypted") && !isDecrypted()) { char new_sys_path[MAXPATHLEN]; char nodepath[256]; int new_major, new_minor; if (n != 1) { /* We only expect one device node returned when mounting encryptable volumes */ SLOGE("Too many device nodes returned when mounting %s\n", getMountpoint()); return -1; } if (cryptfs_setup_volume(getLabel(), MAJOR(deviceNodes[0]), MINOR(deviceNodes[0]), new_sys_path, sizeof(new_sys_path), &new_major, &new_minor)) { SLOGE("Cannot setup encryption mapping for %s\n", getMountpoint()); return -1; } #ifdef MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT if (0 == strcmp(getLabel(), "usbotg")) { if (createDeviceNode(otgNodePath, new_major, new_minor)) { SLOGE("usbotg: Volume mountVol Error making device node '%s' (%s)", otgNodePath, strerror(errno)); } updateDeviceInfo(otgNodePath, new_major, new_minor); } else #endif /* We now have the new sysfs path for the decrypted block device, and the * majore and minor numbers for it. So, create the device, update the * path to the new sysfs path, and continue. */ { snprintf(nodepath, sizeof(nodepath), "/dev/block/vold/%d:%d", new_major, new_minor); if (createDeviceNode(nodepath, new_major, new_minor)) { SLOGE("Error making device node '%s' (%s)", nodepath, strerror(errno)); } // Todo: Either create sys filename from nodepath, or pass in bogus path so // vold ignores state changes on this internal device. updateDeviceInfo(nodepath, new_major, new_minor); /* Get the device nodes again, because they just changed */ n = getDeviceNodes((dev_t *) &deviceNodes, DirectVolume::MAX_PARTITIONS); if (!n) { SLOGE("Failed to get device nodes (%s)\n", strerror(errno)); return -1; } } } #ifdef MTK_MULTI_PARTITION_MOUNT_ONLY_SUPPORT if (0 == strcmp(getLabel(), "usbotg")) { setState(Volume::State_Checking); if (0 != mkdir(getMountpoint(), 0700)) { SLOGE("usbotg: Volume mountVol (%s) mkdir failed (%s)" , getMountpoint(), strerror(errno)); } else { SLOGD("usbotg: Volume mountVol (%s) mkdir success", getMountpoint()); } if (0 != chown(getMountpoint(), AID_MEDIA_RW, AID_MEDIA_RW)) { SLOGE("usbotg: Volume mountVol (%s) mkdir failed (%s)" , getMountpoint(), strerror(errno)); } else { SLOGD("usbotg: Volume mountVol (%s) mkdir success", getMountpoint()); } if (0 != mkdir(getFuseMountpoint(), 0755)) { SLOGE("usbotg: Volume mountVol (%s) mkdir failed (%s)" , getFuseMountpoint(), strerror(errno)); } else { SLOGD("usbotg: Volume mountVol (%s) mkdir success", getFuseMountpoint()); } int fd; int counter = 0; while(1) { counter++; if( counter == 10) { SLOGD("timeout open otgNodePath counter:%d\n",counter); break; } if ((fd = open(otgNodePath, O_RDONLY)) < 0) { SLOGE(" cannot open device '%s' (errno=%d) (%s)", otgNodePath, errno,strerror(errno)); usleep(30000); } else { SLOGD(" can access %s successfully", otgNodePath); close(fd); break; } } if (Fat::check(otgNodePath)) { SLOGE("usbotg: %s fat check fail (%s)\n", otgNodePath, strerror(errno)); char cmd[255] = {0}; sprintf(cmd, "/system/bin/sh -c \"rm -r %s\"", getFuseMountpoint()); system(cmd); SLOGD("usbotg: Volume unmountVol cmd = %s !!!", cmd); sprintf(cmd, "/system/bin/sh -c \"rm -r %s\"", getMountpoint()); system(cmd); SLOGD("usbotg: Volume unmountVol cmd = %s !!!", cmd); return -1; } if (Fat::doMount(otgNodePath, getMountpoint(), false, false, false, AID_MEDIA_RW, AID_MEDIA_RW, 0007, true)) { SLOGE("usbotg: Volume mountVol %s Otg failed to mount via VFAT (%s)\n", otgNodePath, strerror(errno)); char cmd[255] = {0}; sprintf(cmd, "/system/bin/sh -c \"rm -r %s\"", getFuseMountpoint()); system(cmd); SLOGD("usbotg: Volume unmountVol cmd = %s !!!", cmd); sprintf(cmd, "/system/bin/sh -c \"rm -r %s\"", getMountpoint()); system(cmd); SLOGD("usbotg: Volume unmountVol cmd = %s !!!", cmd); setState(Volume::State_Idle); return -1; } extractMetadata(otgNodePath); //fork sdcard process instead of witch service in init.rc struct sigaction act, oact; act.sa_handler = sigCld; act.sa_flags = 0; sigemptyset(&act.sa_mask); if (sigaction(SIGCHLD, &act, &oact) <0) { SLOGD("Error occured on signal"); return -1; } pid_t pid = fork(); if (pid < 0) { SLOGD("Error occured on fork"); return 0; } else if (pid == 0) { SLOGD("usbotg: Volume mountVol go execv,pid=%d", pid); const char* mountCmd = "/system/bin/sdcard"; const char* mountpoint = getMountpoint(); const char* fusemountpoint = getFuseMountpoint(); const char* argv0[] = { mountCmd, "-u", "1023", "-g", "1023", "-w", "1023", "-d", mountpoint, fusemountpoint, NULL }; SLOGD("%s %s %s %s %s %s %s %s %s %s", argv0[0], argv0[1], argv0[2], argv0[3], argv0[4], argv0[5], argv0[6], argv0[7], argv0[8], argv0[9]); if (execv(mountCmd,(char* const*)argv0) < 0) { ALOGE("execv(%s) failed: %s\n", mountCmd, strerror(errno)); SLOGD("usbotg: Volume mountVol mounted failed"); char cmd[255] = {0}; sprintf(cmd, "/system/bin/sh -c \"rm -r %s\"", getFuseMountpoint()); system(cmd); SLOGD("usbotg: Volume unmountVol cmd = %s !!!", cmd); sprintf(cmd, "/system/bin/sh -c \"rm -r %s\"", getMountpoint()); system(cmd); SLOGD("usbotg: Volume unmountVol cmd = %s !!!", cmd); exit(127); } exit(127); } else{ SLOGD("usbotg: Volume mountVol mounted succed,pid=%d",pid); setState(Volume::State_Mounted); mPid = pid; return 0; } } #endif for (i = 0; i < n; i++) { char devicePath[255]; sprintf(devicePath, "/dev/block/vold/%d:%d", major(deviceNodes[i]), minor(deviceNodes[i])); if (deviceNodes[i] == (dev_t)(-1)) { SLOGE("Partition '%s' is invalid dev_t. Skip mounting!", devicePath); continue; } SLOGI("%s being considered for volume %s\n", devicePath, getLabel()); errno = 0; if ((getState() == Volume::State_NoMedia) ) { SLOGI("NoMedia! skip mounting the storage. Update errno to ENODEV"); errno = ENODEV; return -1; } setState(Volume::State_Checking); /* * If FS check failed, we should move on to next partition * instead of returning an error */ __CHECK_FAT_AGAIN: if (Fat::check(devicePath)) { #if 0 if (errno == ENODATA) { SLOGW("%s does not contain a FAT filesystem\n", devicePath); continue; } errno = EIO; /* Badness - abort the mount */ SLOGE("%s failed FS checks (%s)", devicePath, strerror(errno)); setState(Volume::State_Idle); return -1; #else #ifdef MTK_EMMC_SUPPORT if ( mVm->isFirstBoot() && IsEmmcStorage()) { SLOGI("** This is first boot and internal sd is not formatted. Try to format it. (%s)\n", devicePath); if (Fat::format(devicePath, 0, false)) { SLOGE("Failed to format (%s)", strerror(errno)); } else { SLOGI("Format successfully. (%s)\n", devicePath); property_set("persist.vold.first_boot", "0"); goto __CHECK_FAT_AGAIN; } } #endif #ifdef MTK_FAT_ON_NAND char first_boot[PROPERTY_VALUE_MAX] ; property_get("persist.vold.fat_first_boot", first_boot, "1"); if (!strcmp(first_boot, "1") && !strcmp(getLabel(), "sdcard0")) { SLOGI("** This is first boot and internal sd is not formatted. Try to format it. (%s)\n", devicePath); if (Fat::format(devicePath, 0, false)) { SLOGE("Failed to format %s(%d)", strerror(errno), errno); } else { SLOGI("%s format successfully\n", devicePath); property_set("persist.vold.fat_first_boot", "0"); goto __CHECK_FAT_AGAIN; } } #endif SLOGW("%s failed FS checks, move on to next partition", devicePath); continue; #endif } #ifdef MTK_EMMC_SUPPORT else { if ( mVm->isFirstBoot() && IsEmmcStorage()) { property_set("persist.vold.first_boot", "0"); } } #endif errno = 0; int gid; #ifdef MTK_EMMC_DISCARD if (Fat::doMount(devicePath, getMountpoint(), false, false, false, AID_MEDIA_RW, AID_MEDIA_RW, 0007, true, IsEmmcStorage())) { SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno)); continue; } #else //MTK_EMMC_DISCARD if (Fat::doMount(devicePath, getMountpoint(), false, false, false, AID_MEDIA_RW, AID_MEDIA_RW, 0007, true)) { SLOGE("%s failed to mount via VFAT (%s)\n", devicePath, strerror(errno)); continue; } #endif //MTK_EMMC_DISCARD SLOGI("providesAsec = %d", providesAsec); extractMetadata(devicePath); #ifdef MTK_2SDCARD_SWAP char secImgDir[PATH_MAX]; sprintf(secImgDir, "%s/.android_secure", getMountpoint()); SLOGI("Create %s in advance", secImgDir); /* Whether primary or secondary storage, create .android folder in advance to prevent from media out of space for Bindmounts fail This case happens in SWAP feature. */ if (access(secImgDir, R_OK | X_OK)) { if (errno == ENOENT) { if (mkdir(secImgDir, 0777)) { SLOGE("Failed to create %s (%s)", secImgDir, strerror(errno)); } } else { SLOGE("Failed to access %s (%s)", secImgDir, strerror(errno)); } } #endif if (providesAsec && mountAsecExternal() != 0) { SLOGE("Failed to mount secure area (%s)", strerror(errno)); umount(getMountpoint()); setState(Volume::State_Idle); return -1; } char service[64]; char service_id[64]; strcpy(service_id, getMountpoint()+strlen(Volume::MEDIA_DIR)+1); snprintf(service, 64, "fuse_%s", service_id); property_set("ctl.start", service); waitForServiceState(service, "running"); int fd; if ((fd = open(devicePath, O_RDONLY)) < 0) { SLOGE("Cannot open device '%s' (errno=%d)", devicePath, errno); } else { setState(Volume::State_Mounted, Fat::isFat32(fd)); close(fd); } mCurrentlyMountedKdev = deviceNodes[i]; return 0; } SLOGE("Volume %s found no suitable devices for mounting :(\n", getLabel()); curState = getState(); if (curState == Volume::State_NoMedia) { SLOGI("Mount fail caused by NoMedia! Update errno to ENODEV"); errno = ENODEV; } if ((curState != Volume::State_NoMedia) && (curState != Volume::State_Mounted)) { setState(Volume::State_Idle); } if(curState == Volume::State_Mounted) { return 0; } return -1; }