vold: Switch to using libdiskconfig for partition setup.
Also handles an issue where NPARTS=0 on a disk change uevent
Change-Id: I77c56f177dc65df91468bbd7d5fe1889db414d7a
Signed-off-by: San Mehat <san@google.com>
diff --git a/Android.mk b/Android.mk
index 7b18ca0..523601e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -21,7 +21,6 @@
DirectVolume.cpp \
logwrapper.c \
Process.cpp \
- geom_mbr_enc.c \
Fat.cpp \
Loop.cpp \
Devmapper.cpp \
@@ -34,7 +33,7 @@
LOCAL_CFLAGS :=
-LOCAL_SHARED_LIBRARIES := libsysutils libcutils
+LOCAL_SHARED_LIBRARIES := libsysutils libcutils libdiskconfig
include $(BUILD_EXECUTABLE)
diff --git a/DirectVolume.cpp b/DirectVolume.cpp
index dcb1a05..fd99f0c 100644
--- a/DirectVolume.cpp
+++ b/DirectVolume.cpp
@@ -178,6 +178,10 @@
part_num = 1;
}
+ if (part_num > mDiskNumParts) {
+ mDiskNumParts = part_num;
+ }
+
if (major != mDiskMajor) {
LOGE("Partition '%s' has a different major than its disk!", devpath);
return;
@@ -192,7 +196,9 @@
#ifdef PARTITION_DEBUG
LOGD("Dv:partAdd: Got all partitions - ready to rock!");
#endif
- setState(Volume::State_Idle);
+ if (getState() != Volume::State_Formatting) {
+ setState(Volume::State_Idle);
+ }
} else {
#ifdef PARTITION_DEBUG
LOGD("Dv:partAdd: pending mask now = 0x%x", mPendingPartMap);
@@ -224,15 +230,19 @@
}
mPendingPartMap = partmask;
- if (mDiskNumParts == 0) {
- setState(Volume::State_Idle);
- } else {
- setState(Volume::State_Pending);
+ if (getState() != Volume::State_Formatting) {
+ if (mDiskNumParts == 0) {
+ setState(Volume::State_Idle);
+ } else {
+ setState(Volume::State_Pending);
+ }
}
-
}
void DirectVolume::handlePartitionChanged(const char *devpath, NetlinkEvent *evt) {
+ int major = atoi(evt->findParam("MAJOR"));
+ int minor = atoi(evt->findParam("MINOR"));
+ LOGD("Volume %s %s partition %d:%d changed\n", getLabel(), getMountpoint(), major, minor);
}
void DirectVolume::handleDiskRemoved(const char *devpath, NetlinkEvent *evt) {
diff --git a/Volume.cpp b/Volume.cpp
index 07b96a2..d592c5f 100644
--- a/Volume.cpp
+++ b/Volume.cpp
@@ -30,7 +30,7 @@
#include <cutils/properties.h>
-#include "diskmbr.h"
+#include <diskconfig/diskconfig.h>
#define LOG_TAG "Vold"
@@ -185,6 +185,7 @@
MAJOR(diskNode), MINOR(diskNode));
LOGI("Formatting volume %s (%s)", getLabel(), devicePath);
+ setState(Volume::State_Formatting);
if (initializeMbr(devicePath)) {
LOGE("Failed to initialize MBR (%s)", strerror(errno));
@@ -199,6 +200,7 @@
goto err;
}
+ setState(Volume::State_Idle);
return 0;
err:
return -1;
@@ -423,6 +425,7 @@
int Volume::doUnmount(const char *path, bool force) {
int retries = 10;
+ LOGD("Unmounting {%s}, force = %d", path, force);
while (retries--) {
if (!umount(path) || errno == EINVAL || errno == ENOENT) {
LOGI("%s sucessfully unmounted", path);
@@ -534,45 +537,41 @@
}
int Volume::initializeMbr(const char *deviceNode) {
- int fd, rc;
- unsigned char block[512];
- struct dos_partition part;
- unsigned int nr_sec;
+ struct disk_info dinfo;
- if ((fd = open(deviceNode, O_RDWR)) < 0) {
- LOGE("Error opening disk file (%s)", strerror(errno));
+ memset(&dinfo, 0, sizeof(dinfo));
+
+ if (!(dinfo.part_lst = (struct part_info *) malloc(MAX_NUM_PARTS * sizeof(struct part_info)))) {
+ LOGE("Failed to malloc prt_lst");
return -1;
}
- if (ioctl(fd, BLKGETSIZE, &nr_sec)) {
- LOGE("Unable to get device size (%s)", strerror(errno));
- close(fd);
- return -1;
+ memset(dinfo.part_lst, 0, MAX_NUM_PARTS * sizeof(struct part_info));
+ dinfo.device = strdup(deviceNode);
+ dinfo.scheme = PART_SCHEME_MBR;
+ dinfo.sect_size = 512;
+ dinfo.skip_lba = 2048;
+ dinfo.num_lba = 0;
+ dinfo.num_parts = 1;
+
+ struct part_info *pinfo = &dinfo.part_lst[0];
+
+ pinfo->name = strdup("android_sdcard");
+ pinfo->flags |= PART_ACTIVE_FLAG;
+ pinfo->type = PC_PART_TYPE_FAT32;
+ pinfo->len_kb = -1;
+
+ int rc = apply_disk_config(&dinfo, 0);
+
+ if (rc) {
+ LOGE("Failed to apply disk configuration (%d)", rc);
+ goto out;
}
- memset(&part, 0, sizeof(part));
- part.dp_flag = 0x80;
- part.dp_typ = 0xc;
- part.dp_start = ((1024 * 64) / 512) + 1;
- part.dp_size = nr_sec - part.dp_start;
+ out:
+ free(pinfo->name);
+ free(dinfo.device);
+ free(dinfo.part_lst);
- memset(block, 0, sizeof(block));
- block[0x1fe] = 0x55;
- block[0x1ff] = 0xaa;
-
- dos_partition_enc(block + DOSPARTOFF, &part);
-
- if (write(fd, block, sizeof(block)) < 0) {
- LOGE("Error writing MBR (%s)", strerror(errno));
- close(fd);
- return -1;
- }
-
- if (ioctl(fd, BLKRRPART, NULL) < 0) {
- LOGE("Error re-reading partition table (%s)", strerror(errno));
- close(fd);
- return -1;
- }
- close(fd);
- return 0;
+ return rc;
}
diff --git a/diskmbr.h b/diskmbr.h
deleted file mode 100644
index f160575..0000000
--- a/diskmbr.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*-
- * Copyright (c) 1987, 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)disklabel.h 8.2 (Berkeley) 7/10/94
- * $FreeBSD: src/sys/sys/diskmbr.h,v 1.99.2.1 2005/01/31 23:26:56 imp Exp $
- */
-
-#ifndef _SYS_DISKMBR_H_
-#define _SYS_DISKMBR_H_
-
-#define DOSBBSECTOR 0 /* DOS boot block relative sector number */
-#define DOSPARTOFF 446
-#define DOSPARTSIZE 16
-#define NDOSPART 4
-#define NEXTDOSPART 32
-#define DOSMAGICOFFSET 510
-#define DOSMAGIC 0xAA55
-
-#define DOSPTYP_386BSD 0xa5 /* 386BSD partition type */
-#define DOSPTYP_LINSWP 0x82 /* Linux swap partition */
-#define DOSPTYP_LINUX 0x83 /* Linux partition */
-#define DOSPTYP_PMBR 0xee /* GPT Protective MBR */
-#define DOSPTYP_EXT 5 /* DOS extended partition */
-#define DOSPTYP_EXTLBA 15 /* DOS extended partition */
-
-struct dos_partition {
- unsigned char dp_flag; /* bootstrap flags */
- unsigned char dp_shd; /* starting head */
- unsigned char dp_ssect; /* starting sector */
- unsigned char dp_scyl; /* starting cylinder */
- unsigned char dp_typ; /* partition type */
- unsigned char dp_ehd; /* end head */
- unsigned char dp_esect; /* end sector */
- unsigned char dp_ecyl; /* end cylinder */
- u_int32_t dp_start; /* absolute starting sector number */
- u_int32_t dp_size; /* partition size in sectors */
-};
-#ifdef CTASSERT
-CTASSERT(sizeof (struct dos_partition) == DOSPARTSIZE);
-#endif
-
-#define DPSECT(s) ((s) & 0x3f) /* isolate relevant bits of sector */
-#define DPCYL(c, s) ((c) + (((s) & 0xc0)<<2)) /* and those that are cylinder */
-
-#define DIOCSMBR _IOW('M', 129, u_char[512])
-
-#endif /* !_SYS_DISKMBR_H_ */
diff --git a/geom_mbr_enc.c b/geom_mbr_enc.c
deleted file mode 100644
index f1f8339..0000000
--- a/geom_mbr_enc.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*-
- * Copyright (c) 2003 Poul-Henning Kamp
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* Functions to encode or decode struct dos_partition into a bytestream
- * of correct endianess and packing. These functions do no validation
- * or sanity checking, they only pack/unpack the fields correctly.
- *
- * NB! This file must be usable both in kernel and userland.
- */
-
-#include <sys/types.h>
-#include <sys/endian.h>
-
-#include "diskmbr.h"
-
-static __inline uint32_t __unused
-le32dec(const void *buf)
-{
- const uint8_t *p = (const uint8_t *)buf;
-
- return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
-}
-
-static __inline void
-le32enc(void *pp, uint32_t u)
-{
- unsigned char *p = (unsigned char *)pp;
-
- p[0] = u & 0xff;
- p[1] = (u >> 8) & 0xff;
- p[2] = (u >> 16) & 0xff;
- p[3] = (u >> 24) & 0xff;
-}
-
-void
-dos_partition_dec(void const *pp, struct dos_partition *d)
-{
- unsigned char const *p = pp;
-
- d->dp_flag = p[0];
- d->dp_shd = p[1];
- d->dp_ssect = p[2];
- d->dp_scyl = p[3];
- d->dp_typ = p[4];
- d->dp_ehd = p[5];
- d->dp_esect = p[6];
- d->dp_ecyl = p[7];
- d->dp_start = le32dec(p + 8);
- d->dp_size = le32dec(p + 12);
-}
-
-void
-dos_partition_enc(void *pp, struct dos_partition *d)
-{
- unsigned char *p = pp;
-
- p[0] = d->dp_flag;
- p[1] = d->dp_shd;
- p[2] = d->dp_ssect;
- p[3] = d->dp_scyl;
- p[4] = d->dp_typ;
- p[5] = d->dp_ehd;
- p[6] = d->dp_esect;
- p[7] = d->dp_ecyl;
- le32enc(p + 8, d->dp_start);
- le32enc(p + 12, d->dp_size);
-}