123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- /*
- * Copyright (C) 2014 John Crispin <blogic@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 2.1
- * as published by the Free Software Foundation
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include <errno.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/stat.h>
- #include <sys/sysmacros.h>
- #include "libfstools.h"
- int
- find_overlay_mount(char *overlay)
- {
- FILE *fp = fopen("/proc/mounts", "r");
- size_t len = strlen(overlay);
- static char line[256];
- int ret = -1;
- if(!fp)
- return ret;
- while (ret && fgets(line, sizeof(line), fp))
- if (len < sizeof(line) && !strncmp(line, overlay, len) && line[len] == ' ')
- ret = 0;
- fclose(fp);
- return ret;
- }
- /*
- * Find path of a device mounted to the given point.
- */
- char*
- find_mount(char *mp)
- {
- FILE *fp = fopen("/proc/mounts", "r");
- static char line[256];
- if(!fp)
- return NULL;
- while (fgets(line, sizeof(line), fp)) {
- char *s, *t = strstr(line, " ");
- if (!t) {
- fclose(fp);
- return NULL;
- }
- *t = '\0';
- t++;
- s = strstr(t, " ");
- if (!s) {
- fclose(fp);
- return NULL;
- }
- *s = '\0';
- if (!strcmp(t, mp)) {
- fclose(fp);
- return line;
- }
- }
- fclose(fp);
- return NULL;
- }
- /*
- * 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/self/mountinfo", "r");
- static char line[256];
- char *point = NULL, *pos, *tmp, *cpoint, *devname, *fstype;
- struct stat s;
- int rstat;
- unsigned int minor, major;
- if (!block)
- return NULL;
- if (!fp)
- return NULL;
- rstat = stat(block, &s);
- while (fgets(line, sizeof(line), fp)) {
- /* 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 (!strcmp(block, devname)) {
- 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;
- }
- }
- fclose(fp);
- return point;
- }
- int
- find_filesystem(char *fs)
- {
- FILE *fp = fopen("/proc/filesystems", "r");
- static char line[256];
- int ret = -1;
- if (!fp) {
- ULOG_ERR("opening /proc/filesystems failed: %m\n");
- goto out;
- }
- while (ret && fgets(line, sizeof(line), fp))
- if (strstr(line, fs))
- ret = 0;
- fclose(fp);
- out:
- return ret;
- }
|