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>
gugelfrei
San Mehat 15 years ago
parent d071596fd9
commit 2a5b8ce09b

@ -21,7 +21,6 @@ LOCAL_SRC_FILES:= \
DirectVolume.cpp \
logwrapper.c \
Process.cpp \
geom_mbr_enc.c \
Fat.cpp \
Loop.cpp \
Devmapper.cpp \
@ -34,7 +33,7 @@ LOCAL_C_INCLUDES := $(KERNEL_HEADERS) -I../../frameworks/base/include/
LOCAL_CFLAGS :=
LOCAL_SHARED_LIBRARIES := libsysutils libcutils
LOCAL_SHARED_LIBRARIES := libsysutils libcutils libdiskconfig
include $(BUILD_EXECUTABLE)

@ -178,6 +178,10 @@ void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt)
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 @@ void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt)
#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 @@ void DirectVolume::handleDiskChanged(const char *devpath, NetlinkEvent *evt) {
}
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) {

@ -30,7 +30,7 @@
#include <cutils/properties.h>
#include "diskmbr.h"
#include <diskconfig/diskconfig.h>
#define LOG_TAG "Vold"
@ -185,6 +185,7 @@ int Volume::formatVol() {
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 @@ int Volume::formatVol() {
goto err;
}
setState(Volume::State_Idle);
return 0;
err:
return -1;
@ -423,6 +425,7 @@ int Volume::doMoveMount(const char *src, const char *dst, bool force) {
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 @@ out_nomedia:
}
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));
return -1;
}
memset(&dinfo, 0, sizeof(dinfo));
if (ioctl(fd, BLKGETSIZE, &nr_sec)) {
LOGE("Unable to get device size (%s)", strerror(errno));
close(fd);
if (!(dinfo.part_lst = (struct part_info *) malloc(MAX_NUM_PARTS * sizeof(struct part_info)))) {
LOGE("Failed to malloc prt_lst");
return -1;
}
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;
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;
memset(block, 0, sizeof(block));
block[0x1fe] = 0x55;
block[0x1ff] = 0xaa;
struct part_info *pinfo = &dinfo.part_lst[0];
dos_partition_enc(block + DOSPARTOFF, &part);
pinfo->name = strdup("android_sdcard");
pinfo->flags |= PART_ACTIVE_FLAG;
pinfo->type = PC_PART_TYPE_FAT32;
pinfo->len_kb = -1;
if (write(fd, block, sizeof(block)) < 0) {
LOGE("Error writing MBR (%s)", strerror(errno));
close(fd);
return -1;
}
int rc = apply_disk_config(&dinfo, 0);
if (ioctl(fd, BLKRRPART, NULL) < 0) {
LOGE("Error re-reading partition table (%s)", strerror(errno));
close(fd);
return -1;
if (rc) {
LOGE("Failed to apply disk configuration (%d)", rc);
goto out;
}
close(fd);
return 0;
out:
free(pinfo->name);
free(dinfo.device);
free(dinfo.part_lst);
return rc;
}

@ -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_ */

@ -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);
}
Loading…
Cancel
Save