]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - libmount/src/fs.c
d143eb5fa1a963dfe0e46faa35fcd4c00966238d
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 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
;
188 /*DBG(FS, ul_debugobj(dest, "copy from %p", src));*/
191 dest
->parent
= src
->parent
;
192 dest
->devno
= src
->devno
;
193 dest
->tid
= src
->tid
;
195 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, source
)))
197 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagname
)))
199 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, tagval
)))
201 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, root
)))
203 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, swaptype
)))
205 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, target
)))
207 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fstype
)))
209 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, optstr
)))
211 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, vfs_optstr
)))
213 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, fs_optstr
)))
215 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, user_optstr
)))
217 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, attrs
)))
219 if (cpy_str_at_offset(dest
, src
, offsetof(struct libmnt_fs
, bindsrc
)))
222 dest
->freq
= src
->freq
;
223 dest
->passno
= src
->passno
;
224 dest
->flags
= src
->flags
;
225 dest
->size
= src
->size
;
226 dest
->usedsize
= src
->usedsize
;
227 dest
->priority
= src
->priority
;
237 * This function copies all @fs description except information that does not
238 * belong to /etc/mtab (e.g. VFS and userspace mount options with MNT_NOMTAB
241 * Returns: copy of @fs.
243 struct libmnt_fs
*mnt_copy_mtab_fs(const struct libmnt_fs
*fs
)
245 struct libmnt_fs
*n
= mnt_new_fs();
251 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, source
)))
253 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, target
)))
255 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fstype
)))
258 if (fs
->vfs_optstr
) {
260 mnt_optstr_get_options(fs
->vfs_optstr
, &p
,
261 mnt_get_builtin_optmap(MNT_LINUX_MAP
),
266 if (fs
->user_optstr
) {
268 mnt_optstr_get_options(fs
->user_optstr
, &p
,
269 mnt_get_builtin_optmap(MNT_USERSPACE_MAP
),
274 if (cpy_str_at_offset(n
, fs
, offsetof(struct libmnt_fs
, fs_optstr
)))
277 /* we cannot copy original optstr, the new optstr has to be without
278 * non-mtab options -- so, let's generate a new string */
279 n
->optstr
= mnt_fs_strdup_options(n
);
282 n
->passno
= fs
->passno
;
283 n
->flags
= fs
->flags
;
293 * mnt_fs_get_userdata:
294 * @fs: struct libmnt_file instance
296 * Returns: private data set by mnt_fs_set_userdata() or NULL.
298 void *mnt_fs_get_userdata(struct libmnt_fs
*fs
)
303 /*DBG(FS, ul_debugobj(fs, "get userdata [%p]", fs->userdata));*/
308 * mnt_fs_set_userdata:
309 * @fs: struct libmnt_file instance
312 * The "userdata" are library independent data.
314 * Returns: 0 or negative number in case of error (if @fs is NULL).
316 int mnt_fs_set_userdata(struct libmnt_fs
*fs
, void *data
)
321 /*DBG(FS, ul_debugobj(fs, "set userdata [%p]", fs->userdata));*/
327 * mnt_fs_get_srcpath:
328 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
330 * The mount "source path" is:
331 * - a directory for 'bind' mounts (in fstab or mtab only)
332 * - a device name for standard mounts
334 * See also mnt_fs_get_tag() and mnt_fs_get_source().
336 * Returns: mount source path or NULL in case of error or when the path
339 const char *mnt_fs_get_srcpath(struct libmnt_fs
*fs
)
346 return NULL
; /* the source contains a "NAME=value" */
352 * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs
354 * Returns: mount source. Note that the source could be unparsed TAG
355 * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag().
357 const char *mnt_fs_get_source(struct libmnt_fs
*fs
)
359 return fs
? fs
->source
: NULL
;
363 * Used by the parser ONLY (@source has to be freed on error)
365 int __mnt_fs_set_source_ptr(struct libmnt_fs
*fs
, char *source
)
367 char *t
= NULL
, *v
= NULL
;
371 if (source
&& blkid_parse_tag_string(source
, &t
, &v
) == 0 &&
372 !mnt_valid_tagname(t
)) {
373 /* parsable but unknown tag -- ignore */
379 if (fs
->source
!= source
)
393 * @fs: fstab/mtab/mountinfo entry
394 * @source: new source
396 * This function creates a private copy (strdup()) of @source.
398 * Returns: 0 on success or negative number in case of error.
400 int mnt_fs_set_source(struct libmnt_fs
*fs
, const char *source
)
414 rc
= __mnt_fs_set_source_ptr(fs
, p
);
421 * mnt_fs_streq_srcpath:
425 * Compares @fs source path with @path. The redundant slashs are ignored.
426 * This function compares strings and does not cannonicalize the paths.
427 * See also more heavy and generic mnt_fs_match_source().
429 * Returns: 1 if @fs source path equal to @path, otherwise 0.
431 int mnt_fs_streq_srcpath(struct libmnt_fs
*fs
, const char *path
)
438 p
= mnt_fs_get_srcpath(fs
);
440 if (!mnt_fs_is_pseudofs(fs
))
441 return streq_paths(p
, path
);
446 return p
&& path
&& strcmp(p
, path
) == 0;
450 * mnt_fs_streq_target:
454 * Compares @fs target path with @path. The redundant slashs are ignored.
455 * This function compares strings and does not cannonicalize the paths.
456 * See also more generic mnt_fs_match_target().
458 * Returns: 1 if @fs target path equal to @path, otherwise 0.
460 int mnt_fs_streq_target(struct libmnt_fs
*fs
, const char *path
)
462 return fs
&& streq_paths(mnt_fs_get_target(fs
), path
);
468 * @name: returns pointer to NAME string
469 * @value: returns pointer to VALUE string
471 * "TAG" is NAME=VALUE (e.g. LABEL=foo)
473 * The TAG is the first column in the fstab file. The TAG or "srcpath" always has
474 * to be set for all entries.
476 * See also mnt_fs_get_source().
481 * struct libmnt_fs *fs = mnt_table_find_target(tb, "/home", MNT_ITER_FORWARD);
486 * src = mnt_fs_get_srcpath(fs);
489 * if (mnt_fs_get_tag(fs, &tag, &val) == 0)
490 * printf("%s: %s\n", tag, val); // LABEL or UUID
492 * printf("device: %s\n", src); // device or bind path
496 * Returns: 0 on success or negative number in case a TAG is not defined.
498 int mnt_fs_get_tag(struct libmnt_fs
*fs
, const char **name
, const char **value
)
500 if (fs
== NULL
|| !fs
->tagname
)
511 * @fs: fstab/mtab/mountinfo entry pointer
513 * Returns: pointer to mountpoint path or NULL
515 const char *mnt_fs_get_target(struct libmnt_fs
*fs
)
517 return fs
? fs
->target
: NULL
;
522 * @fs: fstab/mtab/mountinfo entry
525 * This function creates a private copy (strdup()) of @tgt.
527 * Returns: 0 on success or negative number in case of error.
529 int mnt_fs_set_target(struct libmnt_fs
*fs
, const char *tgt
)
531 return strdup_to_struct_member(fs
, target
, tgt
);
534 static int mnt_fs_get_flags(struct libmnt_fs
*fs
)
536 return fs
? fs
->flags
: 0;
540 * mnt_fs_get_propagation:
541 * @fs: mountinfo entry
542 * @flags: returns propagation MS_* flags as present in the mountinfo file
544 * Note that this function sets @flags to zero if no propagation flags are found
545 * in the mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored
546 * in the mountinfo file.
548 * Returns: 0 on success or negative number in case of error.
550 int mnt_fs_get_propagation(struct libmnt_fs
*fs
, unsigned long *flags
)
561 * The optional fields format is incompatible with mount options
562 * ... we have to parse the field here.
564 *flags
|= strstr(fs
->opt_fields
, "shared:") ? MS_SHARED
: MS_PRIVATE
;
566 if (strstr(fs
->opt_fields
, "master:"))
568 if (strstr(fs
->opt_fields
, "unbindable"))
569 *flags
|= MS_UNBINDABLE
;
578 * Returns: 1 if the filesystem description is read from kernel e.g. /proc/mounts.
580 int mnt_fs_is_kernel(struct libmnt_fs
*fs
)
582 return mnt_fs_get_flags(fs
) & MNT_FS_KERNEL
;
586 * mnt_fs_is_swaparea:
589 * Returns: 1 if the filesystem uses "swap" as a type
591 int mnt_fs_is_swaparea(struct libmnt_fs
*fs
)
593 return mnt_fs_get_flags(fs
) & MNT_FS_SWAP
;
597 * mnt_fs_is_pseudofs:
600 * Returns: 1 if the filesystem is a pseudo fs type (proc, cgroups)
602 int mnt_fs_is_pseudofs(struct libmnt_fs
*fs
)
604 return mnt_fs_get_flags(fs
) & MNT_FS_PSEUDO
;
611 * Returns: 1 if the filesystem is a network filesystem
613 int mnt_fs_is_netfs(struct libmnt_fs
*fs
)
615 return mnt_fs_get_flags(fs
) & MNT_FS_NET
;
620 * @fs: fstab/mtab/mountinfo entry pointer
622 * Returns: pointer to filesystem type.
624 const char *mnt_fs_get_fstype(struct libmnt_fs
*fs
)
626 return fs
? fs
->fstype
: NULL
;
629 /* Used by the struct libmnt_file parser only */
630 int __mnt_fs_set_fstype_ptr(struct libmnt_fs
*fs
, char *fstype
)
634 if (fstype
!= fs
->fstype
)
638 fs
->flags
&= ~MNT_FS_PSEUDO
;
639 fs
->flags
&= ~MNT_FS_NET
;
640 fs
->flags
&= ~MNT_FS_SWAP
;
642 /* save info about pseudo filesystems */
644 if (mnt_fstype_is_pseudofs(fs
->fstype
))
645 fs
->flags
|= MNT_FS_PSEUDO
;
646 else if (mnt_fstype_is_netfs(fs
->fstype
))
647 fs
->flags
|= MNT_FS_NET
;
648 else if (!strcmp(fs
->fstype
, "swap"))
649 fs
->flags
|= MNT_FS_SWAP
;
656 * @fs: fstab/mtab/mountinfo entry
657 * @fstype: filesystem type
659 * This function creates a private copy (strdup()) of @fstype.
661 * Returns: 0 on success or negative number in case of error.
663 int mnt_fs_set_fstype(struct libmnt_fs
*fs
, const char *fstype
)
674 return __mnt_fs_set_fstype_ptr(fs
, p
);
678 * Merges @vfs and @fs options strings into a new string.
679 * This function cares about 'ro/rw' options. The 'ro' is
680 * always used if @vfs or @fs is read-only.
683 * mnt_merge_optstr("rw,noexec", "ro,journal=update")
685 * returns: "ro,noexec,journal=update"
687 * mnt_merge_optstr("rw,noexec", "rw,journal=update")
689 * returns: "rw,noexec,journal=update"
691 static char *merge_optstr(const char *vfs
, const char *fs
)
700 return strdup(fs
? fs
: vfs
);
701 if (!strcmp(vfs
, fs
))
702 return strdup(vfs
); /* e.g. "aaa" and "aaa" */
704 /* leave space for the leading "r[ow],", "," and the trailing zero */
705 sz
= strlen(vfs
) + strlen(fs
) + 5;
709 p
= res
+ 3; /* make a room for rw/ro flag */
711 snprintf(p
, sz
- 3, "%s,%s", vfs
, fs
);
713 /* remove 'rw' flags */
714 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from vfs */
715 rw
+= !mnt_optstr_remove_option(&p
, "rw"); /* from fs */
717 /* remove 'ro' flags if necessary */
719 ro
+= !mnt_optstr_remove_option(&p
, "ro");
721 ro
+= !mnt_optstr_remove_option(&p
, "ro");
725 memcpy(res
, ro
? "ro" : "rw", 3);
727 memcpy(res
, ro
? "ro," : "rw,", 3);
732 * mnt_fs_strdup_options:
733 * @fs: fstab/mtab/mountinfo entry pointer
735 * Merges all mount options (VFS, FS and userspace) to one options string
736 * and returns the result. This function does not modify @fs.
738 * Returns: pointer to string (can be freed by free(3)) or NULL in case of error.
740 char *mnt_fs_strdup_options(struct libmnt_fs
*fs
)
749 return strdup(fs
->optstr
);
751 res
= merge_optstr(fs
->vfs_optstr
, fs
->fs_optstr
);
754 if (fs
->user_optstr
&&
755 mnt_optstr_append_option(&res
, fs
->user_optstr
, NULL
)) {
763 * mnt_fs_get_options:
764 * @fs: fstab/mtab/mountinfo entry pointer
766 * Returns: pointer to string or NULL in case of error.
768 const char *mnt_fs_get_options(struct libmnt_fs
*fs
)
770 return fs
? fs
->optstr
: NULL
;
774 * mnt_fs_get_optional_fields
775 * @fs: mountinfo entry pointer
777 * Returns: pointer to string with mountinfo optional fields
778 * or NULL in case of error.
780 const char *mnt_fs_get_optional_fields(struct libmnt_fs
*fs
)
782 return fs
? fs
->opt_fields
: NULL
;
786 * mnt_fs_set_options:
787 * @fs: fstab/mtab/mountinfo entry pointer
788 * @optstr: options string
790 * Splits @optstr to VFS, FS and userspace mount options and updates relevant
793 * Returns: 0 on success, or negative number in case of error.
795 int mnt_fs_set_options(struct libmnt_fs
*fs
, const char *optstr
)
797 char *v
= NULL
, *f
= NULL
, *u
= NULL
, *n
= NULL
;
802 int rc
= mnt_split_optstr(optstr
, &u
, &v
, &f
, 0, 0);
815 free(fs
->vfs_optstr
);
816 free(fs
->user_optstr
);
828 * mnt_fs_append_options:
829 * @fs: fstab/mtab/mountinfo entry
830 * @optstr: mount options
832 * Parses (splits) @optstr and appends results to VFS, FS and userspace lists
835 * If @optstr is NULL, then @fs is not modified and 0 is returned.
837 * Returns: 0 on success or negative number in case of error.
839 int mnt_fs_append_options(struct libmnt_fs
*fs
, const char *optstr
)
841 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
849 rc
= mnt_split_optstr((char *) optstr
, &u
, &v
, &f
, 0, 0);
854 rc
= mnt_optstr_append_option(&fs
->vfs_optstr
, v
, NULL
);
856 rc
= mnt_optstr_append_option(&fs
->fs_optstr
, f
, NULL
);
858 rc
= mnt_optstr_append_option(&fs
->user_optstr
, u
, NULL
);
860 rc
= mnt_optstr_append_option(&fs
->optstr
, optstr
, NULL
);
870 * mnt_fs_prepend_options:
871 * @fs: fstab/mtab/mountinfo entry
872 * @optstr: mount options
874 * Parses (splits) @optstr and prepends the results to VFS, FS and userspace lists
877 * If @optstr is NULL, then @fs is not modified and 0 is returned.
879 * Returns: 0 on success or negative number in case of error.
881 int mnt_fs_prepend_options(struct libmnt_fs
*fs
, const char *optstr
)
883 char *v
= NULL
, *f
= NULL
, *u
= NULL
;
891 rc
= mnt_split_optstr((char *) optstr
, &u
, &v
, &f
, 0, 0);
896 rc
= mnt_optstr_prepend_option(&fs
->vfs_optstr
, v
, NULL
);
898 rc
= mnt_optstr_prepend_option(&fs
->fs_optstr
, f
, NULL
);
900 rc
= mnt_optstr_prepend_option(&fs
->user_optstr
, u
, NULL
);
902 rc
= mnt_optstr_prepend_option(&fs
->optstr
, optstr
, NULL
);
912 * mnt_fs_get_fs_options:
913 * @fs: fstab/mtab/mountinfo entry pointer
915 * Returns: pointer to superblock (fs-depend) mount option string or NULL.
917 const char *mnt_fs_get_fs_options(struct libmnt_fs
*fs
)
919 return fs
? fs
->fs_optstr
: NULL
;
923 * mnt_fs_get_vfs_options:
924 * @fs: fstab/mtab entry pointer
926 * Returns: pointer to fs-independent (VFS) mount option string or NULL.
928 const char *mnt_fs_get_vfs_options(struct libmnt_fs
*fs
)
930 return fs
? fs
->vfs_optstr
: NULL
;
934 * mnt_fs_get_user_options:
935 * @fs: fstab/mtab entry pointer
937 * Returns: pointer to userspace mount option string or NULL.
939 const char *mnt_fs_get_user_options(struct libmnt_fs
*fs
)
941 return fs
? fs
->user_optstr
: NULL
;
945 * mnt_fs_get_attributes:
946 * @fs: fstab/mtab entry pointer
948 * Returns: pointer to attributes string or NULL.
950 const char *mnt_fs_get_attributes(struct libmnt_fs
*fs
)
952 return fs
? fs
->attrs
: NULL
;
956 * mnt_fs_set_attributes:
957 * @fs: fstab/mtab/mountinfo entry
958 * @optstr: options string
960 * Sets mount attributes. The attributes are mount(2) and mount(8) independent
961 * options, these options are not sent to the kernel and are not interpreted by
962 * libmount. The attributes are stored in /run/mount/utab only.
964 * The attributes are managed by libmount in userspace only. It's possible
965 * that information stored in userspace will not be available for libmount
966 * after CLONE_FS unshare. Be careful, and don't use attributes if possible.
968 * Returns: 0 on success or negative number in case of error.
970 int mnt_fs_set_attributes(struct libmnt_fs
*fs
, const char *optstr
)
972 return strdup_to_struct_member(fs
, attrs
, optstr
);
976 * mnt_fs_append_attributes
977 * @fs: fstab/mtab/mountinfo entry
978 * @optstr: options string
980 * Appends mount attributes. (See mnt_fs_set_attributes()).
982 * Returns: 0 on success or negative number in case of error.
984 int mnt_fs_append_attributes(struct libmnt_fs
*fs
, const char *optstr
)
990 return mnt_optstr_append_option(&fs
->attrs
, optstr
, NULL
);
994 * mnt_fs_prepend_attributes
995 * @fs: fstab/mtab/mountinfo entry
996 * @optstr: options string
998 * Prepends mount attributes. (See mnt_fs_set_attributes()).
1000 * Returns: 0 on success or negative number in case of error.
1002 int mnt_fs_prepend_attributes(struct libmnt_fs
*fs
, const char *optstr
)
1008 return mnt_optstr_prepend_option(&fs
->attrs
, optstr
, NULL
);
1014 * @fs: fstab/mtab/mountinfo entry pointer
1016 * Returns: dump frequency in days.
1018 int mnt_fs_get_freq(struct libmnt_fs
*fs
)
1020 return fs
? fs
->freq
: 0;
1025 * @fs: fstab/mtab entry pointer
1026 * @freq: dump frequency in days
1028 * Returns: 0 on success or negative number in case of error.
1030 int mnt_fs_set_freq(struct libmnt_fs
*fs
, int freq
)
1039 * mnt_fs_get_passno:
1040 * @fs: fstab/mtab entry pointer
1042 * Returns: "pass number on parallel fsck".
1044 int mnt_fs_get_passno(struct libmnt_fs
*fs
)
1046 return fs
? fs
->passno
: 0;
1050 * mnt_fs_set_passno:
1051 * @fs: fstab/mtab entry pointer
1052 * @passno: pass number
1054 * Returns: 0 on success or negative number in case of error.
1056 int mnt_fs_set_passno(struct libmnt_fs
*fs
, int passno
)
1060 fs
->passno
= passno
;
1066 * @fs: /proc/self/mountinfo entry
1068 * Returns: root of the mount within the filesystem or NULL
1070 const char *mnt_fs_get_root(struct libmnt_fs
*fs
)
1072 return fs
? fs
->root
: NULL
;
1077 * @fs: mountinfo entry
1080 * Returns: 0 on success or negative number in case of error.
1082 int mnt_fs_set_root(struct libmnt_fs
*fs
, const char *path
)
1084 return strdup_to_struct_member(fs
, root
, path
);
1088 * mnt_fs_get_swaptype:
1089 * @fs: /proc/swaps entry
1091 * Returns: swap type or NULL
1093 const char *mnt_fs_get_swaptype(struct libmnt_fs
*fs
)
1095 return fs
? fs
->swaptype
: NULL
;
1100 * @fs: /proc/swaps entry
1104 off_t
mnt_fs_get_size(struct libmnt_fs
*fs
)
1106 return fs
? fs
->size
: 0;
1110 * mnt_fs_get_usedsize:
1111 * @fs: /proc/swaps entry
1113 * Returns: used size
1115 off_t
mnt_fs_get_usedsize(struct libmnt_fs
*fs
)
1117 return fs
? fs
->usedsize
: 0;
1121 * mnt_fs_get_priority:
1122 * @fs: /proc/swaps entry
1126 int mnt_fs_get_priority(struct libmnt_fs
*fs
)
1128 return fs
? fs
->priority
: 0;
1132 * mnt_fs_set_priority:
1133 * @fs: /proc/swaps entry
1136 * Returns: 0 or -1 in case of error
1138 int mnt_fs_set_priority(struct libmnt_fs
*fs
, int prio
)
1142 fs
->priority
= prio
;
1147 * mnt_fs_get_bindsrc:
1148 * @fs: /run/mount/utab entry
1150 * Returns: full path that was used for mount(2) on MS_BIND
1152 const char *mnt_fs_get_bindsrc(struct libmnt_fs
*fs
)
1154 return fs
? fs
->bindsrc
: NULL
;
1158 * mnt_fs_set_bindsrc:
1162 * Returns: 0 on success or negative number in case of error.
1164 int mnt_fs_set_bindsrc(struct libmnt_fs
*fs
, const char *src
)
1166 return strdup_to_struct_member(fs
, bindsrc
, src
);
1171 * @fs: /proc/self/mountinfo entry
1173 * Returns: mount ID (unique identifier of the mount) or negative number in case of error.
1175 int mnt_fs_get_id(struct libmnt_fs
*fs
)
1177 return fs
? fs
->id
: -EINVAL
;
1181 * mnt_fs_get_parent_id:
1182 * @fs: /proc/self/mountinfo entry
1184 * Returns: parent mount ID or negative number in case of error.
1186 int mnt_fs_get_parent_id(struct libmnt_fs
*fs
)
1188 return fs
? fs
->parent
: -EINVAL
;
1193 * @fs: /proc/self/mountinfo entry
1195 * Returns: value of st_dev for files on filesystem or 0 in case of error.
1197 dev_t
mnt_fs_get_devno(struct libmnt_fs
*fs
)
1199 return fs
? fs
->devno
: 0;
1204 * @fs: /proc/tid/mountinfo entry
1206 * Returns: TID (task ID) for filesystems read from the mountinfo file
1208 pid_t
mnt_fs_get_tid(struct libmnt_fs
*fs
)
1210 return fs
? fs
->tid
: 0;
1214 * mnt_fs_get_option:
1215 * @fs: fstab/mtab/mountinfo entry pointer
1216 * @name: option name
1217 * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL
1218 * @valsz: returns size of options value or 0
1220 * Returns: 0 on success, 1 when @name not found or negative number in case of error.
1222 int mnt_fs_get_option(struct libmnt_fs
*fs
, const char *name
,
1223 char **value
, size_t *valsz
)
1230 rc
= mnt_optstr_get_option(fs
->fs_optstr
, name
, value
, valsz
);
1231 if (rc
== 1 && fs
->vfs_optstr
)
1232 rc
= mnt_optstr_get_option(fs
->vfs_optstr
, name
, value
, valsz
);
1233 if (rc
== 1 && fs
->user_optstr
)
1234 rc
= mnt_optstr_get_option(fs
->user_optstr
, name
, value
, valsz
);
1239 * mnt_fs_get_attribute:
1240 * @fs: fstab/mtab/mountinfo entry pointer
1241 * @name: option name
1242 * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL
1243 * @valsz: returns size of options value or 0
1245 * Returns: 0 on success, 1 when @name not found or negative number in case of error.
1247 int mnt_fs_get_attribute(struct libmnt_fs
*fs
, const char *name
,
1248 char **value
, size_t *valsz
)
1255 rc
= mnt_optstr_get_option(fs
->attrs
, name
, value
, valsz
);
1260 * mnt_fs_get_comment:
1261 * @fs: fstab/mtab/mountinfo entry pointer
1263 * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
1265 const char *mnt_fs_get_comment(struct libmnt_fs
*fs
)
1273 * mnt_fs_set_comment:
1274 * @fs: fstab entry pointer
1275 * @comm: comment string
1277 * Note that the comment has to be terminated by '\n' (new line), otherwise
1278 * the whole filesystem entry will be written as a comment to the tabfile (e.g.
1281 * Returns: 0 on success or <0 in case of error.
1283 int mnt_fs_set_comment(struct libmnt_fs
*fs
, const char *comm
)
1285 return strdup_to_struct_member(fs
, comment
, comm
);
1289 * mnt_fs_append_comment:
1290 * @fs: fstab entry pointer
1291 * @comm: comment string
1293 * See also mnt_fs_set_comment().
1295 * Returns: 0 on success or <0 in case of error.
1297 int mnt_fs_append_comment(struct libmnt_fs
*fs
, const char *comm
)
1302 return append_string(&fs
->comment
, comm
);
1306 * mnt_fs_match_target:
1308 * @target: mountpoint path
1309 * @cache: tags/paths cache or NULL
1311 * Possible are three attempts:
1312 * 1) compare @target with @fs->target
1314 * 2) realpath(@target) with @fs->target
1316 * 3) realpath(@target) with realpath(@fs->target) if @fs is not from
1317 * /proc/self/mountinfo.
1319 * However, if mnt_cache_set_targets(cache, mtab) was called, and the
1320 * path @target or @fs->target is found in the @mtab, the canonicalization is
1321 * is not performed (see mnt_resolve_target()).
1323 * The 2nd and 3rd attempts are not performed when @cache is NULL.
1325 * Returns: 1 if @fs target is equal to @target, else 0.
1327 int mnt_fs_match_target(struct libmnt_fs
*fs
, const char *target
,
1328 struct libmnt_cache
*cache
)
1332 if (!fs
|| !target
|| !fs
->target
)
1335 /* 1) native paths */
1336 rc
= mnt_fs_streq_target(fs
, target
);
1339 /* 2) - canonicalized and non-canonicalized */
1340 char *cn
= mnt_resolve_target(target
, cache
);
1341 rc
= (cn
&& mnt_fs_streq_target(fs
, cn
));
1343 /* 3) - canonicalized and canonicalized */
1344 if (!rc
&& cn
&& !mnt_fs_is_kernel(fs
) && !mnt_fs_is_swaparea(fs
)) {
1345 char *tcn
= mnt_resolve_target(fs
->target
, cache
);
1346 rc
= (tcn
&& strcmp(cn
, tcn
) == 0);
1354 * mnt_fs_match_source:
1356 * @source: tag or path (device or so) or NULL
1357 * @cache: tags/paths cache or NULL
1359 * Four attempts are possible:
1360 * 1) compare @source with @fs->source
1361 * 2) compare realpath(@source) with @fs->source
1362 * 3) compare realpath(@source) with realpath(@fs->source)
1363 * 4) compare realpath(@source) with evaluated tag from @fs->source
1365 * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The
1366 * 2nd and 3rd attempts are not performed if @fs->source is tag.
1368 * Returns: 1 if @fs source is equal to @source, else 0.
1370 int mnt_fs_match_source(struct libmnt_fs
*fs
, const char *source
,
1371 struct libmnt_cache
*cache
)
1374 const char *src
, *t
, *v
;
1379 /* 1) native paths... */
1380 if (mnt_fs_streq_srcpath(fs
, source
) == 1)
1383 if (!source
|| !fs
->source
)
1387 if (fs
->tagname
&& strcmp(source
, fs
->source
) == 0)
1392 if (fs
->flags
& (MNT_FS_NET
| MNT_FS_PSEUDO
))
1395 cn
= mnt_resolve_spec(source
, cache
);
1399 /* 2) canonicalized and native */
1400 src
= mnt_fs_get_srcpath(fs
);
1401 if (src
&& mnt_fs_streq_srcpath(fs
, cn
))
1404 /* 3) canonicalized and canonicalized */
1406 src
= mnt_resolve_path(src
, cache
);
1407 if (src
&& !strcmp(cn
, src
))
1410 if (src
|| mnt_fs_get_tag(fs
, &t
, &v
))
1411 /* src path does not match and the tag is not defined */
1414 /* read @source's tags to the cache */
1415 if (mnt_cache_read_tags(cache
, cn
) < 0) {
1416 if (errno
== EACCES
) {
1417 /* we don't have permissions to read TAGs from
1418 * @source, but can translate the @fs tag to devname.
1420 * (because libblkid uses udev symlinks and this is
1421 * accessible for non-root uses)
1423 char *x
= mnt_resolve_tag(t
, v
, cache
);
1424 if (x
&& !strcmp(x
, cn
))
1430 /* 4) has the @source a tag that matches with the tag from @fs ? */
1431 if (mnt_cache_device_has_tag(cache
, cn
, t
, v
))
1438 * mnt_fs_match_fstype:
1440 * @types: filesystem name or comma delimited list of filesystems
1442 * For more details see mnt_match_fstype().
1444 * Returns: 1 if @fs type is matching to @types, else 0. The function returns
1445 * 0 when types is NULL.
1447 int mnt_fs_match_fstype(struct libmnt_fs
*fs
, const char *types
)
1449 return mnt_match_fstype(fs
->fstype
, types
);
1453 * mnt_fs_match_options:
1455 * @options: comma delimited list of options (and nooptions)
1457 * For more details see mnt_match_options().
1459 * Returns: 1 if @fs type is matching to @options, else 0. The function returns
1460 * 0 when types is NULL.
1462 int mnt_fs_match_options(struct libmnt_fs
*fs
, const char *options
)
1464 return mnt_match_options(mnt_fs_get_options(fs
), options
);
1468 * mnt_fs_print_debug
1469 * @fs: fstab/mtab/mountinfo entry
1470 * @file: file stream
1472 * Returns: 0 on success or negative number in case of error.
1474 int mnt_fs_print_debug(struct libmnt_fs
*fs
, FILE *file
)
1478 fprintf(file
, "------ fs: %p\n", fs
);
1479 fprintf(file
, "source: %s\n", mnt_fs_get_source(fs
));
1480 fprintf(file
, "target: %s\n", mnt_fs_get_target(fs
));
1481 fprintf(file
, "fstype: %s\n", mnt_fs_get_fstype(fs
));
1483 if (mnt_fs_get_options(fs
))
1484 fprintf(file
, "optstr: %s\n", mnt_fs_get_options(fs
));
1485 if (mnt_fs_get_vfs_options(fs
))
1486 fprintf(file
, "VFS-optstr: %s\n", mnt_fs_get_vfs_options(fs
));
1487 if (mnt_fs_get_fs_options(fs
))
1488 fprintf(file
, "FS-opstr: %s\n", mnt_fs_get_fs_options(fs
));
1489 if (mnt_fs_get_user_options(fs
))
1490 fprintf(file
, "user-optstr: %s\n", mnt_fs_get_user_options(fs
));
1491 if (mnt_fs_get_optional_fields(fs
))
1492 fprintf(file
, "optional-fields: '%s'\n", mnt_fs_get_optional_fields(fs
));
1493 if (mnt_fs_get_attributes(fs
))
1494 fprintf(file
, "attributes: %s\n", mnt_fs_get_attributes(fs
));
1496 if (mnt_fs_get_root(fs
))
1497 fprintf(file
, "root: %s\n", mnt_fs_get_root(fs
));
1499 if (mnt_fs_get_swaptype(fs
))
1500 fprintf(file
, "swaptype: %s\n", mnt_fs_get_swaptype(fs
));
1501 if (mnt_fs_get_size(fs
))
1502 fprintf(file
, "size: %jd\n", mnt_fs_get_size(fs
));
1503 if (mnt_fs_get_usedsize(fs
))
1504 fprintf(file
, "usedsize: %jd\n", mnt_fs_get_usedsize(fs
));
1505 if (mnt_fs_get_priority(fs
))
1506 fprintf(file
, "priority: %d\n", mnt_fs_get_priority(fs
));
1508 if (mnt_fs_get_bindsrc(fs
))
1509 fprintf(file
, "bindsrc: %s\n", mnt_fs_get_bindsrc(fs
));
1510 if (mnt_fs_get_freq(fs
))
1511 fprintf(file
, "freq: %d\n", mnt_fs_get_freq(fs
));
1512 if (mnt_fs_get_passno(fs
))
1513 fprintf(file
, "pass: %d\n", mnt_fs_get_passno(fs
));
1514 if (mnt_fs_get_id(fs
))
1515 fprintf(file
, "id: %d\n", mnt_fs_get_id(fs
));
1516 if (mnt_fs_get_parent_id(fs
))
1517 fprintf(file
, "parent: %d\n", mnt_fs_get_parent_id(fs
));
1518 if (mnt_fs_get_devno(fs
))
1519 fprintf(file
, "devno: %d:%d\n", major(mnt_fs_get_devno(fs
)),
1520 minor(mnt_fs_get_devno(fs
)));
1521 if (mnt_fs_get_tid(fs
))
1522 fprintf(file
, "tid: %d\n", mnt_fs_get_tid(fs
));
1523 if (mnt_fs_get_comment(fs
))
1524 fprintf(file
, "comment: '%s'\n", mnt_fs_get_comment(fs
));
1533 * Deallocates the "mntent.h" mount entry.
1535 void mnt_free_mntent(struct mntent
*mnt
)
1538 free(mnt
->mnt_fsname
);
1540 free(mnt
->mnt_type
);
1541 free(mnt
->mnt_opts
);
1549 * @mnt: mount description (as described in mntent.h)
1551 * Copies the information from @fs to struct mntent @mnt. If @mnt is already set,
1552 * then the struct mntent items are reallocated and updated. See also
1553 * mnt_free_mntent().
1555 * Returns: 0 on success and a negative number in case of error.
1557 int mnt_fs_to_mntent(struct libmnt_fs
*fs
, struct mntent
**mnt
)
1567 m
= calloc(1, sizeof(*m
));
1572 if ((rc
= update_str(&m
->mnt_fsname
, mnt_fs_get_source(fs
))))
1574 if ((rc
= update_str(&m
->mnt_dir
, mnt_fs_get_target(fs
))))
1576 if ((rc
= update_str(&m
->mnt_type
, mnt_fs_get_fstype(fs
))))
1580 m
->mnt_opts
= mnt_fs_strdup_options(fs
);
1581 if (!m
->mnt_opts
&& errno
) {
1586 m
->mnt_freq
= mnt_fs_get_freq(fs
);
1587 m
->mnt_passno
= mnt_fs_get_passno(fs
);
1589 if (!m
->mnt_fsname
) {
1590 m
->mnt_fsname
= strdup("none");