static void build_fs_mount_list(FsMountList *mounts, Error **errp) { FsMount *mount; char const *mountinfo = "/proc/self/mountinfo"; FILE *fp; char *line = NULL, *dash; size_t n; char check; unsigned int devmajor, devminor; int ret, dir_s, dir_e, type_s, type_e, dev_s, dev_e; fp = fopen(mountinfo, "r"); if (!fp) { build_fs_mount_list_from_mtab(mounts, errp); return; } while (getline(&line, &n, fp) != -1) { ret = sscanf(line, "%*u %*u %u:%u %*s %n%*s%n%c", &devmajor, &devminor, &dir_s, &dir_e, &check); if (ret < 3) { continue; } dash = strstr(line + dir_e, " - "); if (!dash) { continue; } ret = sscanf(dash, " - %n%*s%n %n%*s%n%c", &type_s, &type_e, &dev_s, &dev_e, &check); if (ret < 1) { continue; } line[dir_e] = 0; dash[type_e] = 0; dash[dev_e] = 0; decode_mntname(line + dir_s, dir_e - dir_s); decode_mntname(dash + dev_s, dev_e - dev_s); if (devmajor == 0) { /* btrfs reports major number = 0 */ if (strcmp("btrfs", dash + type_s) != 0 || dev_major_minor(dash + dev_s, &devmajor, &devminor) < 0) { continue; } } mount = g_malloc0(sizeof(FsMount)); mount->dirname = g_strdup(line + dir_s); mount->devtype = g_strdup(dash + type_s); mount->devmajor = devmajor; mount->devminor = devminor; QTAILQ_INSERT_TAIL(mounts, mount, next); } free(line); fclose(fp); }