]>
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 * The initial refcount is 1, and needs to be decremented to
25 * release the resources of the filesystem.
27 * Returns: newly allocated struct libmnt_fs.
29 struct libmnt_fs
*mnt_new_fs(void)
31 struct libmnt_fs
*fs
= calloc(1, sizeof(*fs
));
36 INIT_LIST_HEAD(&fs
->ents
);
37 /*DBG(FS, ul_debugobj(fs, "alloc"));*/
45 * Deallocates the fs. This function does not care about reference count. Don't
46 * use this function directly -- it's better to use mnt_unref_fs().
48 * The reference counting is supported since util-linux v2.24.
50 void mnt_free_fs(struct libmnt_fs
*fs
)
55 DBG(FS
, ul_debugobj(fs
, "free [refcount=%d]", fs
->refcount
));
65 * Resets (zeroize) @fs.
67 void mnt_reset_fs(struct libmnt_fs
*fs
)
88 free(fs
->user_optstr
);
93 memset(fs
, 0, sizeof(*fs
));
94 INIT_LIST_HEAD(&fs
->ents
);
102 * Increments reference counter.
104 void mnt_ref_fs(struct libmnt_fs
*fs
)
108 /*DBG(FS, ul_debugobj(fs, "ref=%d", fs->refcount));*/
116 * De-increments reference counter, on zero the @fs is automatically
117 * deallocated by mnt_free_fs().
119 void mnt_unref_fs(struct libmnt_fs
*fs
)
123 /*DBG(FS, ul_debugobj(fs, "unref=%d", fs->refcount));*/
124 if (fs
->refcount
<= 0)
129 static inline int update_str(char **dest
, const char *src
)
139 return 0; /* source (old) is empty */
142 sz
= strlen(src
) + 1;
143 x
= realloc(*dest
, sz
);
147 memcpy(*dest
, src
, sz
);
151 static inline int cpy_str_at_offset(void *new, const void *old
, size_t offset
)
153 char **o
= (char **) ((char *) old
+ offset
);
154 char **n
= (char **) ((char *) new + offset
);
157 return 0; /* already set, don't overwrite */
159 return update_str(n
, *o
);
164 * @dest: destination FS
167 * If @dest is NULL, then a new FS is allocated, if any @dest field is already
168 * set, then the field is NOT overwritten.
170 * This function does not copy userdata (se mnt_fs_set_userdata()). A new copy is
171 * not linked with any existing mnt_tab.
173 * Returns: @dest or NULL in case of error
175 struct libmnt_fs
*mnt_copy_fs(struct libmnt_fs
*dest
,
176 const struct libmnt_fs
*src
)
178 const struct libmnt_fs
*org
= dest
;
189 dest
->parent
= src
->parent
;
190 dest
->devno
= src
->devno
;
191 dest
->tid
= src
->tid
;
193 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, source
)))
195 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagname
)))
197 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagval
)))
199 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, root
)))
201 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, swaptype
)))
203 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, target
)))
205 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fstype
)))
207 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, optstr
)))
209 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, vfs_optstr
)))
211 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fs_optstr
)))
213 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, user_optstr
)))
215 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, attrs
)))
217 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, bindsrc
)))
220 dest
->freq
= src
->freq
;
221 dest
->passno
= src
->passno
;
222 dest
->flags
= src
->flags
;
223 dest
->size
= src
->size
;
224 dest
->usedsize
= src
->usedsize
;
225 dest
->priority
= src
->priority
;
235 * This function copies all @fs description except information that does not
236 * belong to /etc/mtab (e.g. VFS and userspace mount options with MNT_NOMTAB
239 * Returns: copy of @fs.
241 struct libmnt_fs
*mnt_copy_mtab_fs(const struct libmnt_fs
*fs
)
243 struct libmnt_fs
*n
= mnt_new_fs();
249 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, source
)))
251 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, target
)))
253 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fstype
)))
256 if (fs
->vfs_optstr
) {
258 mnt_optstr_get_options(fs
->vfs_optstr
, &p
,
259 mnt_get_builtin_optmap(MNT_LINUX_MAP
),
264 if (fs
->user_optstr
) {
266 mnt_optstr_get_options(fs
->user_optstr
, &p
,
267 mnt_get_builtin_optmap(MNT_USERSPACE_MAP
),
272 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fs_optstr
)))
275 /* we cannot copy original optstr, the new optstr has to be without
276 * non-mtab options -- so, let's generate a new string */
277 n
->optstr
= mnt_fs_strdup_options(n
);
280 n
->passno
= fs
->passno
;
281 n
->flags
= fs
->flags
;
291 * mnt_fs_get_userdata:
292 * @fs: struct libmnt_file instance
294 * Returns: private data set by mnt_fs_set_userdata() or NULL.
296 void *mnt_fs_get_userdata(struct libmnt_fs
*fs
)
304 * mnt_fs_set_userdata:
305 * @fs: struct libmnt_file instance
308 * The "userdata" are library independent data.
310 * Returns: 0 or negative number in case of error (if @fs is NULL).
312 int mnt_fs_set_userdata(struct libmnt_fs
*fs
, void *data
)
321 * mnt_fs_get_srcpath:
322 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
324 * The mount "source path" is:
325 * - a directory for 'bind' mounts (in fstab or mtab only)
326 * - a device name for standard mounts
328 * See also mnt_fs_get_tag() and mnt_fs_get_source().
330 * Returns: mount source path or NULL in case of error or when the path
333 const char *mnt_fs_get_srcpath(struct libmnt_fs
*fs
)
340 return NULL
; /* the source contains a "NAME=value" */
346 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
348 * Returns: mount source. Note that the source could be unparsed TAG
349 * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag().
351 const char *mnt_fs_get_source(struct libmnt_fs
*fs
)
353 return fs
? fs
->source
: NULL
;
357 * Used by the parser ONLY (@source has to be freed on error)
359 int __mnt_fs_set_source_ptr(struct libmnt_fs
*fs
, char *source
)
361 char *t
= NULL
, *v
= NULL
;
365 if (source
&& blkid_parse_tag_string(source
, &t
, &v
) == 0 &&
366 !mnt_valid_tagname(t
)) {
367 /* parsable but unknown tag -- ignore */
373 if (fs
->source
!= source
)
387 * @fs: fstab/mtab/mountinfo entry
388 * @source: new source
390 * This function creates a private copy (strdup()) of @source.
392 * Returns: 0 on success or negative number in case of error.
394 int mnt_fs_set_source(struct libmnt_fs
*fs
, const char *source
)
408 rc
= __mnt_fs_set_source_ptr(fs
, p
);
415 * mnt_fs_streq_srcpath:
419 * Compares @fs source path with @path. The redundant slashs are ignored.
420 * This function compares strings and does not cannonicalize the paths.
421 * See also more heavy and generic mnt_fs_match_source().
423 * Returns: 1 if @fs source path equal to @path, otherwise 0.
425 int mnt_fs_streq_srcpath(struct libmnt_fs
*fs
, const char *path
)
432 p
= mnt_fs_get_srcpath(fs
);
434 if (!mnt_fs_is_pseudofs(fs
))
435 return streq_paths(p
, path
);
440 return p
&& path
&& strcmp(p
, path
) == 0;
444 * mnt_fs_streq_target:
448 * Compares @fs target path with @path. The redundant slashs are ignored.
449 * This function compares strings and does not cannonicalize the paths.
450 * See also more generic mnt_fs_match_target().
452 * Returns: 1 if @fs target path equal to @path, otherwise 0.
454 int mnt_fs_streq_target(struct libmnt_fs
*fs
, const char *path
)
456 return fs
&& streq_paths(mnt_fs_get_target(fs
), path
);
462 * @name: returns pointer to NAME string
463 * @value: returns pointer to VALUE string
465 * "TAG" is NAME=VALUE (e.g. LABEL=foo)
467 * The TAG is the first column in the fstab file. The TAG or "srcpath" always has
468 * to be set for all entries.
470 * See also mnt_fs_get_source().
475 * struct libmnt_fs *fs = mnt_table_find_target(tb, "/home", MNT_ITER_FORWARD);
480 * src = mnt_fs_get_srcpath(fs);
483 * if (mnt_fs_get_tag(fs, &tag, &val) == 0)
484 * printf("%s: %s\n", tag, val); // LABEL or UUID
486 * printf("device: %s\n", src); // device or bind path
490 * Returns: 0 on success or negative number in case a TAG is not defined.
492 int mnt_fs_get_tag(struct libmnt_fs
*fs
, const char **name
, const char **value
)
494 if (fs
== NULL
|| !fs
->tagname
)
505 * @fs: fstab/mtab/mountinfo entry pointer
507 * Returns: pointer to mountpoint path or NULL
509 const char *mnt_fs_get_target(struct libmnt_fs
*fs
)
511 return fs
? fs
->target
: NULL
;
516 * @fs: fstab/mtab/mountinfo entry
519 * This function creates a private copy (strdup()) of @tgt.
521 * Returns: 0 on success or negative number in case of error.
523 int mnt_fs_set_target(struct libmnt_fs
*fs
, const char *tgt
)
525 return strdup_to_struct_member(fs
, target
, tgt
);
528 static int mnt_fs_get_flags(struct libmnt_fs
*fs
)
530 return fs
? fs
->flags
: 0;
534 * mnt_fs_get_propagation:
535 * @fs: mountinfo entry
536 * @flags: returns propagation MS_* flags as present in the mountinfo file
538 * Note that this function sets @flags to zero if no propagation flags are found
539 * in the mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored
540 * in the mountinfo file.
542 * Returns: 0 on success or negative number in case of error.
544 int mnt_fs_get_propagation(struct libmnt_fs
*fs
, unsigned long *flags
)
555 * The optional fields format is incompatible with mount options
556 * ... we have to parse the field here.
558 *flags
|= strstr(fs
->opt_fields
, "shared:") ? MS_SHARED
: MS_PRIVATE
;
560 if (strstr(fs
->opt_fields
, "master:"))
562 if (strstr(fs
->opt_fields
, "unbindable"))
563 *flags
|= MS_UNBINDABLE
;
572 * Returns: 1 if the filesystem description is read from kernel e.g. /proc/mounts.
574 int mnt_fs_is_kernel(struct libmnt_fs
*fs
)
576 return mnt_fs_get_flags(fs
) & MNT_FS_KERNEL
;
580 * mnt_fs_is_swaparea:
583 * Returns: 1 if the filesystem uses "swap" as a type
585 int mnt_fs_is_swaparea(struct libmnt_fs
*fs
)
587 return mnt_fs_get_flags(fs
) & MNT_FS_SWAP
;
591 * mnt_fs_is_pseudofs:
594 * Returns: 1 if the filesystem is a pseudo fs type (proc, cgroups)
596 int mnt_fs_is_pseudofs(struct libmnt_fs
*fs
)
598 return mnt_fs_get_flags(fs
) & MNT_FS_PSEUDO
;
605 * Returns: 1 if the filesystem is a network filesystem
607 int mnt_fs_is_netfs(struct libmnt_fs
*fs
)
609 return mnt_fs_get_flags(fs
) & MNT_FS_NET
;
614 * @fs: fstab/mtab/mountinfo entry pointer
616 * Returns: pointer to filesystem type.
618 const char *mnt_fs_get_fstype(struct libmnt_fs
*fs
)
620 return fs
? fs
->fstype
: NULL
;
623 /* Used by the struct libmnt_file parser only */
624 int __mnt_fs_set_fstype_ptr(struct libmnt_fs
*fs
, char *fstype
)
628 if (fstype
!= fs
->fstype
)
632 fs
->flags
&= ~MNT_FS_PSEUDO
;
633 fs
->flags
&= ~MNT_FS_NET
;
634 fs
->flags
&= ~MNT_FS_SWAP
;
636 /* save info about pseudo filesystems */
638 if (mnt_fstype_is_pseudofs(fs
->fstype
))
639 fs
->flags
|= MNT_FS_PSEUDO
;
640 else if (mnt_fstype_is_netfs(fs
->fstype
))
641 fs
->flags
|= MNT_FS_NET
;
642 else if (!strcmp(fs
->fstype
, "swap"))
643 fs
->flags
|= MNT_FS_SWAP
;
650 * @fs: fstab/mtab/mountinfo entry
651 * @fstype: filesystem type
653 * This function creates a private copy (strdup()) of @fstype.
655 * Returns: 0 on success or negative number in case of error.
657 int mnt_fs_set_fstype(struct libmnt_fs
*fs
, const char *fstype
)
668 return __mnt_fs_set_fstype_ptr(fs
, p
);
672 * Merges @vfs and @fs options strings into a new string.
673 * This function cares about 'ro/rw' options. The 'ro' is
674 * always used if @vfs or @fs is read-only.
677 * mnt_merge_optstr("rw,noexec", "ro,journal=update")
679 * returns: "ro,noexec,journal=update"
681 * mnt_merge_optstr("rw,noexec", "rw,journal=update")
683 * returns: "rw,noexec,journal=update"
685 static char *merge_optstr(const char *vfs
, const char *fs
)
694 return strdup(fs
? fs
: vfs
);
695 if (!strcmp(vfs
, fs
))
696 return strdup(vfs
); /* e.g. "aaa" and "aaa" */
698 /* leave space for the leading "r[ow],", "," and the trailing zero */
699 sz
= strlen(vfs
) + strlen(fs
) + 5;
703 p
= res
+ 3; /* make a room for rw/ro flag */
705 snprintf(p
, sz
- 3, "%s,%s", vfs
, fs
);
707 /* remove 'rw' flags */
708 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from vfs */
709 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from fs */
711 /* remove 'ro' flags if necessary */
713 ro
+= !mnt_optstr_remove_option(&p
, "ro");
715 ro
+= !mnt_optstr_remove_option(&p
, "ro");
719 memcpy(res
, ro
? "ro" : "rw", 3);
721 memcpy(res
, ro
? "ro," : "rw,", 3);
726 * mnt_fs_strdup_options:
727 * @fs: fstab/mtab/mountinfo entry pointer
729 * Merges all mount options (VFS, FS and userspace) to one options string
730 * and returns the result. This function does not modify @fs.
732 * Returns: pointer to string (can be freed by free(3)) or NULL in case of error.
734 char *mnt_fs_strdup_options(struct libmnt_fs
*fs
)
743 return strdup(fs
->optstr
);
745 res
= merge_optstr(fs
->vfs_optstr
, fs
->fs_optstr
);
748 if (fs
->user_optstr
&&
749 mnt_optstr_append_option(&res
, fs
->user_optstr
, NULL
)) {
757 * mnt_fs_get_options:
758 * @fs: fstab/mtab/mountinfo entry pointer
760 * Returns: pointer to string or NULL in case of error.
762 const char *mnt_fs_get_options(struct libmnt_fs
*fs
)
764 return fs
? fs
->optstr
: NULL
;
768 * mnt_fs_get_optional_fields
769 * @fs: mountinfo entry pointer
771 * Returns: pointer to string with mountinfo optional fields
772 * or NULL in case of error.
774 const char *mnt_fs_get_optional_fields(struct libmnt_fs
*fs
)
776 return fs
? fs
->opt_fields
: NULL
;
780 * mnt_fs_set_options:
781 * @fs: fstab/mtab/mountinfo entry pointer
782 * @optstr: options string
784 * Splits @optstr to VFS, FS and userspace mount options and updates relevant
787 * Returns: 0 on success, or negative number in case of error.
789 int mnt_fs_set_options(struct libmnt_fs
*fs
, const char *optstr
)
791 char *v
= NULL
, *f
= NULL
, *u
= NULL
, *n
= NULL
;
796 int rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
809 free(fs
->vfs_optstr
);
810 free(fs
->user_optstr
);
822 * mnt_fs_append_options:
823 * @fs: fstab/mtab/mountinfo entry
824 * @optstr: mount options
826 * Parses (splits) @optstr and appends results to VFS, FS and userspace lists
829 * If @optstr is NULL, then @fs is not modified and 0 is returned.
831 * Returns: 0 on success or negative number in case of error.
833 int mnt_fs_append_options(struct libmnt_fs
*fs
, const char *optstr
)
835 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
843 rc
= mnt_split_optstr((char *) optstr
, &u
, &v
, &f
, 0, 0);
848 rc
= mnt_optstr_append_option(&fs
->vfs_optstr
, v
, NULL
);
850 rc
= mnt_optstr_append_option(&fs
->fs_optstr
, f
, NULL
);
852 rc
= mnt_optstr_append_option(&fs
->user_optstr
, u
, NULL
);
854 rc
= mnt_optstr_append_option(&fs
->optstr
, optstr
, NULL
);
864 * mnt_fs_prepend_options:
865 * @fs: fstab/mtab/mountinfo entry
866 * @optstr: mount options
868 * Parses (splits) @optstr and prepends the results to VFS, FS and userspace lists
871 * If @optstr is NULL, then @fs is not modified and 0 is returned.
873 * Returns: 0 on success or negative number in case of error.
875 int mnt_fs_prepend_options(struct libmnt_fs
*fs
, const char *optstr
)
877 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
885 rc
= mnt_split_optstr((char *) optstr
, &u
, &v
, &f
, 0, 0);
890 rc
= mnt_optstr_prepend_option(&fs
->vfs_optstr
, v
, NULL
);
892 rc
= mnt_optstr_prepend_option(&fs
->fs_optstr
, f
, NULL
);
894 rc
= mnt_optstr_prepend_option(&fs
->user_optstr
, u
, NULL
);
896 rc
= mnt_optstr_prepend_option(&fs
->optstr
, optstr
, NULL
);
906 * mnt_fs_get_fs_options:
907 * @fs: fstab/mtab/mountinfo entry pointer
909 * Returns: pointer to superblock (fs-depend) mount option string or NULL.
911 const char *mnt_fs_get_fs_options(struct libmnt_fs
*fs
)
913 return fs
? fs
->fs_optstr
: NULL
;
917 * mnt_fs_get_vfs_options:
918 * @fs: fstab/mtab entry pointer
920 * Returns: pointer to fs-independent (VFS) mount option string or NULL.
922 const char *mnt_fs_get_vfs_options(struct libmnt_fs
*fs
)
924 return fs
? fs
->vfs_optstr
: NULL
;
928 * mnt_fs_get_user_options:
929 * @fs: fstab/mtab entry pointer
931 * Returns: pointer to userspace mount option string or NULL.
933 const char *mnt_fs_get_user_options(struct libmnt_fs
*fs
)
935 return fs
? fs
->user_optstr
: NULL
;
939 * mnt_fs_get_attributes:
940 * @fs: fstab/mtab entry pointer
942 * Returns: pointer to attributes string or NULL.
944 const char *mnt_fs_get_attributes(struct libmnt_fs
*fs
)
946 return fs
? fs
->attrs
: NULL
;
950 * mnt_fs_set_attributes:
951 * @fs: fstab/mtab/mountinfo entry
952 * @optstr: options string
954 * Sets mount attributes. The attributes are mount(2) and mount(8) independent
955 * options, these options are not sent to the kernel and are not interpreted by
956 * libmount. The attributes are stored in /run/mount/utab only.
958 * The attributes are managed by libmount in userspace only. It's possible
959 * that information stored in userspace will not be available for libmount
960 * after CLONE_FS unshare. Be careful, and don't use attributes if possible.
962 * Returns: 0 on success or negative number in case of error.
964 int mnt_fs_set_attributes(struct libmnt_fs
*fs
, const char *optstr
)
966 return strdup_to_struct_member(fs
, attrs
, optstr
);
970 * mnt_fs_append_attributes
971 * @fs: fstab/mtab/mountinfo entry
972 * @optstr: options string
974 * Appends mount attributes. (See mnt_fs_set_attributes()).
976 * Returns: 0 on success or negative number in case of error.
978 int mnt_fs_append_attributes(struct libmnt_fs
*fs
, const char *optstr
)
984 return mnt_optstr_append_option(&fs
->attrs
, optstr
, NULL
);
988 * mnt_fs_prepend_attributes
989 * @fs: fstab/mtab/mountinfo entry
990 * @optstr: options string
992 * Prepends mount attributes. (See mnt_fs_set_attributes()).
994 * Returns: 0 on success or negative number in case of error.
996 int mnt_fs_prepend_attributes(struct libmnt_fs
*fs
, const char *optstr
)
1002 return mnt_optstr_prepend_option(&fs
->attrs
, optstr
, NULL
);
1008 * @fs: fstab/mtab/mountinfo entry pointer
1010 * Returns: dump frequency in days.
1012 int mnt_fs_get_freq(struct libmnt_fs
*fs
)
1014 return fs
? fs
->freq
: 0;
1019 * @fs: fstab/mtab entry pointer
1020 * @freq: dump frequency in days
1022 * Returns: 0 on success or negative number in case of error.
1024 int mnt_fs_set_freq(struct libmnt_fs
*fs
, int freq
)
1033 * mnt_fs_get_passno:
1034 * @fs: fstab/mtab entry pointer
1036 * Returns: "pass number on parallel fsck".
1038 int mnt_fs_get_passno(struct libmnt_fs
*fs
)
1040 return fs
? fs
->passno
: 0;
1044 * mnt_fs_set_passno:
1045 * @fs: fstab/mtab entry pointer
1046 * @passno: pass number
1048 * Returns: 0 on success or negative number in case of error.
1050 int mnt_fs_set_passno(struct libmnt_fs
*fs
, int passno
)
1054 fs
->passno
= passno
;
1060 * @fs: /proc/self/mountinfo entry
1062 * Returns: root of the mount within the filesystem or NULL
1064 const char *mnt_fs_get_root(struct libmnt_fs
*fs
)
1066 return fs
? fs
->root
: NULL
;
1071 * @fs: mountinfo entry
1074 * Returns: 0 on success or negative number in case of error.
1076 int mnt_fs_set_root(struct libmnt_fs
*fs
, const char *path
)
1078 return strdup_to_struct_member(fs
, root
, path
);
1082 * mnt_fs_get_swaptype:
1083 * @fs: /proc/swaps entry
1085 * Returns: swap type or NULL
1087 const char *mnt_fs_get_swaptype(struct libmnt_fs
*fs
)
1089 return fs
? fs
->swaptype
: NULL
;
1094 * @fs: /proc/swaps entry
1098 off_t
mnt_fs_get_size(struct libmnt_fs
*fs
)
1100 return fs
? fs
->size
: 0;
1104 * mnt_fs_get_usedsize:
1105 * @fs: /proc/swaps entry
1107 * Returns: used size
1109 off_t
mnt_fs_get_usedsize(struct libmnt_fs
*fs
)
1111 return fs
? fs
->usedsize
: 0;
1115 * mnt_fs_get_priority:
1116 * @fs: /proc/swaps entry
1120 int mnt_fs_get_priority(struct libmnt_fs
*fs
)
1122 return fs
? fs
->priority
: 0;
1126 * mnt_fs_set_priority:
1127 * @fs: /proc/swaps entry
1132 * Returns: 0 or -1 in case of error
1134 int mnt_fs_set_priority(struct libmnt_fs
*fs
, int prio
)
1138 fs
->priority
= prio
;
1143 * mnt_fs_get_bindsrc:
1144 * @fs: /run/mount/utab entry
1146 * Returns: full path that was used for mount(2) on MS_BIND
1148 const char *mnt_fs_get_bindsrc(struct libmnt_fs
*fs
)
1150 return fs
? fs
->bindsrc
: NULL
;
1154 * mnt_fs_set_bindsrc:
1158 * Returns: 0 on success or negative number in case of error.
1160 int mnt_fs_set_bindsrc(struct libmnt_fs
*fs
, const char *src
)
1162 return strdup_to_struct_member(fs
, bindsrc
, src
);
1167 * @fs: /proc/self/mountinfo entry
1169 * Returns: mount ID (unique identifier of the mount) or negative number in case of error.
1171 int mnt_fs_get_id(struct libmnt_fs
*fs
)
1173 return fs
? fs
->id
: -EINVAL
;
1177 * mnt_fs_get_parent_id:
1178 * @fs: /proc/self/mountinfo entry
1180 * Returns: parent mount ID or negative number in case of error.
1182 int mnt_fs_get_parent_id(struct libmnt_fs
*fs
)
1184 return fs
? fs
->parent
: -EINVAL
;
1189 * @fs: /proc/self/mountinfo entry
1191 * Returns: value of st_dev for files on filesystem or 0 in case of error.
1193 dev_t
mnt_fs_get_devno(struct libmnt_fs
*fs
)
1195 return fs
? fs
->devno
: 0;
1200 * @fs: /proc/tid/mountinfo entry
1202 * Returns: TID (task ID) for filesystems read from the mountinfo file
1204 pid_t
mnt_fs_get_tid(struct libmnt_fs
*fs
)
1206 return fs
? fs
->tid
: 0;
1210 * mnt_fs_get_option:
1211 * @fs: fstab/mtab/mountinfo entry pointer
1212 * @name: option name
1213 * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL
1214 * @valsz: returns size of options value or 0
1216 * Returns: 0 on success, 1 when @name not found or negative number in case of error.
1218 int mnt_fs_get_option(struct libmnt_fs
*fs
, const char *name
,
1219 char **value
, size_t *valsz
)
1226 rc
= mnt_optstr_get_option(fs
->fs_optstr
, name
, value
, valsz
);
1227 if (rc
== 1 && fs
->vfs_optstr
)
1228 rc
= mnt_optstr_get_option(fs
->vfs_optstr
, name
, value
, valsz
);
1229 if (rc
== 1 && fs
->user_optstr
)
1230 rc
= mnt_optstr_get_option(fs
->user_optstr
, name
, value
, valsz
);
1235 * mnt_fs_get_attribute:
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_attribute(struct libmnt_fs
*fs
, const char *name
,
1244 char **value
, size_t *valsz
)
1251 rc
= mnt_optstr_get_option(fs
->attrs
, name
, value
, valsz
);
1256 * mnt_fs_get_comment:
1257 * @fs: fstab/mtab/mountinfo entry pointer
1259 * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
1261 const char *mnt_fs_get_comment(struct libmnt_fs
*fs
)
1269 * mnt_fs_set_comment:
1270 * @fs: fstab entry pointer
1271 * @comm: comment string
1273 * Note that the comment has to be terminated by '\n' (new line), otherwise
1274 * the whole filesystem entry will be written as a comment to the tabfile (e.g.
1277 * Returns: 0 on success or <0 in case of error.
1279 int mnt_fs_set_comment(struct libmnt_fs
*fs
, const char *comm
)
1281 return strdup_to_struct_member(fs
, comment
, comm
);
1285 * mnt_fs_append_comment:
1286 * @fs: fstab entry pointer
1287 * @comm: comment string
1289 * See also mnt_fs_set_comment().
1291 * Returns: 0 on success or <0 in case of error.
1293 int mnt_fs_append_comment(struct libmnt_fs
*fs
, const char *comm
)
1298 return append_string(&fs
->comment
, comm
);
1302 * mnt_fs_match_target:
1304 * @target: mountpoint path
1305 * @cache: tags/paths cache or NULL
1307 * Possible are three attempts:
1308 * 1) compare @target with @fs->target
1310 * 2) realpath(@target) with @fs->target
1312 * 3) realpath(@target) with realpath(@fs->target) if @fs is not from
1313 * /proc/self/mountinfo.
1315 * However, if mnt_cache_set_targets(cache, mtab) was called, and the
1316 * path @target or @fs->target is found in the @mtab, the canonicalization is
1317 * is not performed (see mnt_resolve_target()).
1319 * The 2nd and 3rd attempts are not performed when @cache is NULL.
1321 * Returns: 1 if @fs target is equal to @target, else 0.
1323 int mnt_fs_match_target(struct libmnt_fs
*fs
, const char *target
,
1324 struct libmnt_cache
*cache
)
1328 if (!fs
|| !target
|| !fs
->target
)
1331 /* 1) native paths */
1332 rc
= mnt_fs_streq_target(fs
, target
);
1335 /* 2) - canonicalized and non-canonicalized */
1336 char *cn
= mnt_resolve_target(target
, cache
);
1337 rc
= (cn
&& mnt_fs_streq_target(fs
, cn
));
1339 /* 3) - canonicalized and canonicalized */
1340 if (!rc
&& cn
&& !mnt_fs_is_kernel(fs
) && !mnt_fs_is_swaparea(fs
)) {
1341 char *tcn
= mnt_resolve_target(fs
->target
, cache
);
1342 rc
= (tcn
&& strcmp(cn
, tcn
) == 0);
1350 * mnt_fs_match_source:
1352 * @source: tag or path (device or so) or NULL
1353 * @cache: tags/paths cache or NULL
1355 * Four attempts are possible:
1356 * 1) compare @source with @fs->source
1357 * 2) compare realpath(@source) with @fs->source
1358 * 3) compare realpath(@source) with realpath(@fs->source)
1359 * 4) compare realpath(@source) with evaluated tag from @fs->source
1361 * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The
1362 * 2nd and 3rd attempts are not performed if @fs->source is tag.
1364 * Returns: 1 if @fs source is equal to @source, else 0.
1366 int mnt_fs_match_source(struct libmnt_fs
*fs
, const char *source
,
1367 struct libmnt_cache
*cache
)
1370 const char *src
, *t
, *v
;
1375 /* 1) native paths... */
1376 if (mnt_fs_streq_srcpath(fs
, source
) == 1)
1379 if (!source
|| !fs
->source
)
1383 if (fs
->tagname
&& strcmp(source
, fs
->source
) == 0)
1388 if (fs
->flags
& (MNT_FS_NET
| MNT_FS_PSEUDO
))
1391 cn
= mnt_resolve_spec(source
, cache
);
1395 /* 2) canonicalized and native */
1396 src
= mnt_fs_get_srcpath(fs
);
1397 if (src
&& mnt_fs_streq_srcpath(fs
, cn
))
1400 /* 3) canonicalized and canonicalized */
1402 src
= mnt_resolve_path(src
, cache
);
1403 if (src
&& !strcmp(cn
, src
))
1406 if (src
|| mnt_fs_get_tag(fs
, &t
, &v
))
1407 /* src path does not match and the tag is not defined */
1410 /* read @source's tags to the cache */
1411 if (mnt_cache_read_tags(cache
, cn
) < 0) {
1412 if (errno
== EACCES
) {
1413 /* we don't have permissions to read TAGs from
1414 * @source, but can translate the @fs tag to devname.
1416 * (because libblkid uses udev symlinks and this is
1417 * accessible for non-root uses)
1419 char *x
= mnt_resolve_tag(t
, v
, cache
);
1420 if (x
&& !strcmp(x
, cn
))
1426 /* 4) has the @source a tag that matches with the tag from @fs ? */
1427 if (mnt_cache_device_has_tag(cache
, cn
, t
, v
))
1434 * mnt_fs_match_fstype:
1436 * @types: filesystem name or comma delimited list of filesystems
1438 * For more details see mnt_match_fstype().
1440 * Returns: 1 if @fs type is matching to @types, else 0. The function returns
1441 * 0 when types is NULL.
1443 int mnt_fs_match_fstype(struct libmnt_fs
*fs
, const char *types
)
1445 return mnt_match_fstype(fs
->fstype
, types
);
1449 * mnt_fs_match_options:
1451 * @options: comma delimited list of options (and nooptions)
1453 * For more details see mnt_match_options().
1455 * Returns: 1 if @fs type is matching to @options, else 0. The function returns
1456 * 0 when types is NULL.
1458 int mnt_fs_match_options(struct libmnt_fs
*fs
, const char *options
)
1460 return mnt_match_options(mnt_fs_get_options(fs
), options
);
1464 * mnt_fs_print_debug
1465 * @fs: fstab/mtab/mountinfo entry
1466 * @file: file stream
1468 * Returns: 0 on success or negative number in case of error.
1470 int mnt_fs_print_debug(struct libmnt_fs
*fs
, FILE *file
)
1474 fprintf(file
, "------ fs\n");
1475 fprintf(file
, "source: %s\n", mnt_fs_get_source(fs
));
1476 fprintf(file
, "target: %s\n", mnt_fs_get_target(fs
));
1477 fprintf(file
, "fstype: %s\n", mnt_fs_get_fstype(fs
));
1479 if (mnt_fs_get_options(fs
))
1480 fprintf(file
, "optstr: %s\n", mnt_fs_get_options(fs
));
1481 if (mnt_fs_get_vfs_options(fs
))
1482 fprintf(file
, "VFS-optstr: %s\n", mnt_fs_get_vfs_options(fs
));
1483 if (mnt_fs_get_fs_options(fs
))
1484 fprintf(file
, "FS-opstr: %s\n", mnt_fs_get_fs_options(fs
));
1485 if (mnt_fs_get_user_options(fs
))
1486 fprintf(file
, "user-optstr: %s\n", mnt_fs_get_user_options(fs
));
1487 if (mnt_fs_get_optional_fields(fs
))
1488 fprintf(file
, "optional-fields: '%s'\n", mnt_fs_get_optional_fields(fs
));
1489 if (mnt_fs_get_attributes(fs
))
1490 fprintf(file
, "attributes: %s\n", mnt_fs_get_attributes(fs
));
1492 if (mnt_fs_get_root(fs
))
1493 fprintf(file
, "root: %s\n", mnt_fs_get_root(fs
));
1495 if (mnt_fs_get_swaptype(fs
))
1496 fprintf(file
, "swaptype: %s\n", mnt_fs_get_swaptype(fs
));
1497 if (mnt_fs_get_size(fs
))
1498 fprintf(file
, "size: %jd\n", mnt_fs_get_size(fs
));
1499 if (mnt_fs_get_usedsize(fs
))
1500 fprintf(file
, "usedsize: %jd\n", mnt_fs_get_usedsize(fs
));
1501 if (mnt_fs_get_priority(fs
))
1502 fprintf(file
, "priority: %d\n", mnt_fs_get_priority(fs
));
1504 if (mnt_fs_get_bindsrc(fs
))
1505 fprintf(file
, "bindsrc: %s\n", mnt_fs_get_bindsrc(fs
));
1506 if (mnt_fs_get_freq(fs
))
1507 fprintf(file
, "freq: %d\n", mnt_fs_get_freq(fs
));
1508 if (mnt_fs_get_passno(fs
))
1509 fprintf(file
, "pass: %d\n", mnt_fs_get_passno(fs
));
1510 if (mnt_fs_get_id(fs
))
1511 fprintf(file
, "id: %d\n", mnt_fs_get_id(fs
));
1512 if (mnt_fs_get_parent_id(fs
))
1513 fprintf(file
, "parent: %d\n", mnt_fs_get_parent_id(fs
));
1514 if (mnt_fs_get_devno(fs
))
1515 fprintf(file
, "devno: %d:%d\n", major(mnt_fs_get_devno(fs
)),
1516 minor(mnt_fs_get_devno(fs
)));
1517 if (mnt_fs_get_tid(fs
))
1518 fprintf(file
, "tid: %d\n", mnt_fs_get_tid(fs
));
1519 if (mnt_fs_get_comment(fs
))
1520 fprintf(file
, "comment: '%s'\n", mnt_fs_get_comment(fs
));
1529 * Deallocates the "mntent.h" mount entry.
1531 void mnt_free_mntent(struct mntent
*mnt
)
1534 free(mnt
->mnt_fsname
);
1536 free(mnt
->mnt_type
);
1537 free(mnt
->mnt_opts
);
1545 * @mnt: mount description (as described in mntent.h)
1547 * Copies the information from @fs to struct mntent @mnt. If @mnt is already set,
1548 * then the struct mntent items are reallocated and updated. See also
1549 * mnt_free_mntent().
1551 * Returns: 0 on success and a negative number in case of error.
1553 int mnt_fs_to_mntent(struct libmnt_fs
*fs
, struct mntent
**mnt
)
1563 m
= calloc(1, sizeof(*m
));
1568 if ((rc
= update_str(&m
->mnt_fsname
, mnt_fs_get_source(fs
))))
1570 if ((rc
= update_str(&m
->mnt_dir
, mnt_fs_get_target(fs
))))
1572 if ((rc
= update_str(&m
->mnt_type
, mnt_fs_get_fstype(fs
))))
1576 m
->mnt_opts
= mnt_fs_strdup_options(fs
);
1577 if (!m
->mnt_opts
&& errno
) {
1582 m
->mnt_freq
= mnt_fs_get_freq(fs
);
1583 m
->mnt_passno
= mnt_fs_get_passno(fs
);
1585 if (!m
->mnt_fsname
) {
1586 m
->mnt_fsname
= strdup("none");