int VolumeManager::cleanupAsec(Volume *v, bool force) { // Continue for the primary storage (VOL_PROVIDES_ASEC) and for the // external apps volume (VOL_EXTERNAL_APPS) if app moving is enabled if ((v->getFlags() & VOL_PROVIDES_ASEC) == 0 && ((v->getFlags() & VOL_EXTERNAL_APPS) == 0 || !v->isExternalAppsEnabled())) { return 0; } int rc = 0; char asecFileName[255]; AsecIdCollection removeAsec; AsecIdCollection removeObb; for (AsecIdCollection::iterator it = mActiveContainers->begin(); it != mActiveContainers->end(); ++it) { ContainerData* cd = *it; if (cd->type == ASEC) { if (findAsec(cd->id, asecFileName, sizeof(asecFileName))) { SLOGE("Couldn't find ASEC %s; cleaning up", cd->id); removeAsec.push_back(cd); } else { SLOGD("Found ASEC at path %s", asecFileName); if (!strncmp(asecFileName, Volume::SEC_ASECDIR_EXT, strlen(Volume::SEC_ASECDIR_EXT))) { removeAsec.push_back(cd); } } } else if (cd->type == OBB) { if (v == getVolumeForFile(cd->id)) { removeObb.push_back(cd); } } else { SLOGE("Unknown container type %d!", cd->type); } } for (AsecIdCollection::iterator it = removeAsec.begin(); it != removeAsec.end(); ++it) { ContainerData *cd = *it; SLOGI("Unmounting ASEC %s (dependent on %s)", cd->id, v->getLabel()); if (unmountAsec(cd->id, force)) { SLOGE("Failed to unmount ASEC %s (%s)", cd->id, strerror(errno)); rc = -1; } } for (AsecIdCollection::iterator it = removeObb.begin(); it != removeObb.end(); ++it) { ContainerData *cd = *it; SLOGI("Unmounting OBB %s (dependent on %s)", cd->id, v->getLabel()); if (unmountObb(cd->id, force)) { SLOGE("Failed to unmount OBB %s (%s)", cd->id, strerror(errno)); rc = -1; } } return rc; }
int VolumeManager::destroyAsec(const char *id, bool force) { char asecFileName[255]; char mountPoint[255]; snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id); snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); if (isMountpointMounted(mountPoint)) { if (mDebug) { SLOGD("Unmounting container before destroy"); } if (unmountAsec(id, force)) { SLOGE("Failed to unmount asec %s for destroy (%s)", id, strerror(errno)); return -1; } } if (unlink(asecFileName)) { SLOGE("Failed to unlink asec '%s' (%s)", asecFileName, strerror(errno)); return -1; } if (mDebug) { SLOGD("ASEC %s destroyed", id); } return 0; }
int VolumeManager::destroyAsec(const char *id, bool force) { char asecFileName[255]; char mountPoint[255]; if (findAsec(id, asecFileName, sizeof(asecFileName))) { SLOGE("Couldn't find ASEC %s", id); return -1; } int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) { SLOGE("ASEC destroy failed for %s: couldn't construct mountpoint", id); return -1; } if (isMountpointMounted(mountPoint)) { if (mDebug) { SLOGD("Unmounting container before destroy"); } if (unmountAsec(id, force)) { SLOGE("Failed to unmount asec %s for destroy (%s)", id, strerror(errno)); return -1; } } if (unlink(asecFileName)) { SLOGE("Failed to unlink asec '%s' (%s)", asecFileName, strerror(errno)); return -1; } if (mDebug) { SLOGD("ASEC %s destroyed", id); } return 0; }
int VolumeManager::cleanupAsec(Volume *v, bool force) { /* Only EXTERNAL_STORAGE needs ASEC cleanup. */ if (!v->isPrimaryStorage()) return 0; while(mActiveContainers->size()) { AsecIdCollection::iterator it = mActiveContainers->begin(); ContainerData* cd = *it; SLOGI("Unmounting ASEC %s (dependant on %s)", cd->id, v->getMountpoint()); if (cd->type == ASEC) { if (unmountAsec(cd->id, force)) { SLOGE("Failed to unmount ASEC %s (%s)", cd->id, strerror(errno)); return -1; } } else if (cd->type == OBB) { if (unmountObb(cd->id, force)) { SLOGE("Failed to unmount OBB %s (%s)", cd->id, strerror(errno)); return -1; } } else { SLOGE("Unknown container type %d!", cd->type); return -1; } } return 0; }
int VolumeManager::unmountAllAsecsInDir(const char *directory) { DIR *d = opendir(directory); int rc = 0; if (!d) { SLOGE("Could not open asec dir %s", directory); return -1; } size_t dirent_len = offsetof(struct dirent, d_name) + fpathconf(dirfd(d), _PC_NAME_MAX) + 1; struct dirent *dent = (struct dirent *) malloc(dirent_len); if (dent == NULL) { SLOGE("Failed to allocate memory for asec dir"); return -1; } struct dirent *result; while (!readdir_r(d, dent, &result) && result != NULL) { if (dent->d_name[0] == '.') continue; if (dent->d_type != DT_REG) continue; size_t name_len = strlen(dent->d_name); if (name_len > 5 && name_len < (ID_BUF_LEN + ASEC_SUFFIX_LEN - 1) && !strcmp(&dent->d_name[name_len - 5], ASEC_SUFFIX)) { char id[ID_BUF_LEN]; strlcpy(id, dent->d_name, name_len - 4); if (unmountAsec(id, true)) { /* Register the error, but try to unmount more asecs */ rc = -1; } } } closedir(d); free(dent); return rc; }