1d6fbcc389
When requested, kick off a thread that will migrate storage contents between two locations. This is performed in several steps that also interact with the framework: 1. Take old and new volumes offline during migration 2. Wipe new location clean (10% of progress) 3. Copy files from old to new (60% of progress) 4. Inform framework that move was successful so it can persist 5. Wipe old location clean (15% of progress) Derives a hacky progress estimate by using a rough proxy of free disk space changes while a cp/rm is taking place. Add new internal path for direct access to volumes to bypass any FUSE emulation overhead, and send it to framework. Remove mutex around various exec calls since setexeccon() is already per-thread. Bug: 19993667 Change-Id: Ibcb4f6fe0126d05b2365f316f53e71dc3e79a2b8
151 lines
4.2 KiB
C++
151 lines
4.2 KiB
C++
/*
|
|
* Copyright (C) 2008 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_VOLD_VOLUME_BASE_H
|
|
#define ANDROID_VOLD_VOLUME_BASE_H
|
|
|
|
#include "Utils.h"
|
|
|
|
#include <cutils/multiuser.h>
|
|
#include <utils/Errors.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <list>
|
|
#include <string>
|
|
|
|
namespace android {
|
|
namespace vold {
|
|
|
|
/*
|
|
* Representation of a mounted volume ready for presentation.
|
|
*
|
|
* Various subclasses handle the different mounting prerequisites, such as
|
|
* encryption details, etc. Volumes can also be "stacked" above other
|
|
* volumes to help communicate dependencies. For example, an ASEC volume
|
|
* can be stacked on a vfat volume.
|
|
*
|
|
* Mounted volumes can be asked to manage bind mounts to present themselves
|
|
* to specific users on the device.
|
|
*
|
|
* When an unmount is requested, the volume recursively unmounts any stacked
|
|
* volumes and removes any bind mounts before finally unmounting itself.
|
|
*/
|
|
class VolumeBase {
|
|
public:
|
|
virtual ~VolumeBase();
|
|
|
|
enum class Type {
|
|
kPublic = 0,
|
|
kPrivate,
|
|
kEmulated,
|
|
kAsec,
|
|
kObb,
|
|
};
|
|
|
|
enum MountFlags {
|
|
/* Flag that volume is primary external storage */
|
|
kPrimary = 1 << 0,
|
|
/* Flag that volume is visible to normal apps */
|
|
kVisible = 1 << 1,
|
|
};
|
|
|
|
enum class State {
|
|
kUnmounted = 0,
|
|
kChecking,
|
|
kMounted,
|
|
kMountedReadOnly,
|
|
kFormatting,
|
|
kEjecting,
|
|
kUnmountable,
|
|
kRemoved,
|
|
kBadRemoval,
|
|
};
|
|
|
|
const std::string& getId() { return mId; }
|
|
const std::string& getDiskId() { return mDiskId; }
|
|
Type getType() { return mType; }
|
|
int getMountFlags() { return mMountFlags; }
|
|
userid_t getMountUserId() { return mMountUserId; }
|
|
State getState() { return mState; }
|
|
const std::string& getPath() { return mPath; }
|
|
const std::string& getInternalPath() { return mInternalPath; }
|
|
|
|
status_t setDiskId(const std::string& diskId);
|
|
status_t setMountFlags(int mountFlags);
|
|
status_t setMountUserId(userid_t mountUserId);
|
|
status_t setSilent(bool silent);
|
|
|
|
void addVolume(const std::shared_ptr<VolumeBase>& volume);
|
|
void removeVolume(const std::shared_ptr<VolumeBase>& volume);
|
|
|
|
std::shared_ptr<VolumeBase> findVolume(const std::string& id);
|
|
|
|
status_t create();
|
|
status_t destroy();
|
|
status_t mount();
|
|
status_t unmount();
|
|
status_t format();
|
|
|
|
protected:
|
|
explicit VolumeBase(Type type);
|
|
|
|
virtual status_t doCreate();
|
|
virtual status_t doDestroy();
|
|
virtual status_t doMount() = 0;
|
|
virtual status_t doUnmount() = 0;
|
|
virtual status_t doFormat();
|
|
|
|
status_t setId(const std::string& id);
|
|
status_t setPath(const std::string& path);
|
|
status_t setInternalPath(const std::string& internalPath);
|
|
|
|
void notifyEvent(int msg);
|
|
void notifyEvent(int msg, const std::string& value);
|
|
|
|
private:
|
|
/* ID that uniquely references volume while alive */
|
|
std::string mId;
|
|
/* ID that uniquely references parent disk while alive */
|
|
std::string mDiskId;
|
|
/* Volume type */
|
|
Type mType;
|
|
/* Flags used when mounting this volume */
|
|
int mMountFlags;
|
|
/* User that owns this volume, otherwise -1 */
|
|
userid_t mMountUserId;
|
|
/* Flag indicating object is created */
|
|
bool mCreated;
|
|
/* Current state of volume */
|
|
State mState;
|
|
/* Path to mounted volume */
|
|
std::string mPath;
|
|
/* Path to internal backing storage */
|
|
std::string mInternalPath;
|
|
/* Flag indicating that volume should emit no events */
|
|
bool mSilent;
|
|
|
|
/* Volumes stacked on top of this volume */
|
|
std::list<std::shared_ptr<VolumeBase>> mVolumes;
|
|
|
|
void setState(State state);
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(VolumeBase);
|
|
};
|
|
|
|
} // namespace vold
|
|
} // namespace android
|
|
|
|
#endif
|