#include <errno.h>
#include <stdio.h>
#include <string.h>
+#include <sys/stat.h>
#include "libfstools.h"
return point;
}
+/*
+ * Match filesystem type against a bunch of valid types
+ *
+ * jffs2reset may ask if the filesystem type is actually ready for use
+ * with overlayfs before wiping it...
+ */
+static int fs_rootfs_only(char *fstype)
+{
+ if (strncmp(fstype, "ext4", 4) &&
+ strncmp(fstype, "f2fs", 4) &&
+ strncmp(fstype, "jffs2", 5) &&
+ strncmp(fstype, "ubifs", 5)) {
+ ULOG_ERR("block is mounted with wrong fs\n");
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Check if a given device is mounted and return its mountpoint
+ */
char*
find_mount_point(char *block, int root_only)
{
- FILE *fp = fopen("/proc/mounts", "r");
+ FILE *fp = fopen("/proc/self/mountinfo", "r");
static char line[256];
int len = strlen(block);
- char *point = NULL;
+ char *point = NULL, *pos, *tmp, *cpoint, *devname, *fstype;
+ struct stat s;
+ int rstat;
+ unsigned int minor, major;
- if(!fp)
+ if (!fp)
return NULL;
+ rstat = stat(block, &s);
+
while (fgets(line, sizeof(line), fp)) {
- if (!strncmp(line, block, len)) {
- char *p = &line[len + 1];
- char *t = strstr(p, " ");
-
- if (!t) {
- fclose(fp);
- return NULL;
- }
-
- *t = '\0';
- t++;
-
- if (root_only &&
- strncmp(t, "f2fs", 4) &&
- strncmp(t, "jffs2", 5) &&
- strncmp(t, "ubifs", 5)) {
- fclose(fp);
- ULOG_ERR("block is mounted with wrong fs\n");
- return NULL;
- }
- point = p;
+ /* skip first two columns */
+ pos = strchr(line, ' ');
+ if (!pos)
+ continue;
+
+ pos = strchr(pos + 1, ' ');
+ if (!pos)
+ continue;
+
+ /* extract block device major:minor */
+ tmp = ++pos;
+ pos = strchr(pos, ':');
+ if (!pos)
+ continue;
+
+ *pos = '\0';
+ major = atoi(tmp);
+
+ tmp = ++pos;
+ pos = strchr(pos, ' ');
+ if (!pos)
+ continue;
+
+ *pos = '\0';
+ minor = atoi(tmp);
+
+ /* skip another column */
+ pos = strchr(pos + 1, ' ');
+ if (!pos)
+ continue;
+
+ /* get mountpoint */
+ tmp = ++pos;
+ pos = strchr(pos, ' ');
+ if (!pos)
+ continue;
+
+ *pos = '\0';
+ cpoint = tmp;
+
+ /* skip another two columns */
+ pos = strchr(pos + 1, ' ');
+ if (!pos)
+ continue;
+
+ pos = strchr(pos + 1, ' ');
+ if (!pos)
+ continue;
+
+ /* get fstype */
+ tmp = ++pos;
+ pos = strchr(pos, ' ');
+ if (!pos)
+ continue;
+
+ *pos = '\0';
+ fstype = tmp;
+
+ /* get device name */
+ tmp = ++pos;
+ pos = strchr(pos, ' ');
+ if (!pos)
+ continue;
+
+ *pos = '\0';
+ devname = tmp;
+
+ /* if device name matches */
+ if (!strncmp(block, devname, len)) {
+ if (root_only && fs_rootfs_only(fstype))
+ break;
+
+ /* found, return mountpoint */
+ point = strdup(cpoint);
+ break;
+ }
+
+ /* last chance: check if major:minor of block device match */
+ if (rstat)
+ continue;
+
+ if (!S_ISBLK(s.st_mode))
+ continue;
+
+ if (major == major(s.st_rdev) &&
+ minor == minor(s.st_rdev)) {
+ if (root_only && fs_rootfs_only(fstype))
+ break;
+ /* found, return mountpoint */
+ point = strdup(cpoint);
break;
}
}