Index: bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/extlinux/mountinfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,277 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2012 Intel Corporation; All Rights Reserved
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include "mountinfo.h"
+
+/*
+ * Parse /proc/self/mountinfo
+ */
+static int get_string(FILE *f, char *string_buf, size_t string_len, char *ec)
+{
+    int ch;
+    char *p = string_buf;
+
+    for (;;) {
+	if (!string_len)
+	    return -2;		/* String too long */
+
+	ch = getc(f);
+	if (ch == EOF) {
+	    return -1;		/* Got EOF */
+	} else if (ch == ' ' || ch == '\t' || ch == '\n') {
+	    *ec = ch;
+	    *p = '\0';
+	    return p - string_buf;
+	} else if (ch == '\\') {
+	    /* Should always be followed by 3 octal digits in 000..377 */
+	    int oc = 0;
+	    int i;
+	    for (i = 0; i < 3; i++) {
+		ch = getc(f);
+		if (ch < '0' || ch > '7' || (i == 0 && ch > '3'))
+		    return -1;	/* Bad escape sequence */
+		oc = (oc << 3) + (ch - '0');
+	    }
+	    if (!oc)
+		return -1;	/* We can't handle \000 */
+	    *p++ = oc;
+	    string_len--;
+	} else {
+	    *p++ = ch;
+	    string_len--;
+	}
+    }
+}
+
+static void free_mountinfo(struct mountinfo *m)
+{
+    struct mountinfo *nx;
+
+    while (m) {
+	free((char *)m->root);
+	free((char *)m->path);
+	free((char *)m->fstype);
+	free((char *)m->devpath);
+	free((char *)m->mountopt);
+	nx = m->next;
+	free(m);
+	m = nx;
+    }
+}
+
+static struct mountinfo *head = NULL, **tail = &head;
+
+static void parse_mountinfo(void)
+{
+    FILE *f;
+    struct mountinfo *m, *mm;
+    char string_buf[PATH_MAX*8];
+    int n;
+    char ec, *ep;
+    unsigned int ma, mi;
+
+    f = fopen("/proc/self/mountinfo", "r");
+    if (!f)
+	return;
+
+    for (;;) {
+	m = malloc(sizeof(struct mountinfo));
+	if (!m)
+	    break;
+	memset(m, 0, sizeof *m);
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	m->mountid = strtoul(string_buf, &ep, 10);
+	if (*ep)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	m->parentid = strtoul(string_buf, &ep, 10);
+	if (*ep)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	if (sscanf(string_buf, "%u:%u", &ma, &mi) != 2)
+	    break;
+
+	m->dev = makedev(ma, mi);
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 1 || ec == '\n' || string_buf[0] != '/')
+	    break;
+
+	m->root = strdup(string_buf);
+	if (!m->root)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 1 || ec == '\n' || string_buf[0] != '/')
+	    break;
+
+	m->path = strdup(string_buf);
+	m->pathlen = (n == 1) ? 0 : n; /* Treat / as empty */
+
+	/* Skip tagged attributes */
+	do {
+	    n = get_string(f, string_buf, sizeof string_buf, &ec);
+	    if (n < 0 || ec == '\n')
+		goto quit;
+	} while (n != 1 || string_buf[0] != '-');
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	m->fstype = strdup(string_buf);
+	if (!m->fstype)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0 || ec == '\n')
+	    break;
+
+	m->devpath = strdup(string_buf);
+	if (!m->devpath)
+	    break;
+
+	n = get_string(f, string_buf, sizeof string_buf, &ec);
+	if (n < 0)
+	    break;
+
+	m->mountopt = strdup(string_buf);
+	if (!m->mountopt)
+	    break;
+
+	/* Skip any previously unknown fields */
+	while (ec != '\n' && ec != EOF)
+	    ec = getc(f);
+
+	*tail = m;
+	tail = &m->next;
+    }
+quit:
+    fclose(f);
+    free_mountinfo(m);
+
+    /* Create parent links */
+    for (m = head; m; m = m->next) {
+	for (mm = head; mm; mm = mm->next) {
+	    if (m->parentid == mm->mountid) {
+		m->parent = mm;
+		if (!strcmp(m->path, mm->path))
+		    mm->hidden = 1; /* Hidden under another mount */
+		break;
+	    }
+	}
+    }
+}
+
+const struct mountinfo *find_mount(const char *path, char **subpath)
+{
+    static int done_init;
+    char *real_path;
+    const struct mountinfo *m, *best;
+    struct stat st;
+    int len, matchlen;
+
+    if (!done_init) {
+	parse_mountinfo();
+	done_init = 1;
+    }
+
+    if (stat(path, &st))
+	return NULL;
+
+    real_path = realpath(path, NULL);
+    if (!real_path)
+	return NULL;
+
+    /*
+     * Tricky business: we need the longest matching subpath
+     * which isn't a parent of the same subpath.
+     */
+    len = strlen(real_path);
+    matchlen = 0;
+    best = NULL;
+    for (m = head; m; m = m->next) {
+	if (m->hidden)
+	    continue;		/* Hidden underneath another mount */
+
+	if (m->pathlen > len)
+	    continue;		/* Cannot possibly match */
+
+	if (m->pathlen < matchlen)
+	    continue;		/* No point in testing this one */
+
+	if (st.st_dev == m->dev &&
+	    !memcmp(m->path, real_path, m->pathlen) &&
+	    (real_path[m->pathlen] == '/' || real_path[m->pathlen] == '\0')) {
+	    matchlen = m->pathlen;
+	    best = m;
+	}
+    }
+
+    if (best && subpath) {
+	if (real_path[best->pathlen] == '\0')
+	    *subpath = strdup("/");
+	else
+	    *subpath = strdup(real_path + best->pathlen);
+    }
+
+    return best;
+}
+
+#ifdef TEST
+
+int main(int argc, char *argv[])
+{
+    int i;
+    const struct mountinfo *m;
+    char *subpath;
+
+    parse_mountinfo();
+
+    for (i = 1; i < argc; i++) {
+	m = find_mount(argv[i], &subpath);
+	if (!m) {
+	    printf("%s: %s\n", argv[i], strerror(errno));
+	    continue;
+	}
+
+	printf("%s -> %s @ %s(%u,%u):%s %s %s\n",
+	       argv[i], subpath, m->devpath, major(m->dev), minor(m->dev),
+	       m->root, m->fstype, m->mountopt);
+	printf("Usable device: %s\n", find_device(m->dev, m->devpath));
+	free(subpath);
+    }
+
+    return 0;
+}
+
+#endif
