]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - libmount/src/fs.c
2 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
4 * This file may be redistributed under the terms of the
5 * GNU Lesser General Public License.
11 * @short_description: represents one entry from fstab, mtab, or mountinfo file
24 * Returns: newly allocated struct libmnt_fs.
26 struct libmnt_fs
*mnt_new_fs(void)
28 struct libmnt_fs
*fs
= calloc(1, sizeof(*fs
));
32 /*DBG(FS, mnt_debug_h(fs, "alloc"));*/
33 INIT_LIST_HEAD(&fs
->ents
);
43 void mnt_free_fs(struct libmnt_fs
*fs
)
49 /*DBG(FS, mnt_debug_h(fs, "free"));*/
61 free(fs
->user_optstr
);
71 * Resets (zeroize) @fs.
73 void mnt_reset_fs(struct libmnt_fs
*fs
)
76 memset(fs
, 0, sizeof(*fs
));
79 static inline int update_str(char **dest
, const char *src
)
89 return 0; /* source (old) is empty */
93 x
= realloc(*dest
, sz
);
97 memcpy(*dest
, src
, sz
);
101 static inline int cpy_str_at_offset(void *new, const void *old
, size_t offset
)
103 char **o
= (char **) (old
+ offset
);
104 char **n
= (char **) (new + offset
);
107 return 0; /* already set, not overwrite */
109 return update_str(n
, *o
);
114 * @dest: destination FS
117 * If @dest is NULL, then a new FS is allocated, if any @dest field is already
118 * set then the field is NOT overwrited.
120 * This function does not copy userdata (se mnt_fs_set_userdata()). A new copy is
121 * not linked with any existing mnt_tab.
123 * Returns: @dest or NULL in case of error
125 struct libmnt_fs
*mnt_copy_fs(struct libmnt_fs
*dest
,
126 const struct libmnt_fs
*src
)
128 const struct libmnt_fs
*org
= dest
;
136 /*DBG(FS, mnt_debug_h(dest, "copy from %p", src));*/
139 dest
->parent
= src
->parent
;
140 dest
->devno
= src
->devno
;
142 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, source
)))
144 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagname
)))
146 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagval
)))
148 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, root
)))
150 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, target
)))
152 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fstype
)))
154 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, optstr
)))
156 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, vfs_optstr
)))
158 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fs_optstr
)))
160 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, user_optstr
)))
162 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, attrs
)))
164 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, bindsrc
)))
167 dest
->freq
= src
->freq
;
168 dest
->passno
= src
->passno
;
169 dest
->flags
= src
->flags
;
179 * This function copies all @fs description except information that does not
180 * belong to /etc/mtab (e.g. VFS and userspace mount options with MNT_NOMTAB
183 * Returns: copy of @fs.
185 struct libmnt_fs
*mnt_copy_mtab_fs(const struct libmnt_fs
*fs
)
187 struct libmnt_fs
*n
= mnt_new_fs();
192 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, source
)))
194 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, target
)))
196 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fstype
)))
199 if (fs
->vfs_optstr
) {
201 mnt_optstr_get_options(fs
->vfs_optstr
, &p
,
202 mnt_get_builtin_optmap(MNT_LINUX_MAP
),
207 if (fs
->user_optstr
) {
209 mnt_optstr_get_options(fs
->user_optstr
, &p
,
210 mnt_get_builtin_optmap(MNT_USERSPACE_MAP
),
215 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fs_optstr
)))
218 /* we cannot copy original optstr, the new optstr has to be without
219 * non-mtab options -- so, let's generate a new string */
220 n
->optstr
= mnt_fs_strdup_options(n
);
223 n
->passno
= fs
->passno
;
224 n
->flags
= fs
->flags
;
234 * mnt_fs_get_userdata:
235 * @fs: struct libmnt_file instance
237 * Returns: private data set by mnt_fs_set_userdata() or NULL.
239 void *mnt_fs_get_userdata(struct libmnt_fs
*fs
)
241 return fs
? fs
->userdata
: NULL
;
245 * mnt_fs_set_userdata:
246 * @fs: struct libmnt_file instance
249 * The "userdata" are library independent data.
251 * Returns: 0 or negative number in case of error (if @fs is NULL).
253 int mnt_fs_set_userdata(struct libmnt_fs
*fs
, void *data
)
262 * mnt_fs_get_srcpath:
263 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
265 * The mount "source path" is:
266 * - a directory for 'bind' mounts (in fstab or mtab only)
267 * - a device name for standard mounts
269 * See also mnt_fs_get_tag() and mnt_fs_get_source().
271 * Returns: mount source path or NULL in case of error or when the path
274 const char *mnt_fs_get_srcpath(struct libmnt_fs
*fs
)
282 return NULL
; /* the source contains a "NAME=value" */
288 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
290 * Returns: mount source. Note that the source could be unparsed TAG
291 * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag().
293 const char *mnt_fs_get_source(struct libmnt_fs
*fs
)
295 return fs
? fs
->source
: NULL
;
299 * Used by parser ONLY (@source has to be allocated on error)
301 int __mnt_fs_set_source_ptr(struct libmnt_fs
*fs
, char *source
)
303 char *t
= NULL
, *v
= NULL
;
307 if (source
&& !strcmp(source
, "none")) {
311 } else if (source
&& strchr(source
, '=')) {
312 if (blkid_parse_tag_string(source
, &t
, &v
) != 0)
316 if (fs
->source
!= source
)
330 * @fs: fstab/mtab/mountinfo entry
331 * @source: new source
333 * This function creates a private copy (strdup()) of @source.
335 * Returns: 0 on success or negative number in case of error.
337 int mnt_fs_set_source(struct libmnt_fs
*fs
, const char *source
)
350 rc
= __mnt_fs_set_source_ptr(fs
, p
);
359 * @name: returns pointer to NAME string
360 * @value: returns pointer to VALUE string
362 * "TAG" is NAME=VALUE (e.g. LABEL=foo)
364 * The TAG is the first column in the fstab file. The TAG or "srcpath" has to
365 * be always set for all entries.
367 * See also mnt_fs_get_source().
372 * struct libmnt_fs *fs = mnt_table_find_target(tb, "/home", MNT_ITER_FORWARD);
377 * src = mnt_fs_get_srcpath(fs);
380 * if (mnt_fs_get_tag(fs, &tag, &val) == 0)
381 * printf("%s: %s\n", tag, val); // LABEL or UUID
383 * printf("device: %s\n", src); // device or bind path
387 * Returns: 0 on success or negative number in case that a TAG is not defined.
389 int mnt_fs_get_tag(struct libmnt_fs
*fs
, const char **name
, const char **value
)
391 if (fs
== NULL
|| !fs
->tagname
)
402 * @fs: fstab/mtab/mountinfo entry pointer
404 * Returns: pointer to mountpoint path or NULL
406 const char *mnt_fs_get_target(struct libmnt_fs
*fs
)
409 return fs
? fs
->target
: NULL
;
414 * @fs: fstab/mtab/mountinfo entry
415 * @target: mountpoint
417 * This function creates a private copy (strdup()) of @target.
419 * Returns: 0 on success or negative number in case of error.
421 int mnt_fs_set_target(struct libmnt_fs
*fs
, const char *target
)
440 static int mnt_fs_get_flags(struct libmnt_fs
*fs
)
442 return fs
? fs
->flags
: 0;
449 * Returns: 1 if the filesystem description is read from kernel e.g. /proc/mounts.
451 int mnt_fs_is_kernel(struct libmnt_fs
*fs
)
453 return mnt_fs_get_flags(fs
) & MNT_FS_KERNEL
;
457 * mnt_fs_is_swaparea:
460 * Returns: 1 if the filesystem uses "swap" as a type
462 int mnt_fs_is_swaparea(struct libmnt_fs
*fs
)
464 return mnt_fs_get_flags(fs
) & MNT_FS_SWAP
;
468 * mnt_fs_is_pseudofs:
471 * Returns: 1 if the filesystem is a pseudo fs type (proc, cgroups)
473 int mnt_fs_is_pseudo(struct libmnt_fs
*fs
)
475 return mnt_fs_get_flags(fs
) & MNT_FS_PSEUDO
;
482 * Returns: 1 if the filesystem is a network filesystem
484 int mnt_fs_is_netfs(struct libmnt_fs
*fs
)
486 return mnt_fs_get_flags(fs
) & MNT_FS_NET
;
491 * @fs: fstab/mtab/mountinfo entry pointer
493 * Returns: pointer to filesystem type.
495 const char *mnt_fs_get_fstype(struct libmnt_fs
*fs
)
498 return fs
? fs
->fstype
: NULL
;
501 /* Used by struct libmnt_file parser only */
502 int __mnt_fs_set_fstype_ptr(struct libmnt_fs
*fs
, char *fstype
)
506 if (fstype
!= fs
->fstype
)
510 fs
->flags
&= ~MNT_FS_PSEUDO
;
511 fs
->flags
&= ~MNT_FS_NET
;
512 fs
->flags
&= ~MNT_FS_SWAP
;
514 /* save info about pseudo filesystems */
516 if (mnt_fstype_is_pseudofs(fs
->fstype
))
517 fs
->flags
|= MNT_FS_PSEUDO
;
518 else if (mnt_fstype_is_netfs(fs
->fstype
))
519 fs
->flags
|= MNT_FS_NET
;
520 else if (!strcmp(fs
->fstype
, "swap"))
521 fs
->flags
|= MNT_FS_SWAP
;
528 * @fs: fstab/mtab/mountinfo entry
529 * @fstype: filesystem type
531 * This function creates a private copy (strdup()) of @fstype.
533 * Returns: 0 on success or negative number in case of error.
535 int mnt_fs_set_fstype(struct libmnt_fs
*fs
, const char *fstype
)
546 return __mnt_fs_set_fstype_ptr(fs
, p
);
550 * Merges @vfs and @fs options strings into a new string.
551 * This function cares about 'ro/rw' options. The 'ro' is
552 * always used if @vfs or @fs is read-only.
555 * mnt_merge_optstr("rw,noexec", "ro,journal=update")
557 * returns: "ro,noexec,journal=update"
559 * mnt_merge_optstr("rw,noexec", "rw,journal=update")
561 * returns: "rw,noexec,journal=update"
563 static char *merge_optstr(const char *vfs
, const char *fs
)
572 return strdup(fs
? fs
: vfs
);
573 if (!strcmp(vfs
, fs
))
574 return strdup(vfs
); /* e.g. "aaa" and "aaa" */
576 /* leave space for leading "r[ow],", "," and trailing zero */
577 sz
= strlen(vfs
) + strlen(fs
) + 5;
581 p
= res
+ 3; /* make a room for rw/ro flag */
583 snprintf(p
, sz
- 3, "%s,%s", vfs
, fs
);
585 /* remove 'rw' flags */
586 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from vfs */
587 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from fs */
589 /* remove 'ro' flags if necessary */
591 ro
+= !mnt_optstr_remove_option(&p
, "ro");
593 ro
+= !mnt_optstr_remove_option(&p
, "ro");
597 memcpy(res
, ro
? "ro" : "rw", 3);
599 memcpy(res
, ro
? "ro," : "rw,", 3);
604 * mnt_fs_strdup_options:
605 * @fs: fstab/mtab/mountinfo entry pointer
607 * Merges all mount options (VFS, FS and userspace) to the one options string
608 * and returns the result. This function does not modigy @fs.
610 * Returns: pointer to string (can be freed by free(3)) or NULL in case of error.
612 char *mnt_fs_strdup_options(struct libmnt_fs
*fs
)
621 return strdup(fs
->optstr
);
623 res
= merge_optstr(fs
->vfs_optstr
, fs
->fs_optstr
);
626 if (fs
->user_optstr
) {
627 if (mnt_optstr_append_option(&res
, fs
->user_optstr
, NULL
)) {
636 * mnt_fs_get_options:
637 * @fs: fstab/mtab/mountinfo entry pointer
639 * Returns: pointer to string or NULL in case of error.
641 const char *mnt_fs_get_options(struct libmnt_fs
*fs
)
644 return fs
? fs
->optstr
: NULL
;
649 * mnt_fs_set_options:
650 * @fs: fstab/mtab/mountinfo entry pointer
651 * @optstr: options string
653 * Splits @optstr to VFS, FS and userspace mount options and update relevat
656 * Returns: 0 on success, or negative number icase of error.
658 int mnt_fs_set_options(struct libmnt_fs
*fs
, const char *optstr
)
660 char *v
= NULL
, *f
= NULL
, *u
= NULL
, *n
= NULL
;
667 int rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
676 free(fs
->vfs_optstr
);
677 free(fs
->user_optstr
);
689 * mnt_fs_append_options:
690 * @fs: fstab/mtab/mountinfo entry
691 * @optstr: mount options
693 * Parses (splits) @optstr and appends results to VFS, FS and userspace lists
696 * If @optstr is NULL then @fs is not modified and 0 is returned.
698 * Returns: 0 on success or negative number in case of error.
700 int mnt_fs_append_options(struct libmnt_fs
*fs
, const char *optstr
)
702 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
712 rc
= mnt_split_optstr((char *) optstr
, &u
, &v
, &f
, 0, 0);
714 rc
= mnt_optstr_append_option(&fs
->vfs_optstr
, v
, NULL
);
716 rc
= mnt_optstr_append_option(&fs
->fs_optstr
, f
, NULL
);
718 rc
= mnt_optstr_append_option(&fs
->user_optstr
, u
, NULL
);
720 rc
= mnt_optstr_append_option(&fs
->optstr
, optstr
, NULL
);
730 * mnt_fs_prepend_options:
731 * @fs: fstab/mtab/mountinfo entry
732 * @optstr: mount options
734 * Parses (splits) @optstr and prepands results to VFS, FS and userspace lists
737 * If @optstr is NULL then @fs is not modified and 0 is returned.
739 * Returns: 0 on success or negative number in case of error.
741 int mnt_fs_prepend_options(struct libmnt_fs
*fs
, const char *optstr
)
743 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
753 rc
= mnt_split_optstr((char *) optstr
, &u
, &v
, &f
, 0, 0);
755 rc
= mnt_optstr_prepend_option(&fs
->vfs_optstr
, v
, NULL
);
757 rc
= mnt_optstr_prepend_option(&fs
->fs_optstr
, f
, NULL
);
759 rc
= mnt_optstr_prepend_option(&fs
->user_optstr
, u
, NULL
);
761 rc
= mnt_optstr_prepend_option(&fs
->optstr
, optstr
, NULL
);
771 * mnt_fs_get_fs_options:
772 * @fs: fstab/mtab/mountinfo entry pointer
774 * Returns: pointer to superblock (fs-depend) mount option string or NULL.
776 const char *mnt_fs_get_fs_options(struct libmnt_fs
*fs
)
779 return fs
? fs
->fs_optstr
: NULL
;
783 * mnt_fs_get_vfs_options:
784 * @fs: fstab/mtab entry pointer
786 * Returns: pointer to fs-independent (VFS) mount option string or NULL.
788 const char *mnt_fs_get_vfs_options(struct libmnt_fs
*fs
)
791 return fs
? fs
->vfs_optstr
: NULL
;
795 * mnt_fs_get_user_options:
796 * @fs: fstab/mtab entry pointer
798 * Returns: pointer to userspace mount option string or NULL.
800 const char *mnt_fs_get_user_options(struct libmnt_fs
*fs
)
803 return fs
? fs
->user_optstr
: NULL
;
807 * mnt_fs_get_attributes:
808 * @fs: fstab/mtab entry pointer
810 * Returns: pointer to attributes string or NULL.
812 const char *mnt_fs_get_attributes(struct libmnt_fs
*fs
)
815 return fs
? fs
->attrs
: NULL
;
819 * mnt_fs_set_attributes:
820 * @fs: fstab/mtab/mountinfo entry
821 * @optstr: options string
823 * Sets mount attributes. The attributes are mount(2) and mount(8) independent
824 * options, these options are not send to kernel and are not interpreted by
825 * libmount. The attributes are stored in /run/mount/utab only.
827 * The atrtributes are managed by libmount in userspace only. It's possible
828 * that information stored in userspace will not be available for libmount
829 * after CLONE_FS unshare. Be carefull, and don't use attributes if possible.
831 * Returns: 0 on success or negative number in case of error.
833 int mnt_fs_set_attributes(struct libmnt_fs
*fs
, const char *optstr
)
851 * mnt_fs_append_attributes
852 * @fs: fstab/mtab/mountinfo entry
853 * @optstr: options string
855 * Appends mount attributes. (See mnt_fs_set_attributes()).
857 * Returns: 0 on success or negative number in case of error.
859 int mnt_fs_append_attributes(struct libmnt_fs
*fs
, const char *optstr
)
865 return mnt_optstr_append_option(&fs
->attrs
, optstr
, NULL
);
869 * mnt_fs_prepend_attributes
870 * @fs: fstab/mtab/mountinfo entry
871 * @optstr: options string
873 * Prepends mount attributes. (See mnt_fs_set_attributes()).
875 * Returns: 0 on success or negative number in case of error.
877 int mnt_fs_prepend_attributes(struct libmnt_fs
*fs
, const char *optstr
)
883 return mnt_optstr_prepend_option(&fs
->attrs
, optstr
, NULL
);
889 * @fs: fstab/mtab/mountinfo entry pointer
891 * Returns: dump frequency in days.
893 int mnt_fs_get_freq(struct libmnt_fs
*fs
)
896 return fs
? fs
->freq
: 0;
901 * @fs: fstab/mtab entry pointer
902 * @freq: dump frequency in days
904 * Returns: 0 on success or negative number in case of error.
906 int mnt_fs_set_freq(struct libmnt_fs
*fs
, int freq
)
917 * @fs: fstab/mtab entry pointer
919 * Returns: "pass number on parallel fsck".
921 int mnt_fs_get_passno(struct libmnt_fs
*fs
)
924 return fs
? fs
->passno
: 0;
929 * @fs: fstab/mtab entry pointer
930 * @passno: pass number
932 * Returns: 0 on success or negative number in case of error.
934 int mnt_fs_set_passno(struct libmnt_fs
*fs
, int passno
)
945 * @fs: /proc/self/mountinfo entry
947 * Returns: root of the mount within the filesystem or NULL
949 const char *mnt_fs_get_root(struct libmnt_fs
*fs
)
952 return fs
? fs
->root
: NULL
;
957 * @fs: mountinfo entry
960 * Returns: 0 on success or negative number in case of error.
962 int mnt_fs_set_root(struct libmnt_fs
*fs
, const char *root
)
980 * mnt_fs_get_bindsrc:
981 * @fs: /run/mount/utab entry
983 * Returns: full path that was used for mount(2) on MS_BIND
985 const char *mnt_fs_get_bindsrc(struct libmnt_fs
*fs
)
988 return fs
? fs
->bindsrc
: NULL
;
992 * mnt_fs_set_bindsrc:
996 * Returns: 0 on success or negative number in case of error.
998 int mnt_fs_set_bindsrc(struct libmnt_fs
*fs
, const char *src
)
1017 * @fs: /proc/self/mountinfo entry
1019 * Returns: mount ID (unique identifier of the mount) or negative number in case of error.
1021 int mnt_fs_get_id(struct libmnt_fs
*fs
)
1024 return fs
? fs
->id
: -EINVAL
;
1028 * mnt_fs_get_parent_id:
1029 * @fs: /proc/self/mountinfo entry
1031 * Returns: parent mount ID or negative number in case of error.
1033 int mnt_fs_get_parent_id(struct libmnt_fs
*fs
)
1036 return fs
? fs
->parent
: -EINVAL
;
1041 * @fs: /proc/self/mountinfo entry
1043 * Returns: value of st_dev for files on filesystem or 0 in case of error.
1045 dev_t
mnt_fs_get_devno(struct libmnt_fs
*fs
)
1048 return fs
? fs
->devno
: 0;
1052 * mnt_fs_get_option:
1053 * @fs: fstab/mtab/mountinfo entry pointer
1054 * @name: option name
1055 * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL
1056 * @valsz: returns size of options value or 0
1058 * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
1060 int mnt_fs_get_option(struct libmnt_fs
*fs
, const char *name
,
1061 char **value
, size_t *valsz
)
1066 rc
= mnt_optstr_get_option(fs
->fs_optstr
, name
, value
, valsz
);
1067 if (rc
== 1 && fs
->vfs_optstr
)
1068 rc
= mnt_optstr_get_option(fs
->vfs_optstr
, name
, value
, valsz
);
1069 if (rc
== 1 && fs
->user_optstr
)
1070 rc
= mnt_optstr_get_option(fs
->user_optstr
, name
, value
, valsz
);
1075 * mnt_fs_get_attribute:
1076 * @fs: fstab/mtab/mountinfo entry pointer
1077 * @name: option name
1078 * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL
1079 * @valsz: returns size of options value or 0
1081 * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
1083 int mnt_fs_get_attribute(struct libmnt_fs
*fs
, const char *name
,
1084 char **value
, size_t *valsz
)
1089 rc
= mnt_optstr_get_option(fs
->attrs
, name
, value
, valsz
);
1094 * mnt_fs_match_target:
1096 * @target: mountpoint path
1097 * @cache: tags/paths cache or NULL
1099 * Possible are three attempts:
1100 * 1) compare @target with @fs->target
1101 * 2) realpath(@target) with @fs->target
1102 * 3) realpath(@target) with realpath(@fs->target).
1104 * The 2nd and 3rd attempts are not performed when @cache is NULL.
1106 * Returns: 1 if @fs target is equal to @target else 0.
1108 int mnt_fs_match_target(struct libmnt_fs
*fs
, const char *target
,
1109 struct libmnt_cache
*cache
)
1113 if (!fs
|| !target
|| !fs
->target
)
1116 /* 1) native paths */
1117 rc
= !strcmp(target
, fs
->target
);
1120 /* 2) - canonicalized and non-canonicalized */
1121 char *cn
= mnt_resolve_path(target
, cache
);
1122 rc
= (cn
&& strcmp(cn
, fs
->target
) == 0);
1124 /* 3) - canonicalized and canonicalized */
1126 char *tcn
= mnt_resolve_path(fs
->target
, cache
);
1127 rc
= (tcn
&& strcmp(cn
, tcn
) == 0);
1135 * mnt_fs_match_source:
1137 * @source: tag or path (device or so) or NULL
1138 * @cache: tags/paths cache or NULL
1140 * Possible are four attempts:
1141 * 1) compare @source with @fs->source
1142 * 2) compare realpath(@source) with @fs->source
1143 * 3) compare realpath(@source) with realpath(@fs->source)
1144 * 4) compare realpath(@source) with evaluated tag from @fs->source
1146 * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The
1147 * 2nd and 3rd attempts are not performed if @fs->source is tag.
1149 * Note that valid source path is NULL; the libmount uses NULL instead of
1150 * "none". The "none" is used in /proc/{mounts,self/mountninfo} for pseudo
1153 * Returns: 1 if @fs source is equal to @source else 0.
1155 int mnt_fs_match_source(struct libmnt_fs
*fs
, const char *source
,
1156 struct libmnt_cache
*cache
)
1159 const char *src
, *t
, *v
;
1164 /* undefined source -- "none" in /proc */
1165 if (source
== NULL
&& fs
->source
== NULL
)
1168 if (source
== NULL
|| fs
->source
== NULL
)
1171 /* 1) native paths/tags */
1172 if (streq_except_trailing_slash(source
, fs
->source
))
1177 if (fs
->flags
& (MNT_FS_NET
| MNT_FS_PSEUDO
))
1180 cn
= mnt_resolve_spec(source
, cache
);
1184 /* 2) canonicalized and native */
1185 src
= mnt_fs_get_srcpath(fs
);
1186 if (src
&& streq_except_trailing_slash(cn
, src
))
1189 /* 3) canonicalized and canonicalized */
1191 src
= mnt_resolve_path(src
, cache
);
1192 if (src
&& !strcmp(cn
, src
))
1195 if (src
|| mnt_fs_get_tag(fs
, &t
, &v
))
1196 /* src path does not match and tag is not defined */
1199 /* read @source's tags to the cache */
1200 if (mnt_cache_read_tags(cache
, cn
) < 0) {
1201 if (errno
== EACCES
) {
1202 /* we don't have permissions to read TAGs from
1203 * @source, but can translate @fs tag to devname.
1205 * (because libblkid uses udev symlinks and this is
1206 * accessible for non-root uses)
1208 char *x
= mnt_resolve_tag(t
, v
, cache
);
1209 if (x
&& !strcmp(x
, cn
))
1215 /* 4) has the @source a tag that matches with tag from @fs ? */
1216 if (mnt_cache_device_has_tag(cache
, cn
, t
, v
))
1223 * mnt_fs_match_fstype:
1225 * @types: filesystem name or comma delimited list of filesystems
1227 * For more details see mnt_match_fstype().
1229 * Returns: 1 if @fs type is matching to @types else 0. The function returns
1230 * 0 when types is NULL.
1232 int mnt_fs_match_fstype(struct libmnt_fs
*fs
, const char *types
)
1234 return mnt_match_fstype(fs
->fstype
, types
);
1238 * mnt_fs_match_options:
1240 * @options: comma delimited list of options (and nooptions)
1242 * For more details see mnt_match_options().
1244 * Returns: 1 if @fs type is matching to @options else 0. The function returns
1245 * 0 when types is NULL.
1247 int mnt_fs_match_options(struct libmnt_fs
*fs
, const char *options
)
1249 return mnt_match_options(mnt_fs_get_options(fs
), options
);
1253 * mnt_fs_print_debug
1254 * @fs: fstab/mtab/mountinfo entry
1255 * @file: file stream
1257 * Returns: 0 on success or negative number in case of error.
1259 int mnt_fs_print_debug(struct libmnt_fs
*fs
, FILE *file
)
1263 fprintf(file
, "------ fs: %p\n", fs
);
1264 fprintf(file
, "source: %s\n", mnt_fs_get_source(fs
));
1265 fprintf(file
, "target: %s\n", mnt_fs_get_target(fs
));
1266 fprintf(file
, "fstype: %s\n", mnt_fs_get_fstype(fs
));
1268 if (mnt_fs_get_options(fs
))
1269 fprintf(file
, "optstr: %s\n", mnt_fs_get_options(fs
));
1270 if (mnt_fs_get_vfs_options(fs
))
1271 fprintf(file
, "VFS-optstr: %s\n", mnt_fs_get_vfs_options(fs
));
1272 if (mnt_fs_get_fs_options(fs
))
1273 fprintf(file
, "FS-opstr: %s\n", mnt_fs_get_fs_options(fs
));
1274 if (mnt_fs_get_user_options(fs
))
1275 fprintf(file
, "user-optstr: %s\n", mnt_fs_get_user_options(fs
));
1276 if (mnt_fs_get_attributes(fs
))
1277 fprintf(file
, "attributes: %s\n", mnt_fs_get_attributes(fs
));
1279 if (mnt_fs_get_root(fs
))
1280 fprintf(file
, "root: %s\n", mnt_fs_get_root(fs
));
1281 if (mnt_fs_get_bindsrc(fs
))
1282 fprintf(file
, "bindsrc: %s\n", mnt_fs_get_bindsrc(fs
));
1283 if (mnt_fs_get_freq(fs
))
1284 fprintf(file
, "freq: %d\n", mnt_fs_get_freq(fs
));
1285 if (mnt_fs_get_passno(fs
))
1286 fprintf(file
, "pass: %d\n", mnt_fs_get_passno(fs
));
1287 if (mnt_fs_get_id(fs
))
1288 fprintf(file
, "id: %d\n", mnt_fs_get_id(fs
));
1289 if (mnt_fs_get_parent_id(fs
))
1290 fprintf(file
, "parent: %d\n", mnt_fs_get_parent_id(fs
));
1291 if (mnt_fs_get_devno(fs
))
1292 fprintf(file
, "devno: %d:%d\n", major(mnt_fs_get_devno(fs
)),
1293 minor(mnt_fs_get_devno(fs
)));
1301 * Deallocates "mntent.h" mount entry.
1303 void mnt_free_mntent(struct mntent
*mnt
)
1306 free(mnt
->mnt_fsname
);
1308 free(mnt
->mnt_type
);
1309 free(mnt
->mnt_opts
);
1317 * @mnt: mount description (as described in mntent.h)
1319 * Copies information from @fs to struct mntent @mnt. If @mnt is already set
1320 * then the struct mntent items are reallocated and updated. See also
1321 * mnt_free_mntent().
1323 * Returns: 0 on success and negative number in case of error.
1325 int mnt_fs_to_mntent(struct libmnt_fs
*fs
, struct mntent
**mnt
)
1335 m
= calloc(1, sizeof(*m
));
1340 if ((rc
= update_str(&m
->mnt_fsname
, mnt_fs_get_source(fs
))))
1342 if ((rc
= update_str(&m
->mnt_dir
, mnt_fs_get_target(fs
))))
1344 if ((rc
= update_str(&m
->mnt_type
, mnt_fs_get_fstype(fs
))))
1348 m
->mnt_opts
= mnt_fs_strdup_options(fs
);
1349 if (!m
->mnt_opts
&& errno
) {
1354 m
->mnt_freq
= mnt_fs_get_freq(fs
);
1355 m
->mnt_passno
= mnt_fs_get_passno(fs
);
1357 if (!m
->mnt_fsname
) {
1358 m
->mnt_fsname
= strdup("none");