DirectVolume.cpp revision f3d3ce5e53ab7928f4c292c183c417a1bd051151
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 22a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include <linux/kdev_t.h> 23a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 24a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#define LOG_TAG "DirectVolume" 25f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 26f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat#include <cutils/log.h> 27fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat#include <sysutils/NetlinkEvent.h> 28f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 29ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehat#include "DirectVolume.h" 30a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "VolumeManager.h" 31a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#include "ResponseCode.h" 32a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 33a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat// #define PARTITION_DEBUG 34f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 35a2677e4ad01f250b0765f04adf0acfa6627efc98San MehatDirectVolume::DirectVolume(VolumeManager *vm, const char *label, 36a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat const char *mount_point, int partIdx) : 37a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat Volume(vm, label, mount_point) { 38f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mPartIdx = partIdx; 39a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 40f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mPaths = new PathCollection(); 41dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat for (int i = 0; i < MAX_PARTITIONS; i++) 42dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat mPartMinors[i] = -1; 43a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mPendingPartMap = 0; 44a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mDiskMajor = -1; 45a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mDiskMinor = -1; 46a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mDiskNumParts = 0; 47a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 48a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(Volume::State_NoMedia); 49f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 50f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 51ae10b91044bf76b40b77d81c169e48e0bbdf6d75San MehatDirectVolume::~DirectVolume() { 52f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat PathCollection::iterator it; 53f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 54f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat for (it = mPaths->begin(); it != mPaths->end(); ++it) 55f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat free(*it); 56f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat delete mPaths; 57f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 58f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 59ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatint DirectVolume::addPath(const char *path) { 60f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat mPaths->push_back(strdup(path)); 61f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 62f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 63f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 64a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatdev_t DirectVolume::getDiskDevice() { 65a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return MKDEV(mDiskMajor, mDiskMinor); 66a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 67a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 682dfe297ec47559dbe2297a72bea71cf515c03797Mike Lockwooddev_t DirectVolume::getShareDevice() { 692dfe297ec47559dbe2297a72bea71cf515c03797Mike Lockwood if (mPartIdx != -1) { 702dfe297ec47559dbe2297a72bea71cf515c03797Mike Lockwood return MKDEV(mDiskMajor, mPartIdx); 712dfe297ec47559dbe2297a72bea71cf515c03797Mike Lockwood } else { 722dfe297ec47559dbe2297a72bea71cf515c03797Mike Lockwood return MKDEV(mDiskMajor, mDiskMinor); 732dfe297ec47559dbe2297a72bea71cf515c03797Mike Lockwood } 742dfe297ec47559dbe2297a72bea71cf515c03797Mike Lockwood} 752dfe297ec47559dbe2297a72bea71cf515c03797Mike Lockwood 76a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatvoid DirectVolume::handleVolumeShared() { 77a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(Volume::State_Shared); 78a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 79a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 80a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatvoid DirectVolume::handleVolumeUnshared() { 81a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(Volume::State_Idle); 82a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 83a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 84ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatint DirectVolume::handleBlockEvent(NetlinkEvent *evt) { 85fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat const char *dp = evt->findParam("DEVPATH"); 86f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat 87fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat PathCollection::iterator it; 88f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat for (it = mPaths->begin(); it != mPaths->end(); ++it) { 89f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat if (!strncmp(dp, *it, strlen(*it))) { 90fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat /* We can handle this disk */ 91fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int action = evt->getAction(); 92fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat const char *devtype = evt->findParam("DEVTYPE"); 93fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 94a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (action == NetlinkEvent::NlActionAdd) { 95a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int major = atoi(evt->findParam("MAJOR")); 96a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int minor = atoi(evt->findParam("MINOR")); 97a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char nodepath[255]; 98a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 99a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat snprintf(nodepath, 100a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat sizeof(nodepath), "/dev/block/vold/%d:%d", 101a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat major, minor); 102a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (createDeviceNode(nodepath, major, minor)) { 10397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Error making device node '%s' (%s)", nodepath, 104a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat strerror(errno)); 105a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 106a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!strcmp(devtype, "disk")) { 107fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat handleDiskAdded(dp, evt); 108a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 109fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat handlePartitionAdded(dp, evt); 110a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 111a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else if (action == NetlinkEvent::NlActionRemove) { 112a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!strcmp(devtype, "disk")) { 113a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat handleDiskRemoved(dp, evt); 114a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 115fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat handlePartitionRemoved(dp, evt); 116a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 117a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else if (action == NetlinkEvent::NlActionChange) { 118a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (!strcmp(devtype, "disk")) { 119a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat handleDiskChanged(dp, evt); 120a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 121a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat handlePartitionChanged(dp, evt); 122a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 123a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 12497ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Ignoring non add/remove/change event"); 125f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 126fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 127f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return 0; 128f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 129f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat } 130f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat errno = ENODEV; 131f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat return -1; 132f1b736bc5605e92e917ab27f5abf3ba839be2270San Mehat} 133fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 134ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatvoid DirectVolume::handleDiskAdded(const char *devpath, NetlinkEvent *evt) { 135da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root mDiskMajor = atoi(evt->findParam("MAJOR")); 136da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root mDiskMinor = atoi(evt->findParam("MINOR")); 1377b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat 1387b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat const char *tmp = evt->findParam("NPARTS"); 1397b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat if (tmp) { 1407b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat mDiskNumParts = atoi(tmp); 1417b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat } else { 14297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Kernel block uevent missing 'NPARTS'"); 1437b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat mDiskNumParts = 1; 1447b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat } 1457b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat 146a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char msg[255]; 147fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 148fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int partmask = 0; 149fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat int i; 15059abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat for (i = 1; i <= mDiskNumParts; i++) { 151fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat partmask |= (1 << i); 152fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat } 153fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat mPendingPartMap = partmask; 154fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 155fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat if (mDiskNumParts == 0) { 156a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifdef PARTITION_DEBUG 15797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Dv::diskIns - No partitions - good to go son!"); 158a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif 159fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat setState(Volume::State_Idle); 160fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat } else { 161a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifdef PARTITION_DEBUG 16297ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Dv::diskIns - waiting for %d partitions (mask 0x%x)", 163fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat mDiskNumParts, mPendingPartMap); 164a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif 165fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat setState(Volume::State_Pending); 166fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat } 167a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 168a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat snprintf(msg, sizeof(msg), "Volume %s %s disk inserted (%d:%d)", 169a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat getLabel(), getMountpoint(), mDiskMajor, mDiskMinor); 170a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskInserted, 171a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg, false); 172fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat} 173fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 174ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatvoid DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) { 175da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int major = atoi(evt->findParam("MAJOR")); 176da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int minor = atoi(evt->findParam("MINOR")); 1777b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat 1787b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat int part_num; 1797b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat 1807b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat const char *tmp = evt->findParam("PARTN"); 1817b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat 1827b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat if (tmp) { 1837b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat part_num = atoi(tmp); 1847b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat } else { 18597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Kernel block uevent missing 'PARTN'"); 1867b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat part_num = 1; 1877b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat } 18859abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat 189f3d3ce5e53ab7928f4c292c183c417a1bd051151Nick Kralevich if (part_num > MAX_PARTITIONS || part_num < 1) { 190f3d3ce5e53ab7928f4c292c183c417a1bd051151Nick Kralevich SLOGW("Invalid 'PARTN' value"); 191f3d3ce5e53ab7928f4c292c183c417a1bd051151Nick Kralevich part_num = 1; 192f3d3ce5e53ab7928f4c292c183c417a1bd051151Nick Kralevich } 193f3d3ce5e53ab7928f4c292c183c417a1bd051151Nick Kralevich 1942a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat if (part_num > mDiskNumParts) { 1952a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat mDiskNumParts = part_num; 1962a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat } 1972a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat 198dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if (major != mDiskMajor) { 19997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Partition '%s' has a different major than its disk!", devpath); 200dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat return; 201dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 202a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifdef PARTITION_DEBUG 20397ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Dv:partAdd: part_num = %d, minor = %d\n", part_num, minor); 204a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif 205dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat mPartMinors[part_num -1] = minor; 206dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 20759abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat mPendingPartMap &= ~(1 << part_num); 20859abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat if (!mPendingPartMap) { 209a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifdef PARTITION_DEBUG 21097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Dv:partAdd: Got all partitions - ready to rock!"); 211a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif 2122a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat if (getState() != Volume::State_Formatting) { 2132a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat setState(Volume::State_Idle); 2142a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat } 21559abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat } else { 216a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#ifdef PARTITION_DEBUG 21797ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Dv:partAdd: pending mask now = 0x%x", mPendingPartMap); 218a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat#endif 219a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 220a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 221a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 222a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatvoid DirectVolume::handleDiskChanged(const char *devpath, NetlinkEvent *evt) { 223da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int major = atoi(evt->findParam("MAJOR")); 224da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int minor = atoi(evt->findParam("MINOR")); 225a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 226a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if ((major != mDiskMajor) || (minor != mDiskMinor)) { 227a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return; 228a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 229a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 23097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGI("Volume %s disk has changed", getLabel()); 2317b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat const char *tmp = evt->findParam("NPARTS"); 2327b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat if (tmp) { 2337b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat mDiskNumParts = atoi(tmp); 2347b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat } else { 23597ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGW("Kernel block uevent missing 'NPARTS'"); 2367b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat mDiskNumParts = 1; 2377b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat } 2387b8f2db4b07deaaa2f6f5ffbee0386a394032b08San Mehat 239a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int partmask = 0; 240a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int i; 241a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat for (i = 1; i <= mDiskNumParts; i++) { 242a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat partmask |= (1 << i); 243a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 244a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mPendingPartMap = partmask; 245a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 2462a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat if (getState() != Volume::State_Formatting) { 2472a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat if (mDiskNumParts == 0) { 2482a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat setState(Volume::State_Idle); 2492a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat } else { 2502a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat setState(Volume::State_Pending); 2512a5b8ce09b8836a8463ef9beaaff865c36ca5e6aSan Mehat } 25259abc3c56b432089abfe868c04cdbc3b6d28aee2San Mehat } 253a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat} 254a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 255a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatvoid DirectVolume::handlePartitionChanged(const char *devpath, NetlinkEvent *evt) { 256da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int major = atoi(evt->findParam("MAJOR")); 257da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int minor = atoi(evt->findParam("MINOR")); 25897ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Volume %s %s partition %d:%d changed\n", getLabel(), getMountpoint(), major, minor); 259fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat} 260fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 261ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatvoid DirectVolume::handleDiskRemoved(const char *devpath, NetlinkEvent *evt) { 262da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int major = atoi(evt->findParam("MAJOR")); 263da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int minor = atoi(evt->findParam("MINOR")); 264a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char msg[255]; 265a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 26697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Volume %s %s disk %d:%d removed\n", getLabel(), getMountpoint(), major, minor); 267a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat snprintf(msg, sizeof(msg), "Volume %s %s disk removed (%d:%d)", 268a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat getLabel(), getMountpoint(), major, minor); 269a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeDiskRemoved, 270a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg, false); 271a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat setState(Volume::State_NoMedia); 272fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat} 273fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat 274ae10b91044bf76b40b77d81c169e48e0bbdf6d75San Mehatvoid DirectVolume::handlePartitionRemoved(const char *devpath, NetlinkEvent *evt) { 275da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int major = atoi(evt->findParam("MAJOR")); 276da62e7c00259f6b98696cedb7d031f04951caef0Kenny Root int minor = atoi(evt->findParam("MINOR")); 277a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat char msg[255]; 278a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 27997ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Volume %s %s partition %d:%d removed\n", getLabel(), getMountpoint(), major, minor); 280a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 281a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat /* 282a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * The framework doesn't need to get notified of 283a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * partition removal unless it's mounted. Otherwise 284a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * the removal notification will be sent on the Disk 285a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * itself 286a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat */ 287a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (getState() != Volume::State_Mounted) { 288a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return; 289a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 290a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 291a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if ((dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev) { 292a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat /* 293a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * Yikes, our mounted partition is going away! 294a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat */ 295a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat 296a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat snprintf(msg, sizeof(msg), "Volume %s %s bad removal (%d:%d)", 297a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat getLabel(), getMountpoint(), major, minor); 298a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat mVm->getBroadcaster()->sendBroadcast(ResponseCode::VolumeBadRemoval, 299a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat msg, false); 3001a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat 3011a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat if (mVm->cleanupAsec(this, true)) { 3021a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat SLOGE("Failed to cleanup ASEC - unmount will probably fail!"); 3031a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat } 3041a06edaf4db4e9c520624bcc06e0e13ee470d90eSan Mehat 3054ba8948dc16463053e21cda5744f519a555080d0San Mehat if (Volume::unmountVol(true)) { 30697ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGE("Failed to unmount volume on bad removal (%s)", 307a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat strerror(errno)); 308a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat // XXX: At this point we're screwed for now 309a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } else { 31097ac40e4e6f3ed0bd5d6878d7d8d4a54fcaecb76San Mehat SLOGD("Crisis averted"); 311a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 312a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 313fd7f5875129adfe2845f4f3fffb17db3a89eea25San Mehat} 31449e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat 315dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat/* 316a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat * Called from base to get a list of devicenodes for mounting 317dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat */ 318a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehatint DirectVolume::getDeviceNodes(dev_t *devs, int max) { 319dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 320dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if (mPartIdx == -1) { 321a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat // If the disk has no partitions, try the disk itself 322dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat if (!mDiskNumParts) { 323a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat devs[0] = MKDEV(mDiskMajor, mDiskMinor); 324a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 1; 325dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 326dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat 327a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat int i; 328a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat for (i = 0; i < mDiskNumParts; i++) { 329a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat if (i == max) 330a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat break; 331a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat devs[i] = MKDEV(mDiskMajor, mPartMinors[i]); 332a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat } 333a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return mDiskNumParts; 334dd9b8e92aaf330b48ddb40a7380588ef92b53de6San Mehat } 335a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat devs[0] = MKDEV(mDiskMajor, mPartMinors[mPartIdx -1]); 336a2677e4ad01f250b0765f04adf0acfa6627efc98San Mehat return 1; 33749e2bce5b74129c26a35e25d4693cbfe98c4688eSan Mehat} 338