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