/** * mnt_table_parse_mtab: * @tb: table * @filename: overwrites default (/etc/mtab or $LIBMOUNT_MTAB) or NULL * * This function parses /etc/mtab or /proc/self/mountinfo + * /run/mount/utabs or /proc/mounts. * * See also mnt_table_set_parser_errcb(). * * Returns: 0 on success or negative number in case of error. */ int mnt_table_parse_mtab(struct libmnt_table *tb, const char *filename) { int rc; const char *utab = NULL; struct libmnt_table *u_tb; assert(tb); if (mnt_has_regular_mtab(&filename, NULL)) { DBG(TAB, mnt_debug_h(tb, "force %s usage", filename)); rc = mnt_table_parse_file(tb, filename); if (!rc) return 0; filename = NULL; /* failed */ } /* * useless /etc/mtab * -- read kernel information from /proc/self/mountinfo */ tb->fmt = MNT_FMT_MOUNTINFO; rc = mnt_table_parse_file(tb, _PATH_PROC_MOUNTINFO); if (rc) { /* hmm, old kernel? ...try /proc/mounts */ tb->fmt = MNT_FMT_MTAB; return mnt_table_parse_file(tb, _PATH_PROC_MOUNTS); } if (mnt_table_get_nents(tb) == 0) return 0; /* empty, ignore utab */ /* * try to read the user specific information from /run/mount/utabs */ utab = mnt_get_utab_path(); if (!utab || is_file_empty(utab)) return 0; u_tb = mnt_new_table(); if (!u_tb) return -ENOMEM; u_tb->fmt = MNT_FMT_UTAB; mnt_table_set_parser_fltrcb(u_tb, tb->fltrcb, tb->fltrcb_data); if (mnt_table_parse_file(u_tb, utab) == 0) { struct libmnt_fs *u_fs; struct libmnt_iter itr; mnt_reset_iter(&itr, MNT_ITER_BACKWARD); /* merge user options into mountinfo from the kernel */ while(mnt_table_next_fs(u_tb, &itr, &u_fs) == 0) mnt_table_merge_user_fs(tb, u_fs); } mnt_unref_table(u_tb); return 0; }
/** * mnt_table_parse_mtab: * @tb: table * @filename: overwrites default (/etc/mtab or $LIBMOUNT_MTAB) or NULL * * This function parses /etc/mtab or /proc/self/mountinfo + * /run/mount/utabs or /proc/mounts. * * See also mnt_table_set_parser_errcb(). * * Returns: 0 on success or negative number in case of error. */ int mnt_table_parse_mtab(struct libmnt_table *tb, const char *filename) { int rc; const char *utab = NULL; if (mnt_has_regular_mtab(&filename, NULL)) { DBG(TAB, mnt_debug_h(tb, "force %s usage", filename)); rc = mnt_table_parse_file(tb, filename); if (!rc) return 0; filename = NULL; /* failed */ } /* * useless /etc/mtab * -- read kernel information from /proc/self/mountinfo */ tb->fmt = MNT_FMT_MOUNTINFO; rc = mnt_table_parse_file(tb, _PATH_PROC_MOUNTINFO); if (rc) { /* hmm, old kernel? ...try /proc/mounts */ tb->fmt = MNT_FMT_MTAB; return mnt_table_parse_file(tb, _PATH_PROC_MOUNTS); } /* * try to read user specific information from /run/mount/utabs */ utab = mnt_get_utab_path(); if (utab) { struct libmnt_table *u_tb = __mnt_new_table_from_file(utab, MNT_FMT_UTAB); if (u_tb) { struct libmnt_fs *u_fs; struct libmnt_iter itr; mnt_reset_iter(&itr, MNT_ITER_BACKWARD); /* merge user options into mountinfo from kernel */ while(mnt_table_next_fs(u_tb, &itr, &u_fs) == 0) mnt_table_merge_user_fs(tb, u_fs); mnt_free_table(u_tb); } } return 0; }
/* default filename is /proc/self/mountinfo */ int __mnt_table_parse_mtab(struct libmnt_table *tb, const char *filename, struct libmnt_table *u_tb) { int rc = 0, priv_utab = 0; assert(tb); if (filename) DBG(TAB, ul_debugobj(tb, "%s reuested as mtab", filename)); #ifdef USE_LIBMOUNT_SUPPORT_MTAB if (mnt_has_regular_mtab(&filename, NULL)) { DBG(TAB, ul_debugobj(tb, "force mtab usage [filename=%s]", filename)); rc = mnt_table_parse_file(tb, filename); /* * If @filename forces us to read from /proc then also read * utab file to merge userspace mount options. */ if (rc == 0 && is_mountinfo(tb)) goto read_utab; if (!rc) return 0; filename = NULL; /* failed */ } else filename = NULL; /* mtab useless */ #endif if (!filename || strcmp(filename, _PATH_PROC_MOUNTINFO) == 0) { filename = _PATH_PROC_MOUNTINFO; tb->fmt = MNT_FMT_MOUNTINFO; DBG(TAB, ul_debugobj(tb, "mtab parse: #1 read mountinfo")); } else tb->fmt = MNT_FMT_GUESS; rc = mnt_table_parse_file(tb, filename); if (rc) { /* hmm, old kernel? ...try /proc/mounts */ tb->fmt = MNT_FMT_MTAB; return mnt_table_parse_file(tb, _PATH_PROC_MOUNTS); } if (!is_mountinfo(tb)) return 0; #ifdef USE_LIBMOUNT_SUPPORT_MTAB read_utab: #endif DBG(TAB, ul_debugobj(tb, "mtab parse: #2 read utab")); if (mnt_table_get_nents(tb) == 0) return 0; /* empty, ignore utab */ /* * try to read the user specific information from /run/mount/utabs */ if (!u_tb) { const char *utab = mnt_get_utab_path(); if (!utab || is_file_empty(utab)) return 0; u_tb = mnt_new_table(); if (!u_tb) return -ENOMEM; u_tb->fmt = MNT_FMT_UTAB; mnt_table_set_parser_fltrcb(u_tb, tb->fltrcb, tb->fltrcb_data); rc = mnt_table_parse_file(u_tb, utab); priv_utab = 1; } DBG(TAB, ul_debugobj(tb, "mtab parse: #3 merge utab")); if (rc == 0) { struct libmnt_fs *u_fs; struct libmnt_iter itr; mnt_reset_iter(&itr, MNT_ITER_BACKWARD); /* merge user options into mountinfo from the kernel */ while(mnt_table_next_fs(u_tb, &itr, &u_fs) == 0) mnt_table_merge_user_fs(tb, u_fs); } if (priv_utab) mnt_unref_table(u_tb); return 0; }