DirectVolume.cpp revision dd9b8e92aaf330b48ddb40a7380588ef92b53de6
1f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat/* 2f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Copyright (C) 2008 The Android Open Source Project 3f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 4f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * you may not use this file except in compliance with the License. 6f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * You may obtain a copy of the License at 7f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 8f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * 10f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * Unless required by applicable law or agreed to in writing, software 11f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * See the License for the specific language governing permissions and 14f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat * limitations under the License. 15f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat */ 16f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 17f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <stdio.h> 18fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <stdlib.h> 19f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <string.h> 20fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <errno.h> 21f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 22f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#define LOG_TAG "Vold" 23f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 24f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <cutils/log.h> 25fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <sysutils/NetlinkEvent.h> 26f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 27ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat#include "DirectVolume.h" 28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 29ae10b91044bf76b40b77d81c169e48e0bbdf6d75San MehatDirectVolume::DirectVolume(const char *label, const char *mount_point, int partIdx) : 30f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat Volume(label, mount_point) { 31f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mPartIdx = partIdx; 32f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 33f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mPaths = new PathCollection(); 34dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat for (int i = 0; i < MAX_PARTITIONS; i++) 35dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat mPartMinors[i] = -1; 36f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 37f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 38ae10b91044bf76b40b77d81c169e48e0bbdf6d75San MehatDirectVolume::~DirectVolume() { 39f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat PathCollection::iterator it; 40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 41f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat for (it = mPaths->begin(); it != mPaths->end(); ++it) 42f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat free(*it); 43f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat delete mPaths; 44f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 45f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 46ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatint DirectVolume::addPath(const char *path) { 47f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mPaths->push_back(strdup(path)); 48f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 49f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 51ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatint DirectVolume::handleBlockEvent(NetlinkEvent *evt) { 52fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat const char *dp = evt->findParam("DEVPATH"); 53f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 54fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat PathCollection::iterator it; 55f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat for (it = mPaths->begin(); it != mPaths->end(); ++it) { 56f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (!strncmp(dp, *it, strlen(*it))) { 57fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat /* We can handle this disk */ 58fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int action = evt->getAction(); 59fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat const char *devtype = evt->findParam("DEVTYPE"); 60fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 61fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat if (!strcmp(devtype, "disk")) { 62fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat if (action == NetlinkEvent::NlActionAdd) 63fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat handleDiskAdded(dp, evt); 64fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat else if (action == NetlinkEvent::NlActionRemove) 65fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat handleDiskRemoved(dp, evt); 66fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat else 67fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat LOGD("Ignoring non add/remove event"); 68f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } else { 69fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat if (action == NetlinkEvent::NlActionAdd) 70fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat handlePartitionAdded(dp, evt); 71fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat else if (action == NetlinkEvent::NlActionRemove) 72fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat handlePartitionRemoved(dp, evt); 73fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat else 74fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat LOGD("Ignoring non add/remove event"); 75f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 76fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 77f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 78f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 79f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 80f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat errno = ENODEV; 81f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return -1; 82f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 83fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 84ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatvoid DirectVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) { 85dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat mDiskMajor = atoi(evt->findParam("MAJOR")); 86dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat mDiskMinor = atoi(evt->findParam("MAJOR")); 87fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat mDiskNumParts = atoi(evt->findParam("NPARTS")); 88fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 89fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int partmask = 0; 90fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int i; 9159abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat for (i = 1; i <= mDiskNumParts; i++) { 92fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat partmask |= (1 << i); 93fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat } 94fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat mPendingPartMap = partmask; 95fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 96fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat if (mDiskNumParts == 0) { 97fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat LOGD("Dv::diskIns - No partitions - good to go son!"); 98fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat setState(Volume::State_Idle); 99fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat } else { 100fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat LOGD("Dv::diskIns - waiting for %d partitions (mask 0x%x)", 101fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat mDiskNumParts, mPendingPartMap); 102fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat setState(Volume::State_Pending); 103fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat } 104fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat} 105fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 106ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatvoid DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) { 107fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int major = atoi(evt->findParam("MAJOR")); 108fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int minor = atoi(evt->findParam("MINOR")); 109fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int part_num = atoi(evt->findParam("PARTN")); 11059abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat 111dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if (major != mDiskMajor) { 112dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat LOGE("Partition '%s' has a different major than its disk!", devpath); 113dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat return; 114dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 115dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat mPartMinors[part_num -1] = minor; 116dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 11759abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat mPendingPartMap &= ~(1 << part_num); 11859abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat if (!mPendingPartMap) { 11959abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat LOGD("Dv:partAdd: Got all partitions - ready to rock!"); 12059abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat setState(Volume::State_Idle); 12159abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat } else { 12259abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat LOGD("Dv:partAdd: pending mask now = 0x%x", mPendingPartMap); 12359abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat } 124fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat} 125fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 126ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatvoid DirectVolume::handleDiskRemoved(const char *devpath, NetlinkEvent *evt) { 127fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat} 128fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 129ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatvoid DirectVolume::handlePartitionRemoved(const char *devpath, NetlinkEvent *evt) { 130fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat} 13149e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 132dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat/* 133dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat * Called from Volume to determine the major/minor numbers 134dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat * to be used for mounting 135dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat */ 13649e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehatint DirectVolume::prepareToMount(int *major, int *minor) { 137dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat *major = mDiskMajor; 138dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 139dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if (mPartIdx == -1) { 140dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat /* No specific partition specified */ 141dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 142dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if (!mDiskNumParts) { 143dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat *minor = mDiskMinor; 144dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat return 0; 145dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 146dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 147dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat /* 148dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat * XXX: Use first partition for now. 149dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat * The right thing to do would be to choose 150dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat * this based on the partition type. 151dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat * 152dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat */ 153dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 154dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat *minor = mPartMinors[0]; 155dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat return 0; 156dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 157dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 158dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if (mPartIdx - 1 > mDiskNumParts) { 159dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat errno = EINVAL; 160dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat return -1; 161dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 162dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 163dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat *minor = mPartMinors[mPartIdx-1]; 164dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat return 0; 16549e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat} 166