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