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);
-}