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;
}
示例#2
0
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;
}
示例#4
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;
}