]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - libmount/src/fs.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 * This file is part of libmount from util-linux project.
5 * Copyright (C) 2008-2018 Karel Zak <kzak@redhat.com>
7 * libmount is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
16 * @short_description: represents one entry from fstab, mtab, or mountinfo file
29 * The initial refcount is 1, and needs to be decremented to
30 * release the resources of the filesystem.
32 * Returns: newly allocated struct libmnt_fs.
34 struct libmnt_fs
*mnt_new_fs(void)
36 struct libmnt_fs
*fs
= calloc(1, sizeof(*fs
));
41 INIT_LIST_HEAD(&fs
->ents
);
42 /*DBG(FS, ul_debugobj(fs, "alloc"));*/
50 * Deallocates the fs. This function does not care about reference count. Don't
51 * use this function directly -- it's better to use mnt_unref_fs().
53 * The reference counting is supported since util-linux v2.24.
55 void mnt_free_fs(struct libmnt_fs
*fs
)
60 DBG(FS
, ul_debugobj(fs
, "free [refcount=%d]", fs
->refcount
));
70 * Resets (zeroize) @fs.
72 void mnt_reset_fs(struct libmnt_fs
*fs
)
93 free(fs
->user_optstr
);
98 memset(fs
, 0, sizeof(*fs
));
99 INIT_LIST_HEAD(&fs
->ents
);
107 * Increments reference counter.
109 void mnt_ref_fs(struct libmnt_fs
*fs
)
113 /*DBG(FS, ul_debugobj(fs, "ref=%d", fs->refcount));*/
121 * De-increments reference counter, on zero the @fs is automatically
122 * deallocated by mnt_free_fs().
124 void mnt_unref_fs(struct libmnt_fs
*fs
)
128 /*DBG(FS, ul_debugobj(fs, "unref=%d", fs->refcount));*/
129 if (fs
->refcount
<= 0)
134 static inline int update_str(char **dest
, const char *src
)
144 return 0; /* source (old) is empty */
147 sz
= strlen(src
) + 1;
148 x
= realloc(*dest
, sz
);
152 memcpy(*dest
, src
, sz
);
156 static inline int cpy_str_at_offset(void *new, const void *old
, size_t offset
)
158 char **o
= (char **) ((char *) old
+ offset
);
159 char **n
= (char **) ((char *) new + offset
);
162 return 0; /* already set, don't overwrite */
164 return update_str(n
, *o
);
169 * @dest: destination FS
172 * If @dest is NULL, then a new FS is allocated, if any @dest field is already
173 * set, then the field is NOT overwritten.
175 * This function does not copy userdata (se mnt_fs_set_userdata()). A new copy is
176 * not linked with any existing mnt_tab.
178 * Returns: @dest or NULL in case of error
180 struct libmnt_fs
*mnt_copy_fs(struct libmnt_fs
*dest
,
181 const struct libmnt_fs
*src
)
183 const struct libmnt_fs
*org
= dest
;
196 dest
->parent
= src
->parent
;
197 dest
->devno
= src
->devno
;
198 dest
->tid
= src
->tid
;
200 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, source
)))
202 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagname
)))
204 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagval
)))
206 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, root
)))
208 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, swaptype
)))
210 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, target
)))
212 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fstype
)))
214 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, optstr
)))
216 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, vfs_optstr
)))
218 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fs_optstr
)))
220 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, user_optstr
)))
222 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, attrs
)))
224 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, bindsrc
)))
227 dest
->freq
= src
->freq
;
228 dest
->passno
= src
->passno
;
229 dest
->flags
= src
->flags
;
230 dest
->size
= src
->size
;
231 dest
->usedsize
= src
->usedsize
;
232 dest
->priority
= src
->priority
;
242 * This function copies all @fs description except information that does not
243 * belong to /etc/mtab (e.g. VFS and userspace mount options with MNT_NOMTAB
246 * Returns: copy of @fs.
248 struct libmnt_fs
*mnt_copy_mtab_fs(const struct libmnt_fs
*fs
)
250 struct libmnt_fs
*n
= mnt_new_fs();
256 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, source
)))
258 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, target
)))
260 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fstype
)))
263 if (fs
->vfs_optstr
) {
265 mnt_optstr_get_options(fs
->vfs_optstr
, &p
,
266 mnt_get_builtin_optmap(MNT_LINUX_MAP
),
271 if (fs
->user_optstr
) {
273 mnt_optstr_get_options(fs
->user_optstr
, &p
,
274 mnt_get_builtin_optmap(MNT_USERSPACE_MAP
),
279 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fs_optstr
)))
282 /* we cannot copy original optstr, the new optstr has to be without
283 * non-mtab options -- so, let's generate a new string */
284 n
->optstr
= mnt_fs_strdup_options(n
);
287 n
->passno
= fs
->passno
;
288 n
->flags
= fs
->flags
;
298 * mnt_fs_get_userdata:
299 * @fs: struct libmnt_file instance
301 * Returns: private data set by mnt_fs_set_userdata() or NULL.
303 void *mnt_fs_get_userdata(struct libmnt_fs
*fs
)
311 * mnt_fs_set_userdata:
312 * @fs: struct libmnt_file instance
315 * The "userdata" are library independent data.
317 * Returns: 0 or negative number in case of error (if @fs is NULL).
319 int mnt_fs_set_userdata(struct libmnt_fs
*fs
, void *data
)
328 * mnt_fs_get_srcpath:
329 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
331 * The mount "source path" is:
332 * - a directory for 'bind' mounts (in fstab or mtab only)
333 * - a device name for standard mounts
335 * See also mnt_fs_get_tag() and mnt_fs_get_source().
337 * Returns: mount source path or NULL in case of error or when the path
340 const char *mnt_fs_get_srcpath(struct libmnt_fs
*fs
)
347 return NULL
; /* the source contains a "NAME=value" */
353 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
355 * Returns: mount source. Note that the source could be unparsed TAG
356 * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag().
358 const char *mnt_fs_get_source(struct libmnt_fs
*fs
)
360 return fs
? fs
->source
: NULL
;
364 * Used by the parser ONLY (@source has to be freed on error)
366 int __mnt_fs_set_source_ptr(struct libmnt_fs
*fs
, char *source
)
368 char *t
= NULL
, *v
= NULL
;
372 if (source
&& blkid_parse_tag_string(source
, &t
, &v
) == 0 &&
373 !mnt_valid_tagname(t
)) {
374 /* parsable but unknown tag -- ignore */
380 if (fs
->source
!= source
)
394 * @fs: fstab/mtab/mountinfo entry
395 * @source: new source
397 * This function creates a private copy (strdup()) of @source.
399 * Returns: 0 on success or negative number in case of error.
401 int mnt_fs_set_source(struct libmnt_fs
*fs
, const char *source
)
415 rc
= __mnt_fs_set_source_ptr(fs
, p
);
422 * mnt_fs_streq_srcpath:
426 * Compares @fs source path with @path. The redundant slashes are ignored.
427 * This function compares strings and does not canonicalize the paths.
428 * See also more heavy and generic mnt_fs_match_source().
430 * Returns: 1 if @fs source path equal to @path, otherwise 0.
432 int mnt_fs_streq_srcpath(struct libmnt_fs
*fs
, const char *path
)
439 p
= mnt_fs_get_srcpath(fs
);
441 if (!mnt_fs_is_pseudofs(fs
))
442 return streq_paths(p
, path
);
447 return p
&& path
&& strcmp(p
, path
) == 0;
453 * @tb: table that contains @fs
455 * Returns: 0 or negative number on error (if @fs or @tb is NULL).
459 int mnt_fs_get_table(struct libmnt_fs
*fs
, struct libmnt_table
**tb
)
469 * mnt_fs_streq_target:
473 * Compares @fs target path with @path. The redundant slashes are ignored.
474 * This function compares strings and does not canonicalize the paths.
475 * See also more generic mnt_fs_match_target().
477 * Returns: 1 if @fs target path equal to @path, otherwise 0.
479 int mnt_fs_streq_target(struct libmnt_fs
*fs
, const char *path
)
481 return fs
&& streq_paths(mnt_fs_get_target(fs
), path
);
487 * @name: returns pointer to NAME string
488 * @value: returns pointer to VALUE string
490 * "TAG" is NAME=VALUE (e.g. LABEL=foo)
492 * The TAG is the first column in the fstab file. The TAG or "srcpath" always has
493 * to be set for all entries.
495 * See also mnt_fs_get_source().
500 * struct libmnt_fs *fs = mnt_table_find_target(tb, "/home", MNT_ITER_FORWARD);
505 * src = mnt_fs_get_srcpath(fs);
508 * if (mnt_fs_get_tag(fs, &tag, &val) == 0)
509 * printf("%s: %s\n", tag, val); // LABEL or UUID
511 * printf("device: %s\n", src); // device or bind path
515 * Returns: 0 on success or negative number in case a TAG is not defined.
517 int mnt_fs_get_tag(struct libmnt_fs
*fs
, const char **name
, const char **value
)
519 if (fs
== NULL
|| !fs
->tagname
)
530 * @fs: fstab/mtab/mountinfo entry pointer
532 * Returns: pointer to mountpoint path or NULL
534 const char *mnt_fs_get_target(struct libmnt_fs
*fs
)
536 return fs
? fs
->target
: NULL
;
541 * @fs: fstab/mtab/mountinfo entry
544 * This function creates a private copy (strdup()) of @tgt.
546 * Returns: 0 on success or negative number in case of error.
548 int mnt_fs_set_target(struct libmnt_fs
*fs
, const char *tgt
)
550 return strdup_to_struct_member(fs
, target
, tgt
);
553 static int mnt_fs_get_flags(struct libmnt_fs
*fs
)
555 return fs
? fs
->flags
: 0;
559 * mnt_fs_get_propagation:
560 * @fs: mountinfo entry
561 * @flags: returns propagation MS_* flags as present in the mountinfo file
563 * Note that this function sets @flags to zero if no propagation flags are found
564 * in the mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored
565 * in the mountinfo file.
567 * Returns: 0 on success or negative number in case of error.
569 int mnt_fs_get_propagation(struct libmnt_fs
*fs
, unsigned long *flags
)
580 * The optional fields format is incompatible with mount options
581 * ... we have to parse the field here.
583 *flags
|= strstr(fs
->opt_fields
, "shared:") ? MS_SHARED
: MS_PRIVATE
;
585 if (strstr(fs
->opt_fields
, "master:"))
587 if (strstr(fs
->opt_fields
, "unbindable"))
588 *flags
|= MS_UNBINDABLE
;
597 * Returns: 1 if the filesystem description is read from kernel e.g. /proc/mounts.
599 int mnt_fs_is_kernel(struct libmnt_fs
*fs
)
601 return mnt_fs_get_flags(fs
) & MNT_FS_KERNEL
;
605 * mnt_fs_is_swaparea:
608 * Returns: 1 if the filesystem uses "swap" as a type
610 int mnt_fs_is_swaparea(struct libmnt_fs
*fs
)
612 return mnt_fs_get_flags(fs
) & MNT_FS_SWAP
;
616 * mnt_fs_is_pseudofs:
619 * Returns: 1 if the filesystem is a pseudo fs type (proc, cgroups)
621 int mnt_fs_is_pseudofs(struct libmnt_fs
*fs
)
623 return mnt_fs_get_flags(fs
) & MNT_FS_PSEUDO
;
630 * Returns: 1 if the filesystem is a network filesystem
632 int mnt_fs_is_netfs(struct libmnt_fs
*fs
)
634 return mnt_fs_get_flags(fs
) & MNT_FS_NET
;
639 * @fs: fstab/mtab/mountinfo entry pointer
641 * Returns: pointer to filesystem type.
643 const char *mnt_fs_get_fstype(struct libmnt_fs
*fs
)
645 return fs
? fs
->fstype
: NULL
;
648 /* Used by the struct libmnt_file parser only */
649 int __mnt_fs_set_fstype_ptr(struct libmnt_fs
*fs
, char *fstype
)
653 if (fstype
!= fs
->fstype
)
657 fs
->flags
&= ~MNT_FS_PSEUDO
;
658 fs
->flags
&= ~MNT_FS_NET
;
659 fs
->flags
&= ~MNT_FS_SWAP
;
661 /* save info about pseudo filesystems */
663 if (mnt_fstype_is_pseudofs(fs
->fstype
))
664 fs
->flags
|= MNT_FS_PSEUDO
;
665 else if (mnt_fstype_is_netfs(fs
->fstype
))
666 fs
->flags
|= MNT_FS_NET
;
667 else if (!strcmp(fs
->fstype
, "swap"))
668 fs
->flags
|= MNT_FS_SWAP
;
675 * @fs: fstab/mtab/mountinfo entry
676 * @fstype: filesystem type
678 * This function creates a private copy (strdup()) of @fstype.
680 * Returns: 0 on success or negative number in case of error.
682 int mnt_fs_set_fstype(struct libmnt_fs
*fs
, const char *fstype
)
693 return __mnt_fs_set_fstype_ptr(fs
, p
);
697 * Merges @vfs and @fs options strings into a new string.
698 * This function cares about 'ro/rw' options. The 'ro' is
699 * always used if @vfs or @fs is read-only.
702 * mnt_merge_optstr("rw,noexec", "ro,journal=update")
704 * returns: "ro,noexec,journal=update"
706 * mnt_merge_optstr("rw,noexec", "rw,journal=update")
708 * returns: "rw,noexec,journal=update"
710 static char *merge_optstr(const char *vfs
, const char *fs
)
719 return strdup(fs
? fs
: vfs
);
720 if (!strcmp(vfs
, fs
))
721 return strdup(vfs
); /* e.g. "aaa" and "aaa" */
723 /* leave space for the leading "r[ow],", "," and the trailing zero */
724 sz
= strlen(vfs
) + strlen(fs
) + 5;
728 p
= res
+ 3; /* make a room for rw/ro flag */
730 snprintf(p
, sz
- 3, "%s,%s", vfs
, fs
);
732 /* remove 'rw' flags */
733 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from vfs */
734 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from fs */
736 /* remove 'ro' flags if necessary */
738 ro
+= !mnt_optstr_remove_option(&p
, "ro");
740 ro
+= !mnt_optstr_remove_option(&p
, "ro");
744 memcpy(res
, ro
? "ro" : "rw", 3);
746 memcpy(res
, ro
? "ro," : "rw,", 3);
751 * mnt_fs_strdup_options:
752 * @fs: fstab/mtab/mountinfo entry pointer
754 * Merges all mount options (VFS, FS and userspace) to one options string
755 * and returns the result. This function does not modify @fs.
757 * Returns: pointer to string (can be freed by free(3)) or NULL in case of error.
759 char *mnt_fs_strdup_options(struct libmnt_fs
*fs
)
768 return strdup(fs
->optstr
);
770 res
= merge_optstr(fs
->vfs_optstr
, fs
->fs_optstr
);
773 if (fs
->user_optstr
&&
774 mnt_optstr_append_option(&res
, fs
->user_optstr
, NULL
)) {
782 * mnt_fs_get_options:
783 * @fs: fstab/mtab/mountinfo entry pointer
785 * Returns: pointer to string or NULL in case of error.
787 const char *mnt_fs_get_options(struct libmnt_fs
*fs
)
789 return fs
? fs
->optstr
: NULL
;
793 * mnt_fs_get_optional_fields
794 * @fs: mountinfo entry pointer
796 * Returns: pointer to string with mountinfo optional fields
797 * or NULL in case of error.
799 const char *mnt_fs_get_optional_fields(struct libmnt_fs
*fs
)
801 return fs
? fs
->opt_fields
: NULL
;
805 * mnt_fs_set_options:
806 * @fs: fstab/mtab/mountinfo entry pointer
807 * @optstr: options string
809 * Splits @optstr to VFS, FS and userspace mount options and updates relevant
812 * Returns: 0 on success, or negative number in case of error.
814 int mnt_fs_set_options(struct libmnt_fs
*fs
, const char *optstr
)
816 char *v
= NULL
, *f
= NULL
, *u
= NULL
, *n
= NULL
;
821 int rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
834 free(fs
->vfs_optstr
);
835 free(fs
->user_optstr
);
847 * mnt_fs_append_options:
848 * @fs: fstab/mtab/mountinfo entry
849 * @optstr: mount options
851 * Parses (splits) @optstr and appends results to VFS, FS and userspace lists
854 * If @optstr is NULL, then @fs is not modified and 0 is returned.
856 * Returns: 0 on success or negative number in case of error.
858 int mnt_fs_append_options(struct libmnt_fs
*fs
, const char *optstr
)
860 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
868 rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
873 rc
= mnt_optstr_append_option(&fs
->vfs_optstr
, v
, NULL
);
875 rc
= mnt_optstr_append_option(&fs
->fs_optstr
, f
, NULL
);
877 rc
= mnt_optstr_append_option(&fs
->user_optstr
, u
, NULL
);
879 rc
= mnt_optstr_append_option(&fs
->optstr
, optstr
, NULL
);
889 * mnt_fs_prepend_options:
890 * @fs: fstab/mtab/mountinfo entry
891 * @optstr: mount options
893 * Parses (splits) @optstr and prepends the results to VFS, FS and userspace lists
896 * If @optstr is NULL, then @fs is not modified and 0 is returned.
898 * Returns: 0 on success or negative number in case of error.
900 int mnt_fs_prepend_options(struct libmnt_fs
*fs
, const char *optstr
)
902 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
910 rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
915 rc
= mnt_optstr_prepend_option(&fs
->vfs_optstr
, v
, NULL
);
917 rc
= mnt_optstr_prepend_option(&fs
->fs_optstr
, f
, NULL
);
919 rc
= mnt_optstr_prepend_option(&fs
->user_optstr
, u
, NULL
);
921 rc
= mnt_optstr_prepend_option(&fs
->optstr
, optstr
, NULL
);
931 * mnt_fs_get_fs_options:
932 * @fs: fstab/mtab/mountinfo entry pointer
934 * Returns: pointer to superblock (fs-depend) mount option string or NULL.
936 const char *mnt_fs_get_fs_options(struct libmnt_fs
*fs
)
938 return fs
? fs
->fs_optstr
: NULL
;
942 * mnt_fs_get_vfs_options:
943 * @fs: fstab/mtab entry pointer
945 * Returns: pointer to fs-independent (VFS) mount option string or NULL.
947 const char *mnt_fs_get_vfs_options(struct libmnt_fs
*fs
)
949 return fs
? fs
->vfs_optstr
: NULL
;
953 * mnt_fs_get_user_options:
954 * @fs: fstab/mtab entry pointer
956 * Returns: pointer to userspace mount option string or NULL.
958 const char *mnt_fs_get_user_options(struct libmnt_fs
*fs
)
960 return fs
? fs
->user_optstr
: NULL
;
964 * mnt_fs_get_attributes:
965 * @fs: fstab/mtab entry pointer
967 * Returns: pointer to attributes string or NULL.
969 const char *mnt_fs_get_attributes(struct libmnt_fs
*fs
)
971 return fs
? fs
->attrs
: NULL
;
975 * mnt_fs_set_attributes:
976 * @fs: fstab/mtab/mountinfo entry
977 * @optstr: options string
979 * Sets mount attributes. The attributes are mount(2) and mount(8) independent
980 * options, these options are not sent to the kernel and are not interpreted by
981 * libmount. The attributes are stored in /run/mount/utab only.
983 * The attributes are managed by libmount in userspace only. It's possible
984 * that information stored in userspace will not be available for libmount
985 * after CLONE_FS unshare. Be careful, and don't use attributes if possible.
987 * Returns: 0 on success or negative number in case of error.
989 int mnt_fs_set_attributes(struct libmnt_fs
*fs
, const char *optstr
)
991 return strdup_to_struct_member(fs
, attrs
, optstr
);
995 * mnt_fs_append_attributes
996 * @fs: fstab/mtab/mountinfo entry
997 * @optstr: options string
999 * Appends mount attributes. (See mnt_fs_set_attributes()).
1001 * Returns: 0 on success or negative number in case of error.
1003 int mnt_fs_append_attributes(struct libmnt_fs
*fs
, const char *optstr
)
1009 return mnt_optstr_append_option(&fs
->attrs
, optstr
, NULL
);
1013 * mnt_fs_prepend_attributes
1014 * @fs: fstab/mtab/mountinfo entry
1015 * @optstr: options string
1017 * Prepends mount attributes. (See mnt_fs_set_attributes()).
1019 * Returns: 0 on success or negative number in case of error.
1021 int mnt_fs_prepend_attributes(struct libmnt_fs
*fs
, const char *optstr
)
1027 return mnt_optstr_prepend_option(&fs
->attrs
, optstr
, NULL
);
1033 * @fs: fstab/mtab/mountinfo entry pointer
1035 * Returns: dump frequency in days.
1037 int mnt_fs_get_freq(struct libmnt_fs
*fs
)
1039 return fs
? fs
->freq
: 0;
1044 * @fs: fstab/mtab entry pointer
1045 * @freq: dump frequency in days
1047 * Returns: 0 on success or negative number in case of error.
1049 int mnt_fs_set_freq(struct libmnt_fs
*fs
, int freq
)
1058 * mnt_fs_get_passno:
1059 * @fs: fstab/mtab entry pointer
1061 * Returns: "pass number on parallel fsck".
1063 int mnt_fs_get_passno(struct libmnt_fs
*fs
)
1065 return fs
? fs
->passno
: 0;
1069 * mnt_fs_set_passno:
1070 * @fs: fstab/mtab entry pointer
1071 * @passno: pass number
1073 * Returns: 0 on success or negative number in case of error.
1075 int mnt_fs_set_passno(struct libmnt_fs
*fs
, int passno
)
1079 fs
->passno
= passno
;
1085 * @fs: /proc/self/mountinfo entry
1087 * Returns: root of the mount within the filesystem or NULL
1089 const char *mnt_fs_get_root(struct libmnt_fs
*fs
)
1091 return fs
? fs
->root
: NULL
;
1096 * @fs: mountinfo entry
1099 * Returns: 0 on success or negative number in case of error.
1101 int mnt_fs_set_root(struct libmnt_fs
*fs
, const char *path
)
1103 return strdup_to_struct_member(fs
, root
, path
);
1107 * mnt_fs_get_swaptype:
1108 * @fs: /proc/swaps entry
1110 * Returns: swap type or NULL
1112 const char *mnt_fs_get_swaptype(struct libmnt_fs
*fs
)
1114 return fs
? fs
->swaptype
: NULL
;
1119 * @fs: /proc/swaps entry
1123 off_t
mnt_fs_get_size(struct libmnt_fs
*fs
)
1125 return fs
? fs
->size
: 0;
1129 * mnt_fs_get_usedsize:
1130 * @fs: /proc/swaps entry
1132 * Returns: used size
1134 off_t
mnt_fs_get_usedsize(struct libmnt_fs
*fs
)
1136 return fs
? fs
->usedsize
: 0;
1140 * mnt_fs_get_priority:
1141 * @fs: /proc/swaps entry
1145 int mnt_fs_get_priority(struct libmnt_fs
*fs
)
1147 return fs
? fs
->priority
: 0;
1151 * mnt_fs_set_priority:
1152 * @fs: /proc/swaps entry
1157 * Returns: 0 or -1 in case of error
1159 int mnt_fs_set_priority(struct libmnt_fs
*fs
, int prio
)
1163 fs
->priority
= prio
;
1168 * mnt_fs_get_bindsrc:
1169 * @fs: /run/mount/utab entry
1171 * Returns: full path that was used for mount(2) on MS_BIND
1173 const char *mnt_fs_get_bindsrc(struct libmnt_fs
*fs
)
1175 return fs
? fs
->bindsrc
: NULL
;
1179 * mnt_fs_set_bindsrc:
1183 * Returns: 0 on success or negative number in case of error.
1185 int mnt_fs_set_bindsrc(struct libmnt_fs
*fs
, const char *src
)
1187 return strdup_to_struct_member(fs
, bindsrc
, src
);
1192 * @fs: /proc/self/mountinfo entry
1194 * Returns: mount ID (unique identifier of the mount) or negative number in case of error.
1196 int mnt_fs_get_id(struct libmnt_fs
*fs
)
1198 return fs
? fs
->id
: -EINVAL
;
1202 * mnt_fs_get_parent_id:
1203 * @fs: /proc/self/mountinfo entry
1205 * Returns: parent mount ID or negative number in case of error.
1207 int mnt_fs_get_parent_id(struct libmnt_fs
*fs
)
1209 return fs
? fs
->parent
: -EINVAL
;
1214 * @fs: /proc/self/mountinfo entry
1216 * Returns: value of st_dev for files on filesystem or 0 in case of error.
1218 dev_t
mnt_fs_get_devno(struct libmnt_fs
*fs
)
1220 return fs
? fs
->devno
: 0;
1225 * @fs: /proc/tid/mountinfo entry
1227 * Returns: TID (task ID) for filesystems read from the mountinfo file
1229 pid_t
mnt_fs_get_tid(struct libmnt_fs
*fs
)
1231 return fs
? fs
->tid
: 0;
1235 * mnt_fs_get_option:
1236 * @fs: fstab/mtab/mountinfo entry pointer
1237 * @name: option name
1238 * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL
1239 * @valsz: returns size of options value or 0
1241 * Returns: 0 on success, 1 when @name not found or negative number in case of error.
1243 int mnt_fs_get_option(struct libmnt_fs
*fs
, const char *name
,
1244 char **value
, size_t *valsz
)
1251 rc
= mnt_optstr_get_option(fs
->fs_optstr
, name
, value
, valsz
);
1252 if (rc
== 1 && fs
->vfs_optstr
)
1253 rc
= mnt_optstr_get_option(fs
->vfs_optstr
, name
, value
, valsz
);
1254 if (rc
== 1 && fs
->user_optstr
)
1255 rc
= mnt_optstr_get_option(fs
->user_optstr
, name
, value
, valsz
);
1260 * mnt_fs_get_attribute:
1261 * @fs: fstab/mtab/mountinfo entry pointer
1262 * @name: option name
1263 * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL
1264 * @valsz: returns size of options value or 0
1266 * Returns: 0 on success, 1 when @name not found or negative number in case of error.
1268 int mnt_fs_get_attribute(struct libmnt_fs
*fs
, const char *name
,
1269 char **value
, size_t *valsz
)
1276 rc
= mnt_optstr_get_option(fs
->attrs
, name
, value
, valsz
);
1281 * mnt_fs_get_comment:
1282 * @fs: fstab/mtab/mountinfo entry pointer
1284 * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
1286 const char *mnt_fs_get_comment(struct libmnt_fs
*fs
)
1294 * mnt_fs_set_comment:
1295 * @fs: fstab entry pointer
1296 * @comm: comment string
1298 * Note that the comment has to be terminated by '\n' (new line), otherwise
1299 * the whole filesystem entry will be written as a comment to the tabfile (e.g.
1302 * Returns: 0 on success or <0 in case of error.
1304 int mnt_fs_set_comment(struct libmnt_fs
*fs
, const char *comm
)
1306 return strdup_to_struct_member(fs
, comment
, comm
);
1310 * mnt_fs_append_comment:
1311 * @fs: fstab entry pointer
1312 * @comm: comment string
1314 * See also mnt_fs_set_comment().
1316 * Returns: 0 on success or <0 in case of error.
1318 int mnt_fs_append_comment(struct libmnt_fs
*fs
, const char *comm
)
1323 return append_string(&fs
->comment
, comm
);
1327 * mnt_fs_match_target:
1329 * @target: mountpoint path
1330 * @cache: tags/paths cache or NULL
1332 * Possible are three attempts:
1333 * 1) compare @target with @fs->target
1335 * 2) realpath(@target) with @fs->target
1337 * 3) realpath(@target) with realpath(@fs->target) if @fs is not from
1338 * /proc/self/mountinfo.
1340 * However, if mnt_cache_set_targets(cache, mtab) was called, and the
1341 * path @target or @fs->target is found in the @mtab, the canonicalization is
1342 * is not performed (see mnt_resolve_target()).
1344 * The 2nd and 3rd attempts are not performed when @cache is NULL.
1346 * Returns: 1 if @fs target is equal to @target, else 0.
1348 int mnt_fs_match_target(struct libmnt_fs
*fs
, const char *target
,
1349 struct libmnt_cache
*cache
)
1353 if (!fs
|| !target
|| !fs
->target
)
1356 /* 1) native paths */
1357 rc
= mnt_fs_streq_target(fs
, target
);
1360 /* 2) - canonicalized and non-canonicalized */
1361 char *cn
= mnt_resolve_target(target
, cache
);
1362 rc
= (cn
&& mnt_fs_streq_target(fs
, cn
));
1364 /* 3) - canonicalized and canonicalized */
1365 if (!rc
&& cn
&& !mnt_fs_is_kernel(fs
) && !mnt_fs_is_swaparea(fs
)) {
1366 char *tcn
= mnt_resolve_target(fs
->target
, cache
);
1367 rc
= (tcn
&& strcmp(cn
, tcn
) == 0);
1375 * mnt_fs_match_source:
1377 * @source: tag or path (device or so) or NULL
1378 * @cache: tags/paths cache or NULL
1380 * Four attempts are possible:
1381 * 1) compare @source with @fs->source
1382 * 2) compare realpath(@source) with @fs->source
1383 * 3) compare realpath(@source) with realpath(@fs->source)
1384 * 4) compare realpath(@source) with evaluated tag from @fs->source
1386 * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The
1387 * 2nd and 3rd attempts are not performed if @fs->source is tag.
1389 * Returns: 1 if @fs source is equal to @source, else 0.
1391 int mnt_fs_match_source(struct libmnt_fs
*fs
, const char *source
,
1392 struct libmnt_cache
*cache
)
1395 const char *src
, *t
, *v
;
1400 /* 1) native paths... */
1401 if (mnt_fs_streq_srcpath(fs
, source
) == 1)
1404 if (!source
|| !fs
->source
)
1408 if (fs
->tagname
&& strcmp(source
, fs
->source
) == 0)
1413 if (fs
->flags
& (MNT_FS_NET
| MNT_FS_PSEUDO
))
1416 cn
= mnt_resolve_spec(source
, cache
);
1420 /* 2) canonicalized and native */
1421 src
= mnt_fs_get_srcpath(fs
);
1422 if (src
&& mnt_fs_streq_srcpath(fs
, cn
))
1425 /* 3) canonicalized and canonicalized */
1427 src
= mnt_resolve_path(src
, cache
);
1428 if (src
&& !strcmp(cn
, src
))
1431 if (src
|| mnt_fs_get_tag(fs
, &t
, &v
))
1432 /* src path does not match and the tag is not defined */
1435 /* read @source's tags to the cache */
1436 if (mnt_cache_read_tags(cache
, cn
) < 0) {
1437 if (errno
== EACCES
) {
1438 /* we don't have permissions to read TAGs from
1439 * @source, but can translate the @fs tag to devname.
1441 * (because libblkid uses udev symlinks and this is
1442 * accessible for non-root uses)
1444 char *x
= mnt_resolve_tag(t
, v
, cache
);
1445 if (x
&& !strcmp(x
, cn
))
1451 /* 4) has the @source a tag that matches with the tag from @fs ? */
1452 if (mnt_cache_device_has_tag(cache
, cn
, t
, v
))
1459 * mnt_fs_match_fstype:
1461 * @types: filesystem name or comma delimited list of filesystems
1463 * For more details see mnt_match_fstype().
1465 * Returns: 1 if @fs type is matching to @types, else 0. The function returns
1466 * 0 when types is NULL.
1468 int mnt_fs_match_fstype(struct libmnt_fs
*fs
, const char *types
)
1470 return mnt_match_fstype(fs
->fstype
, types
);
1474 * mnt_fs_match_options:
1476 * @options: comma delimited list of options (and nooptions)
1478 * For more details see mnt_match_options().
1480 * Returns: 1 if @fs type is matching to @options, else 0. The function returns
1481 * 0 when types is NULL.
1483 int mnt_fs_match_options(struct libmnt_fs
*fs
, const char *options
)
1485 return mnt_match_options(mnt_fs_get_options(fs
), options
);
1489 * mnt_fs_print_debug
1490 * @fs: fstab/mtab/mountinfo entry
1491 * @file: file stream
1493 * Returns: 0 on success or negative number in case of error.
1495 int mnt_fs_print_debug(struct libmnt_fs
*fs
, FILE *file
)
1499 fprintf(file
, "------ fs:\n");
1500 fprintf(file
, "source: %s\n", mnt_fs_get_source(fs
));
1501 fprintf(file
, "target: %s\n", mnt_fs_get_target(fs
));
1502 fprintf(file
, "fstype: %s\n", mnt_fs_get_fstype(fs
));
1504 if (mnt_fs_get_options(fs
))
1505 fprintf(file
, "optstr: %s\n", mnt_fs_get_options(fs
));
1506 if (mnt_fs_get_vfs_options(fs
))
1507 fprintf(file
, "VFS-optstr: %s\n", mnt_fs_get_vfs_options(fs
));
1508 if (mnt_fs_get_fs_options(fs
))
1509 fprintf(file
, "FS-opstr: %s\n", mnt_fs_get_fs_options(fs
));
1510 if (mnt_fs_get_user_options(fs
))
1511 fprintf(file
, "user-optstr: %s\n", mnt_fs_get_user_options(fs
));
1512 if (mnt_fs_get_optional_fields(fs
))
1513 fprintf(file
, "optional-fields: '%s'\n", mnt_fs_get_optional_fields(fs
));
1514 if (mnt_fs_get_attributes(fs
))
1515 fprintf(file
, "attributes: %s\n", mnt_fs_get_attributes(fs
));
1517 if (mnt_fs_get_root(fs
))
1518 fprintf(file
, "root: %s\n", mnt_fs_get_root(fs
));
1520 if (mnt_fs_get_swaptype(fs
))
1521 fprintf(file
, "swaptype: %s\n", mnt_fs_get_swaptype(fs
));
1522 if (mnt_fs_get_size(fs
))
1523 fprintf(file
, "size: %jd\n", mnt_fs_get_size(fs
));
1524 if (mnt_fs_get_usedsize(fs
))
1525 fprintf(file
, "usedsize: %jd\n", mnt_fs_get_usedsize(fs
));
1526 if (mnt_fs_get_priority(fs
))
1527 fprintf(file
, "priority: %d\n", mnt_fs_get_priority(fs
));
1529 if (mnt_fs_get_bindsrc(fs
))
1530 fprintf(file
, "bindsrc: %s\n", mnt_fs_get_bindsrc(fs
));
1531 if (mnt_fs_get_freq(fs
))
1532 fprintf(file
, "freq: %d\n", mnt_fs_get_freq(fs
));
1533 if (mnt_fs_get_passno(fs
))
1534 fprintf(file
, "pass: %d\n", mnt_fs_get_passno(fs
));
1535 if (mnt_fs_get_id(fs
))
1536 fprintf(file
, "id: %d\n", mnt_fs_get_id(fs
));
1537 if (mnt_fs_get_parent_id(fs
))
1538 fprintf(file
, "parent: %d\n", mnt_fs_get_parent_id(fs
));
1539 if (mnt_fs_get_devno(fs
))
1540 fprintf(file
, "devno: %d:%d\n", major(mnt_fs_get_devno(fs
)),
1541 minor(mnt_fs_get_devno(fs
)));
1542 if (mnt_fs_get_tid(fs
))
1543 fprintf(file
, "tid: %d\n", mnt_fs_get_tid(fs
));
1544 if (mnt_fs_get_comment(fs
))
1545 fprintf(file
, "comment: '%s'\n", mnt_fs_get_comment(fs
));
1554 * Deallocates the "mntent.h" mount entry.
1556 void mnt_free_mntent(struct mntent
*mnt
)
1559 free(mnt
->mnt_fsname
);
1561 free(mnt
->mnt_type
);
1562 free(mnt
->mnt_opts
);
1570 * @mnt: mount description (as described in mntent.h)
1572 * Copies the information from @fs to struct mntent @mnt. If @mnt is already set,
1573 * then the struct mntent items are reallocated and updated. See also
1574 * mnt_free_mntent().
1576 * Returns: 0 on success and a negative number in case of error.
1578 int mnt_fs_to_mntent(struct libmnt_fs
*fs
, struct mntent
**mnt
)
1588 m
= calloc(1, sizeof(*m
));
1593 if ((rc
= update_str(&m
->mnt_fsname
, mnt_fs_get_source(fs
))))
1595 if ((rc
= update_str(&m
->mnt_dir
, mnt_fs_get_target(fs
))))
1597 if ((rc
= update_str(&m
->mnt_type
, mnt_fs_get_fstype(fs
))))
1601 m
->mnt_opts
= mnt_fs_strdup_options(fs
);
1602 if (!m
->mnt_opts
&& errno
) {
1607 m
->mnt_freq
= mnt_fs_get_freq(fs
);
1608 m
->mnt_passno
= mnt_fs_get_passno(fs
);
1610 if (!m
->mnt_fsname
) {
1611 m
->mnt_fsname
= strdup("none");