]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - libmount/src/fs.c
9971d6ae312a6190a9a8a872ef3b10ecb52943c4
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
;
194 dest
->parent
= src
->parent
;
195 dest
->devno
= src
->devno
;
196 dest
->tid
= src
->tid
;
198 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, source
)))
200 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagname
)))
202 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagval
)))
204 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, root
)))
206 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, swaptype
)))
208 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, target
)))
210 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fstype
)))
212 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, optstr
)))
214 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, vfs_optstr
)))
216 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fs_optstr
)))
218 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, user_optstr
)))
220 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, attrs
)))
222 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, bindsrc
)))
225 dest
->freq
= src
->freq
;
226 dest
->passno
= src
->passno
;
227 dest
->flags
= src
->flags
;
228 dest
->size
= src
->size
;
229 dest
->usedsize
= src
->usedsize
;
230 dest
->priority
= src
->priority
;
240 * This function copies all @fs description except information that does not
241 * belong to /etc/mtab (e.g. VFS and userspace mount options with MNT_NOMTAB
244 * Returns: copy of @fs.
246 struct libmnt_fs
*mnt_copy_mtab_fs(const struct libmnt_fs
*fs
)
248 struct libmnt_fs
*n
= mnt_new_fs();
254 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, source
)))
256 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, target
)))
258 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fstype
)))
261 if (fs
->vfs_optstr
) {
263 mnt_optstr_get_options(fs
->vfs_optstr
, &p
,
264 mnt_get_builtin_optmap(MNT_LINUX_MAP
),
269 if (fs
->user_optstr
) {
271 mnt_optstr_get_options(fs
->user_optstr
, &p
,
272 mnt_get_builtin_optmap(MNT_USERSPACE_MAP
),
277 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fs_optstr
)))
280 /* we cannot copy original optstr, the new optstr has to be without
281 * non-mtab options -- so, let's generate a new string */
282 n
->optstr
= mnt_fs_strdup_options(n
);
285 n
->passno
= fs
->passno
;
286 n
->flags
= fs
->flags
;
296 * mnt_fs_get_userdata:
297 * @fs: struct libmnt_file instance
299 * Returns: private data set by mnt_fs_set_userdata() or NULL.
301 void *mnt_fs_get_userdata(struct libmnt_fs
*fs
)
309 * mnt_fs_set_userdata:
310 * @fs: struct libmnt_file instance
313 * The "userdata" are library independent data.
315 * Returns: 0 or negative number in case of error (if @fs is NULL).
317 int mnt_fs_set_userdata(struct libmnt_fs
*fs
, void *data
)
326 * mnt_fs_get_srcpath:
327 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
329 * The mount "source path" is:
330 * - a directory for 'bind' mounts (in fstab or mtab only)
331 * - a device name for standard mounts
333 * See also mnt_fs_get_tag() and mnt_fs_get_source().
335 * Returns: mount source path or NULL in case of error or when the path
338 const char *mnt_fs_get_srcpath(struct libmnt_fs
*fs
)
345 return NULL
; /* the source contains a "NAME=value" */
351 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
353 * Returns: mount source. Note that the source could be unparsed TAG
354 * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag().
356 const char *mnt_fs_get_source(struct libmnt_fs
*fs
)
358 return fs
? fs
->source
: NULL
;
362 * Used by the parser ONLY (@source has to be freed on error)
364 int __mnt_fs_set_source_ptr(struct libmnt_fs
*fs
, char *source
)
366 char *t
= NULL
, *v
= NULL
;
370 if (source
&& blkid_parse_tag_string(source
, &t
, &v
) == 0 &&
371 !mnt_valid_tagname(t
)) {
372 /* parsable but unknown tag -- ignore */
378 if (fs
->source
!= source
)
392 * @fs: fstab/mtab/mountinfo entry
393 * @source: new source
395 * This function creates a private copy (strdup()) of @source.
397 * Returns: 0 on success or negative number in case of error.
399 int mnt_fs_set_source(struct libmnt_fs
*fs
, const char *source
)
413 rc
= __mnt_fs_set_source_ptr(fs
, p
);
420 * mnt_fs_streq_srcpath:
424 * Compares @fs source path with @path. The redundant slashes are ignored.
425 * This function compares strings and does not canonicalize the paths.
426 * See also more heavy and generic mnt_fs_match_source().
428 * Returns: 1 if @fs source path equal to @path, otherwise 0.
430 int mnt_fs_streq_srcpath(struct libmnt_fs
*fs
, const char *path
)
437 p
= mnt_fs_get_srcpath(fs
);
439 if (!mnt_fs_is_pseudofs(fs
))
440 return streq_paths(p
, path
);
445 return p
&& path
&& strcmp(p
, path
) == 0;
449 * mnt_fs_streq_target:
453 * Compares @fs target path with @path. The redundant slashes are ignored.
454 * This function compares strings and does not canonicalize the paths.
455 * See also more generic mnt_fs_match_target().
457 * Returns: 1 if @fs target path equal to @path, otherwise 0.
459 int mnt_fs_streq_target(struct libmnt_fs
*fs
, const char *path
)
461 return fs
&& streq_paths(mnt_fs_get_target(fs
), path
);
467 * @name: returns pointer to NAME string
468 * @value: returns pointer to VALUE string
470 * "TAG" is NAME=VALUE (e.g. LABEL=foo)
472 * The TAG is the first column in the fstab file. The TAG or "srcpath" always has
473 * to be set for all entries.
475 * See also mnt_fs_get_source().
480 * struct libmnt_fs *fs = mnt_table_find_target(tb, "/home", MNT_ITER_FORWARD);
485 * src = mnt_fs_get_srcpath(fs);
488 * if (mnt_fs_get_tag(fs, &tag, &val) == 0)
489 * printf("%s: %s\n", tag, val); // LABEL or UUID
491 * printf("device: %s\n", src); // device or bind path
495 * Returns: 0 on success or negative number in case a TAG is not defined.
497 int mnt_fs_get_tag(struct libmnt_fs
*fs
, const char **name
, const char **value
)
499 if (fs
== NULL
|| !fs
->tagname
)
510 * @fs: fstab/mtab/mountinfo entry pointer
512 * Returns: pointer to mountpoint path or NULL
514 const char *mnt_fs_get_target(struct libmnt_fs
*fs
)
516 return fs
? fs
->target
: NULL
;
521 * @fs: fstab/mtab/mountinfo entry
524 * This function creates a private copy (strdup()) of @tgt.
526 * Returns: 0 on success or negative number in case of error.
528 int mnt_fs_set_target(struct libmnt_fs
*fs
, const char *tgt
)
530 return strdup_to_struct_member(fs
, target
, tgt
);
533 static int mnt_fs_get_flags(struct libmnt_fs
*fs
)
535 return fs
? fs
->flags
: 0;
539 * mnt_fs_get_propagation:
540 * @fs: mountinfo entry
541 * @flags: returns propagation MS_* flags as present in the mountinfo file
543 * Note that this function sets @flags to zero if no propagation flags are found
544 * in the mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored
545 * in the mountinfo file.
547 * Returns: 0 on success or negative number in case of error.
549 int mnt_fs_get_propagation(struct libmnt_fs
*fs
, unsigned long *flags
)
560 * The optional fields format is incompatible with mount options
561 * ... we have to parse the field here.
563 *flags
|= strstr(fs
->opt_fields
, "shared:") ? MS_SHARED
: MS_PRIVATE
;
565 if (strstr(fs
->opt_fields
, "master:"))
567 if (strstr(fs
->opt_fields
, "unbindable"))
568 *flags
|= MS_UNBINDABLE
;
577 * Returns: 1 if the filesystem description is read from kernel e.g. /proc/mounts.
579 int mnt_fs_is_kernel(struct libmnt_fs
*fs
)
581 return mnt_fs_get_flags(fs
) & MNT_FS_KERNEL
;
585 * mnt_fs_is_swaparea:
588 * Returns: 1 if the filesystem uses "swap" as a type
590 int mnt_fs_is_swaparea(struct libmnt_fs
*fs
)
592 return mnt_fs_get_flags(fs
) & MNT_FS_SWAP
;
596 * mnt_fs_is_pseudofs:
599 * Returns: 1 if the filesystem is a pseudo fs type (proc, cgroups)
601 int mnt_fs_is_pseudofs(struct libmnt_fs
*fs
)
603 return mnt_fs_get_flags(fs
) & MNT_FS_PSEUDO
;
610 * Returns: 1 if the filesystem is a network filesystem
612 int mnt_fs_is_netfs(struct libmnt_fs
*fs
)
614 return mnt_fs_get_flags(fs
) & MNT_FS_NET
;
619 * @fs: fstab/mtab/mountinfo entry pointer
621 * Returns: pointer to filesystem type.
623 const char *mnt_fs_get_fstype(struct libmnt_fs
*fs
)
625 return fs
? fs
->fstype
: NULL
;
628 /* Used by the struct libmnt_file parser only */
629 int __mnt_fs_set_fstype_ptr(struct libmnt_fs
*fs
, char *fstype
)
633 if (fstype
!= fs
->fstype
)
637 fs
->flags
&= ~MNT_FS_PSEUDO
;
638 fs
->flags
&= ~MNT_FS_NET
;
639 fs
->flags
&= ~MNT_FS_SWAP
;
641 /* save info about pseudo filesystems */
643 if (mnt_fstype_is_pseudofs(fs
->fstype
))
644 fs
->flags
|= MNT_FS_PSEUDO
;
645 else if (mnt_fstype_is_netfs(fs
->fstype
))
646 fs
->flags
|= MNT_FS_NET
;
647 else if (!strcmp(fs
->fstype
, "swap"))
648 fs
->flags
|= MNT_FS_SWAP
;
655 * @fs: fstab/mtab/mountinfo entry
656 * @fstype: filesystem type
658 * This function creates a private copy (strdup()) of @fstype.
660 * Returns: 0 on success or negative number in case of error.
662 int mnt_fs_set_fstype(struct libmnt_fs
*fs
, const char *fstype
)
673 return __mnt_fs_set_fstype_ptr(fs
, p
);
677 * Merges @vfs and @fs options strings into a new string.
678 * This function cares about 'ro/rw' options. The 'ro' is
679 * always used if @vfs or @fs is read-only.
682 * mnt_merge_optstr("rw,noexec", "ro,journal=update")
684 * returns: "ro,noexec,journal=update"
686 * mnt_merge_optstr("rw,noexec", "rw,journal=update")
688 * returns: "rw,noexec,journal=update"
690 static char *merge_optstr(const char *vfs
, const char *fs
)
699 return strdup(fs
? fs
: vfs
);
700 if (!strcmp(vfs
, fs
))
701 return strdup(vfs
); /* e.g. "aaa" and "aaa" */
703 /* leave space for the leading "r[ow],", "," and the trailing zero */
704 sz
= strlen(vfs
) + strlen(fs
) + 5;
708 p
= res
+ 3; /* make a room for rw/ro flag */
710 snprintf(p
, sz
- 3, "%s,%s", vfs
, fs
);
712 /* remove 'rw' flags */
713 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from vfs */
714 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from fs */
716 /* remove 'ro' flags if necessary */
718 ro
+= !mnt_optstr_remove_option(&p
, "ro");
720 ro
+= !mnt_optstr_remove_option(&p
, "ro");
724 memcpy(res
, ro
? "ro" : "rw", 3);
726 memcpy(res
, ro
? "ro," : "rw,", 3);
731 * mnt_fs_strdup_options:
732 * @fs: fstab/mtab/mountinfo entry pointer
734 * Merges all mount options (VFS, FS and userspace) to one options string
735 * and returns the result. This function does not modify @fs.
737 * Returns: pointer to string (can be freed by free(3)) or NULL in case of error.
739 char *mnt_fs_strdup_options(struct libmnt_fs
*fs
)
748 return strdup(fs
->optstr
);
750 res
= merge_optstr(fs
->vfs_optstr
, fs
->fs_optstr
);
753 if (fs
->user_optstr
&&
754 mnt_optstr_append_option(&res
, fs
->user_optstr
, NULL
)) {
762 * mnt_fs_get_options:
763 * @fs: fstab/mtab/mountinfo entry pointer
765 * Returns: pointer to string or NULL in case of error.
767 const char *mnt_fs_get_options(struct libmnt_fs
*fs
)
769 return fs
? fs
->optstr
: NULL
;
773 * mnt_fs_get_optional_fields
774 * @fs: mountinfo entry pointer
776 * Returns: pointer to string with mountinfo optional fields
777 * or NULL in case of error.
779 const char *mnt_fs_get_optional_fields(struct libmnt_fs
*fs
)
781 return fs
? fs
->opt_fields
: NULL
;
785 * mnt_fs_set_options:
786 * @fs: fstab/mtab/mountinfo entry pointer
787 * @optstr: options string
789 * Splits @optstr to VFS, FS and userspace mount options and updates relevant
792 * Returns: 0 on success, or negative number in case of error.
794 int mnt_fs_set_options(struct libmnt_fs
*fs
, const char *optstr
)
796 char *v
= NULL
, *f
= NULL
, *u
= NULL
, *n
= NULL
;
801 int rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
814 free(fs
->vfs_optstr
);
815 free(fs
->user_optstr
);
827 * mnt_fs_append_options:
828 * @fs: fstab/mtab/mountinfo entry
829 * @optstr: mount options
831 * Parses (splits) @optstr and appends results to VFS, FS and userspace lists
834 * If @optstr is NULL, then @fs is not modified and 0 is returned.
836 * Returns: 0 on success or negative number in case of error.
838 int mnt_fs_append_options(struct libmnt_fs
*fs
, const char *optstr
)
840 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
848 rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
853 rc
= mnt_optstr_append_option(&fs
->vfs_optstr
, v
, NULL
);
855 rc
= mnt_optstr_append_option(&fs
->fs_optstr
, f
, NULL
);
857 rc
= mnt_optstr_append_option(&fs
->user_optstr
, u
, NULL
);
859 rc
= mnt_optstr_append_option(&fs
->optstr
, optstr
, NULL
);
869 * mnt_fs_prepend_options:
870 * @fs: fstab/mtab/mountinfo entry
871 * @optstr: mount options
873 * Parses (splits) @optstr and prepends the results to VFS, FS and userspace lists
876 * If @optstr is NULL, then @fs is not modified and 0 is returned.
878 * Returns: 0 on success or negative number in case of error.
880 int mnt_fs_prepend_options(struct libmnt_fs
*fs
, const char *optstr
)
882 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
890 rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
895 rc
= mnt_optstr_prepend_option(&fs
->vfs_optstr
, v
, NULL
);
897 rc
= mnt_optstr_prepend_option(&fs
->fs_optstr
, f
, NULL
);
899 rc
= mnt_optstr_prepend_option(&fs
->user_optstr
, u
, NULL
);
901 rc
= mnt_optstr_prepend_option(&fs
->optstr
, optstr
, NULL
);
911 * mnt_fs_get_fs_options:
912 * @fs: fstab/mtab/mountinfo entry pointer
914 * Returns: pointer to superblock (fs-depend) mount option string or NULL.
916 const char *mnt_fs_get_fs_options(struct libmnt_fs
*fs
)
918 return fs
? fs
->fs_optstr
: NULL
;
922 * mnt_fs_get_vfs_options:
923 * @fs: fstab/mtab entry pointer
925 * Returns: pointer to fs-independent (VFS) mount option string or NULL.
927 const char *mnt_fs_get_vfs_options(struct libmnt_fs
*fs
)
929 return fs
? fs
->vfs_optstr
: NULL
;
933 * mnt_fs_get_user_options:
934 * @fs: fstab/mtab entry pointer
936 * Returns: pointer to userspace mount option string or NULL.
938 const char *mnt_fs_get_user_options(struct libmnt_fs
*fs
)
940 return fs
? fs
->user_optstr
: NULL
;
944 * mnt_fs_get_attributes:
945 * @fs: fstab/mtab entry pointer
947 * Returns: pointer to attributes string or NULL.
949 const char *mnt_fs_get_attributes(struct libmnt_fs
*fs
)
951 return fs
? fs
->attrs
: NULL
;
955 * mnt_fs_set_attributes:
956 * @fs: fstab/mtab/mountinfo entry
957 * @optstr: options string
959 * Sets mount attributes. The attributes are mount(2) and mount(8) independent
960 * options, these options are not sent to the kernel and are not interpreted by
961 * libmount. The attributes are stored in /run/mount/utab only.
963 * The attributes are managed by libmount in userspace only. It's possible
964 * that information stored in userspace will not be available for libmount
965 * after CLONE_FS unshare. Be careful, and don't use attributes if possible.
967 * Returns: 0 on success or negative number in case of error.
969 int mnt_fs_set_attributes(struct libmnt_fs
*fs
, const char *optstr
)
971 return strdup_to_struct_member(fs
, attrs
, optstr
);
975 * mnt_fs_append_attributes
976 * @fs: fstab/mtab/mountinfo entry
977 * @optstr: options string
979 * Appends mount attributes. (See mnt_fs_set_attributes()).
981 * Returns: 0 on success or negative number in case of error.
983 int mnt_fs_append_attributes(struct libmnt_fs
*fs
, const char *optstr
)
989 return mnt_optstr_append_option(&fs
->attrs
, optstr
, NULL
);
993 * mnt_fs_prepend_attributes
994 * @fs: fstab/mtab/mountinfo entry
995 * @optstr: options string
997 * Prepends mount attributes. (See mnt_fs_set_attributes()).
999 * Returns: 0 on success or negative number in case of error.
1001 int mnt_fs_prepend_attributes(struct libmnt_fs
*fs
, const char *optstr
)
1007 return mnt_optstr_prepend_option(&fs
->attrs
, optstr
, NULL
);
1013 * @fs: fstab/mtab/mountinfo entry pointer
1015 * Returns: dump frequency in days.
1017 int mnt_fs_get_freq(struct libmnt_fs
*fs
)
1019 return fs
? fs
->freq
: 0;
1024 * @fs: fstab/mtab entry pointer
1025 * @freq: dump frequency in days
1027 * Returns: 0 on success or negative number in case of error.
1029 int mnt_fs_set_freq(struct libmnt_fs
*fs
, int freq
)
1038 * mnt_fs_get_passno:
1039 * @fs: fstab/mtab entry pointer
1041 * Returns: "pass number on parallel fsck".
1043 int mnt_fs_get_passno(struct libmnt_fs
*fs
)
1045 return fs
? fs
->passno
: 0;
1049 * mnt_fs_set_passno:
1050 * @fs: fstab/mtab entry pointer
1051 * @passno: pass number
1053 * Returns: 0 on success or negative number in case of error.
1055 int mnt_fs_set_passno(struct libmnt_fs
*fs
, int passno
)
1059 fs
->passno
= passno
;
1065 * @fs: /proc/self/mountinfo entry
1067 * Returns: root of the mount within the filesystem or NULL
1069 const char *mnt_fs_get_root(struct libmnt_fs
*fs
)
1071 return fs
? fs
->root
: NULL
;
1076 * @fs: mountinfo entry
1079 * Returns: 0 on success or negative number in case of error.
1081 int mnt_fs_set_root(struct libmnt_fs
*fs
, const char *path
)
1083 return strdup_to_struct_member(fs
, root
, path
);
1087 * mnt_fs_get_swaptype:
1088 * @fs: /proc/swaps entry
1090 * Returns: swap type or NULL
1092 const char *mnt_fs_get_swaptype(struct libmnt_fs
*fs
)
1094 return fs
? fs
->swaptype
: NULL
;
1099 * @fs: /proc/swaps entry
1103 off_t
mnt_fs_get_size(struct libmnt_fs
*fs
)
1105 return fs
? fs
->size
: 0;
1109 * mnt_fs_get_usedsize:
1110 * @fs: /proc/swaps entry
1112 * Returns: used size
1114 off_t
mnt_fs_get_usedsize(struct libmnt_fs
*fs
)
1116 return fs
? fs
->usedsize
: 0;
1120 * mnt_fs_get_priority:
1121 * @fs: /proc/swaps entry
1125 int mnt_fs_get_priority(struct libmnt_fs
*fs
)
1127 return fs
? fs
->priority
: 0;
1131 * mnt_fs_set_priority:
1132 * @fs: /proc/swaps entry
1137 * Returns: 0 or -1 in case of error
1139 int mnt_fs_set_priority(struct libmnt_fs
*fs
, int prio
)
1143 fs
->priority
= prio
;
1148 * mnt_fs_get_bindsrc:
1149 * @fs: /run/mount/utab entry
1151 * Returns: full path that was used for mount(2) on MS_BIND
1153 const char *mnt_fs_get_bindsrc(struct libmnt_fs
*fs
)
1155 return fs
? fs
->bindsrc
: NULL
;
1159 * mnt_fs_set_bindsrc:
1163 * Returns: 0 on success or negative number in case of error.
1165 int mnt_fs_set_bindsrc(struct libmnt_fs
*fs
, const char *src
)
1167 return strdup_to_struct_member(fs
, bindsrc
, src
);
1172 * @fs: /proc/self/mountinfo entry
1174 * Returns: mount ID (unique identifier of the mount) or negative number in case of error.
1176 int mnt_fs_get_id(struct libmnt_fs
*fs
)
1178 return fs
? fs
->id
: -EINVAL
;
1182 * mnt_fs_get_parent_id:
1183 * @fs: /proc/self/mountinfo entry
1185 * Returns: parent mount ID or negative number in case of error.
1187 int mnt_fs_get_parent_id(struct libmnt_fs
*fs
)
1189 return fs
? fs
->parent
: -EINVAL
;
1194 * @fs: /proc/self/mountinfo entry
1196 * Returns: value of st_dev for files on filesystem or 0 in case of error.
1198 dev_t
mnt_fs_get_devno(struct libmnt_fs
*fs
)
1200 return fs
? fs
->devno
: 0;
1205 * @fs: /proc/tid/mountinfo entry
1207 * Returns: TID (task ID) for filesystems read from the mountinfo file
1209 pid_t
mnt_fs_get_tid(struct libmnt_fs
*fs
)
1211 return fs
? fs
->tid
: 0;
1215 * mnt_fs_get_option:
1216 * @fs: fstab/mtab/mountinfo entry pointer
1217 * @name: option name
1218 * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL
1219 * @valsz: returns size of options value or 0
1221 * Returns: 0 on success, 1 when @name not found or negative number in case of error.
1223 int mnt_fs_get_option(struct libmnt_fs
*fs
, const char *name
,
1224 char **value
, size_t *valsz
)
1231 rc
= mnt_optstr_get_option(fs
->fs_optstr
, name
, value
, valsz
);
1232 if (rc
== 1 && fs
->vfs_optstr
)
1233 rc
= mnt_optstr_get_option(fs
->vfs_optstr
, name
, value
, valsz
);
1234 if (rc
== 1 && fs
->user_optstr
)
1235 rc
= mnt_optstr_get_option(fs
->user_optstr
, name
, value
, valsz
);
1240 * mnt_fs_get_attribute:
1241 * @fs: fstab/mtab/mountinfo entry pointer
1242 * @name: option name
1243 * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL
1244 * @valsz: returns size of options value or 0
1246 * Returns: 0 on success, 1 when @name not found or negative number in case of error.
1248 int mnt_fs_get_attribute(struct libmnt_fs
*fs
, const char *name
,
1249 char **value
, size_t *valsz
)
1256 rc
= mnt_optstr_get_option(fs
->attrs
, name
, value
, valsz
);
1261 * mnt_fs_get_comment:
1262 * @fs: fstab/mtab/mountinfo entry pointer
1264 * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
1266 const char *mnt_fs_get_comment(struct libmnt_fs
*fs
)
1274 * mnt_fs_set_comment:
1275 * @fs: fstab entry pointer
1276 * @comm: comment string
1278 * Note that the comment has to be terminated by '\n' (new line), otherwise
1279 * the whole filesystem entry will be written as a comment to the tabfile (e.g.
1282 * Returns: 0 on success or <0 in case of error.
1284 int mnt_fs_set_comment(struct libmnt_fs
*fs
, const char *comm
)
1286 return strdup_to_struct_member(fs
, comment
, comm
);
1290 * mnt_fs_append_comment:
1291 * @fs: fstab entry pointer
1292 * @comm: comment string
1294 * See also mnt_fs_set_comment().
1296 * Returns: 0 on success or <0 in case of error.
1298 int mnt_fs_append_comment(struct libmnt_fs
*fs
, const char *comm
)
1303 return append_string(&fs
->comment
, comm
);
1307 * mnt_fs_match_target:
1309 * @target: mountpoint path
1310 * @cache: tags/paths cache or NULL
1312 * Possible are three attempts:
1313 * 1) compare @target with @fs->target
1315 * 2) realpath(@target) with @fs->target
1317 * 3) realpath(@target) with realpath(@fs->target) if @fs is not from
1318 * /proc/self/mountinfo.
1320 * However, if mnt_cache_set_targets(cache, mtab) was called, and the
1321 * path @target or @fs->target is found in the @mtab, the canonicalization is
1322 * is not performed (see mnt_resolve_target()).
1324 * The 2nd and 3rd attempts are not performed when @cache is NULL.
1326 * Returns: 1 if @fs target is equal to @target, else 0.
1328 int mnt_fs_match_target(struct libmnt_fs
*fs
, const char *target
,
1329 struct libmnt_cache
*cache
)
1333 if (!fs
|| !target
|| !fs
->target
)
1336 /* 1) native paths */
1337 rc
= mnt_fs_streq_target(fs
, target
);
1340 /* 2) - canonicalized and non-canonicalized */
1341 char *cn
= mnt_resolve_target(target
, cache
);
1342 rc
= (cn
&& mnt_fs_streq_target(fs
, cn
));
1344 /* 3) - canonicalized and canonicalized */
1345 if (!rc
&& cn
&& !mnt_fs_is_kernel(fs
) && !mnt_fs_is_swaparea(fs
)) {
1346 char *tcn
= mnt_resolve_target(fs
->target
, cache
);
1347 rc
= (tcn
&& strcmp(cn
, tcn
) == 0);
1355 * mnt_fs_match_source:
1357 * @source: tag or path (device or so) or NULL
1358 * @cache: tags/paths cache or NULL
1360 * Four attempts are possible:
1361 * 1) compare @source with @fs->source
1362 * 2) compare realpath(@source) with @fs->source
1363 * 3) compare realpath(@source) with realpath(@fs->source)
1364 * 4) compare realpath(@source) with evaluated tag from @fs->source
1366 * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The
1367 * 2nd and 3rd attempts are not performed if @fs->source is tag.
1369 * Returns: 1 if @fs source is equal to @source, else 0.
1371 int mnt_fs_match_source(struct libmnt_fs
*fs
, const char *source
,
1372 struct libmnt_cache
*cache
)
1375 const char *src
, *t
, *v
;
1380 /* 1) native paths... */
1381 if (mnt_fs_streq_srcpath(fs
, source
) == 1)
1384 if (!source
|| !fs
->source
)
1388 if (fs
->tagname
&& strcmp(source
, fs
->source
) == 0)
1393 if (fs
->flags
& (MNT_FS_NET
| MNT_FS_PSEUDO
))
1396 cn
= mnt_resolve_spec(source
, cache
);
1400 /* 2) canonicalized and native */
1401 src
= mnt_fs_get_srcpath(fs
);
1402 if (src
&& mnt_fs_streq_srcpath(fs
, cn
))
1405 /* 3) canonicalized and canonicalized */
1407 src
= mnt_resolve_path(src
, cache
);
1408 if (src
&& !strcmp(cn
, src
))
1411 if (src
|| mnt_fs_get_tag(fs
, &t
, &v
))
1412 /* src path does not match and the tag is not defined */
1415 /* read @source's tags to the cache */
1416 if (mnt_cache_read_tags(cache
, cn
) < 0) {
1417 if (errno
== EACCES
) {
1418 /* we don't have permissions to read TAGs from
1419 * @source, but can translate the @fs tag to devname.
1421 * (because libblkid uses udev symlinks and this is
1422 * accessible for non-root uses)
1424 char *x
= mnt_resolve_tag(t
, v
, cache
);
1425 if (x
&& !strcmp(x
, cn
))
1431 /* 4) has the @source a tag that matches with the tag from @fs ? */
1432 if (mnt_cache_device_has_tag(cache
, cn
, t
, v
))
1439 * mnt_fs_match_fstype:
1441 * @types: filesystem name or comma delimited list of filesystems
1443 * For more details see mnt_match_fstype().
1445 * Returns: 1 if @fs type is matching to @types, else 0. The function returns
1446 * 0 when types is NULL.
1448 int mnt_fs_match_fstype(struct libmnt_fs
*fs
, const char *types
)
1450 return mnt_match_fstype(fs
->fstype
, types
);
1454 * mnt_fs_match_options:
1456 * @options: comma delimited list of options (and nooptions)
1458 * For more details see mnt_match_options().
1460 * Returns: 1 if @fs type is matching to @options, else 0. The function returns
1461 * 0 when types is NULL.
1463 int mnt_fs_match_options(struct libmnt_fs
*fs
, const char *options
)
1465 return mnt_match_options(mnt_fs_get_options(fs
), options
);
1469 * mnt_fs_print_debug
1470 * @fs: fstab/mtab/mountinfo entry
1471 * @file: file stream
1473 * Returns: 0 on success or negative number in case of error.
1475 int mnt_fs_print_debug(struct libmnt_fs
*fs
, FILE *file
)
1479 fprintf(file
, "------ fs:\n");
1480 fprintf(file
, "source: %s\n", mnt_fs_get_source(fs
));
1481 fprintf(file
, "target: %s\n", mnt_fs_get_target(fs
));
1482 fprintf(file
, "fstype: %s\n", mnt_fs_get_fstype(fs
));
1484 if (mnt_fs_get_options(fs
))
1485 fprintf(file
, "optstr: %s\n", mnt_fs_get_options(fs
));
1486 if (mnt_fs_get_vfs_options(fs
))
1487 fprintf(file
, "VFS-optstr: %s\n", mnt_fs_get_vfs_options(fs
));
1488 if (mnt_fs_get_fs_options(fs
))
1489 fprintf(file
, "FS-opstr: %s\n", mnt_fs_get_fs_options(fs
));
1490 if (mnt_fs_get_user_options(fs
))
1491 fprintf(file
, "user-optstr: %s\n", mnt_fs_get_user_options(fs
));
1492 if (mnt_fs_get_optional_fields(fs
))
1493 fprintf(file
, "optional-fields: '%s'\n", mnt_fs_get_optional_fields(fs
));
1494 if (mnt_fs_get_attributes(fs
))
1495 fprintf(file
, "attributes: %s\n", mnt_fs_get_attributes(fs
));
1497 if (mnt_fs_get_root(fs
))
1498 fprintf(file
, "root: %s\n", mnt_fs_get_root(fs
));
1500 if (mnt_fs_get_swaptype(fs
))
1501 fprintf(file
, "swaptype: %s\n", mnt_fs_get_swaptype(fs
));
1502 if (mnt_fs_get_size(fs
))
1503 fprintf(file
, "size: %jd\n", mnt_fs_get_size(fs
));
1504 if (mnt_fs_get_usedsize(fs
))
1505 fprintf(file
, "usedsize: %jd\n", mnt_fs_get_usedsize(fs
));
1506 if (mnt_fs_get_priority(fs
))
1507 fprintf(file
, "priority: %d\n", mnt_fs_get_priority(fs
));
1509 if (mnt_fs_get_bindsrc(fs
))
1510 fprintf(file
, "bindsrc: %s\n", mnt_fs_get_bindsrc(fs
));
1511 if (mnt_fs_get_freq(fs
))
1512 fprintf(file
, "freq: %d\n", mnt_fs_get_freq(fs
));
1513 if (mnt_fs_get_passno(fs
))
1514 fprintf(file
, "pass: %d\n", mnt_fs_get_passno(fs
));
1515 if (mnt_fs_get_id(fs
))
1516 fprintf(file
, "id: %d\n", mnt_fs_get_id(fs
));
1517 if (mnt_fs_get_parent_id(fs
))
1518 fprintf(file
, "parent: %d\n", mnt_fs_get_parent_id(fs
));
1519 if (mnt_fs_get_devno(fs
))
1520 fprintf(file
, "devno: %d:%d\n", major(mnt_fs_get_devno(fs
)),
1521 minor(mnt_fs_get_devno(fs
)));
1522 if (mnt_fs_get_tid(fs
))
1523 fprintf(file
, "tid: %d\n", mnt_fs_get_tid(fs
));
1524 if (mnt_fs_get_comment(fs
))
1525 fprintf(file
, "comment: '%s'\n", mnt_fs_get_comment(fs
));
1534 * Deallocates the "mntent.h" mount entry.
1536 void mnt_free_mntent(struct mntent
*mnt
)
1539 free(mnt
->mnt_fsname
);
1541 free(mnt
->mnt_type
);
1542 free(mnt
->mnt_opts
);
1550 * @mnt: mount description (as described in mntent.h)
1552 * Copies the information from @fs to struct mntent @mnt. If @mnt is already set,
1553 * then the struct mntent items are reallocated and updated. See also
1554 * mnt_free_mntent().
1556 * Returns: 0 on success and a negative number in case of error.
1558 int mnt_fs_to_mntent(struct libmnt_fs
*fs
, struct mntent
**mnt
)
1568 m
= calloc(1, sizeof(*m
));
1573 if ((rc
= update_str(&m
->mnt_fsname
, mnt_fs_get_source(fs
))))
1575 if ((rc
= update_str(&m
->mnt_dir
, mnt_fs_get_target(fs
))))
1577 if ((rc
= update_str(&m
->mnt_type
, mnt_fs_get_fstype(fs
))))
1581 m
->mnt_opts
= mnt_fs_strdup_options(fs
);
1582 if (!m
->mnt_opts
&& errno
) {
1587 m
->mnt_freq
= mnt_fs_get_freq(fs
);
1588 m
->mnt_passno
= mnt_fs_get_passno(fs
);
1590 if (!m
->mnt_fsname
) {
1591 m
->mnt_fsname
= strdup("none");