mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
mount-tool: use libmount to parse /proc/self/mountinfo
Same motivation as in other places: let's use a single logic to parse this. Use path_equal() to compare the path. A bug in error handling is fixed: if we failed after the GREEDY_REALLOC but before the line that sets the last item to NULL, we would jump to _cleanup_strv_free_ with the strv unterminated. Let's use GREEDY_REALLOC0 to avoid the issue.
This commit is contained in:
parent
13dcfe4661
commit
7d991d4818
@ -2470,6 +2470,7 @@ exe = executable('systemd-mount',
|
||||
'src/mount/mount-tool.c',
|
||||
include_directories : includes,
|
||||
link_with : [libshared],
|
||||
dependencies: [libmount],
|
||||
install_rpath : rootlibexecdir,
|
||||
install : true)
|
||||
public_programs += exe
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "fstab-util.h"
|
||||
#include "libmount-util.h"
|
||||
#include "main-func.h"
|
||||
#include "mount-util.h"
|
||||
#include "mountpoint-util.h"
|
||||
@ -713,9 +714,11 @@ static int start_transient_automount(
|
||||
}
|
||||
|
||||
static int find_mount_points(const char *what, char ***list) {
|
||||
_cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
size_t bufsize = 0, n = 0;
|
||||
int r;
|
||||
|
||||
assert(what);
|
||||
assert(list);
|
||||
@ -723,55 +726,47 @@ static int find_mount_points(const char *what, char ***list) {
|
||||
/* Returns all mount points obtained from /proc/self/mountinfo in *list,
|
||||
* and the number of mount points as return value. */
|
||||
|
||||
proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
|
||||
if (!proc_self_mountinfo)
|
||||
return log_error_errno(errno, "Can't open /proc/self/mountinfo: %m");
|
||||
table = mnt_new_table();
|
||||
iter = mnt_new_iter(MNT_ITER_FORWARD);
|
||||
if (!table || !iter)
|
||||
return log_oom();
|
||||
|
||||
r = mnt_table_parse_mtab(table, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *path = NULL, *where = NULL, *dev = NULL;
|
||||
int r;
|
||||
struct libmnt_fs *fs;
|
||||
const char *source, *target;
|
||||
|
||||
r = fscanf(proc_self_mountinfo,
|
||||
"%*s " /* (1) mount id */
|
||||
"%*s " /* (2) parent id */
|
||||
"%*s " /* (3) major:minor */
|
||||
"%*s " /* (4) root */
|
||||
"%ms " /* (5) mount point */
|
||||
"%*s" /* (6) mount options */
|
||||
"%*[^-]" /* (7) optional fields */
|
||||
"- " /* (8) separator */
|
||||
"%*s " /* (9) file system type */
|
||||
"%ms" /* (10) mount source */
|
||||
"%*s" /* (11) mount options 2 */
|
||||
"%*[^\n]", /* some rubbish at the end */
|
||||
&path, &dev);
|
||||
if (r != 2) {
|
||||
if (r == EOF)
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!streq(what, dev))
|
||||
continue;
|
||||
|
||||
r = cunescape(path, UNESCAPE_RELAX, &where);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r == 1)
|
||||
break;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
||||
|
||||
source = mnt_fs_get_source(fs);
|
||||
target = mnt_fs_get_target(fs);
|
||||
if (!source || !target)
|
||||
continue;
|
||||
|
||||
if (!path_equal(source, what))
|
||||
continue;
|
||||
|
||||
/* one extra slot is needed for the terminating NULL */
|
||||
if (!GREEDY_REALLOC(l, bufsize, n + 2))
|
||||
if (!GREEDY_REALLOC0(l, bufsize, n + 2))
|
||||
return log_oom();
|
||||
|
||||
l[n++] = TAKE_PTR(where);
|
||||
l[n] = strdup(target);
|
||||
if (!l[n])
|
||||
return log_oom();
|
||||
n++;
|
||||
}
|
||||
|
||||
if (!GREEDY_REALLOC(l, bufsize, n + 1))
|
||||
if (!GREEDY_REALLOC0(l, bufsize, n + 1))
|
||||
return log_oom();
|
||||
|
||||
l[n] = NULL;
|
||||
*list = TAKE_PTR(l);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user