]>
Commit | Line | Data |
---|---|---|
2c37ca7c | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
d115ee9b | 2 | /* |
2c37ca7c | 3 | * This file is part of libmount from util-linux project. |
d115ee9b | 4 | * |
2c37ca7c KZ |
5 | * Copyright (C) 2008-2018 Karel Zak <kzak@redhat.com> |
6 | * | |
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. | |
d115ee9b KZ |
11 | */ |
12 | ||
192c6aad KZ |
13 | /** |
14 | * SECTION: fs | |
15 | * @title: Filesystem | |
63de90d4 | 16 | * @short_description: represents one entry from fstab, mtab, or mountinfo file |
192c6aad KZ |
17 | * |
18 | */ | |
d115ee9b | 19 | #include <ctype.h> |
8e368761 | 20 | #include <blkid.h> |
9ecdf48f | 21 | #include <stddef.h> |
d115ee9b | 22 | |
d115ee9b | 23 | #include "mountP.h" |
b106d052 | 24 | #include "strutils.h" |
d115ee9b KZ |
25 | |
26 | /** | |
27 | * mnt_new_fs: | |
28 | * | |
26d0c0ae KZ |
29 | * The initial refcount is 1, and needs to be decremented to |
30 | * release the resources of the filesystem. | |
31 | * | |
68164f6c | 32 | * Returns: newly allocated struct libmnt_fs. |
d115ee9b | 33 | */ |
68164f6c | 34 | struct libmnt_fs *mnt_new_fs(void) |
d115ee9b | 35 | { |
68164f6c | 36 | struct libmnt_fs *fs = calloc(1, sizeof(*fs)); |
d115ee9b KZ |
37 | if (!fs) |
38 | return NULL; | |
39 | ||
26d0c0ae | 40 | fs->refcount = 1; |
d115ee9b | 41 | INIT_LIST_HEAD(&fs->ents); |
83a78332 | 42 | /*DBG(FS, ul_debugobj(fs, "alloc"));*/ |
d115ee9b KZ |
43 | return fs; |
44 | } | |
45 | ||
46 | /** | |
47 | * mnt_free_fs: | |
48 | * @fs: fs pointer | |
49 | * | |
26d0c0ae | 50 | * Deallocates the fs. This function does not care about reference count. Don't |
a7349ee3 | 51 | * use this function directly -- it's better to use mnt_unref_fs(). |
26d0c0ae KZ |
52 | * |
53 | * The reference counting is supported since util-linux v2.24. | |
d115ee9b | 54 | */ |
68164f6c | 55 | void mnt_free_fs(struct libmnt_fs *fs) |
d115ee9b KZ |
56 | { |
57 | if (!fs) | |
58 | return; | |
309139c7 | 59 | |
a504eaed | 60 | DBG(FS, ul_debugobj(fs, "free [refcount=%d]", fs->refcount)); |
d115ee9b | 61 | |
a504eaed | 62 | mnt_reset_fs(fs); |
d115ee9b KZ |
63 | free(fs); |
64 | } | |
65 | ||
309139c7 KZ |
66 | /** |
67 | * mnt_reset_fs: | |
68 | * @fs: fs pointer | |
69 | * | |
70 | * Resets (zeroize) @fs. | |
71 | */ | |
72 | void mnt_reset_fs(struct libmnt_fs *fs) | |
73 | { | |
26d0c0ae KZ |
74 | int ref; |
75 | ||
76 | if (!fs) | |
77 | return; | |
78 | ||
79 | ref = fs->refcount; | |
a504eaed KZ |
80 | |
81 | list_del(&fs->ents); | |
82 | free(fs->source); | |
83 | free(fs->bindsrc); | |
84 | free(fs->tagname); | |
85 | free(fs->tagval); | |
86 | free(fs->root); | |
87 | free(fs->swaptype); | |
88 | free(fs->target); | |
89 | free(fs->fstype); | |
90 | free(fs->optstr); | |
91 | free(fs->vfs_optstr); | |
92 | free(fs->fs_optstr); | |
93 | free(fs->user_optstr); | |
94 | free(fs->attrs); | |
95 | free(fs->opt_fields); | |
96 | free(fs->comment); | |
97 | ||
26d0c0ae | 98 | memset(fs, 0, sizeof(*fs)); |
14104e93 | 99 | INIT_LIST_HEAD(&fs->ents); |
26d0c0ae KZ |
100 | fs->refcount = ref; |
101 | } | |
102 | ||
103 | /** | |
104 | * mnt_ref_fs: | |
105 | * @fs: fs pointer | |
106 | * | |
107 | * Increments reference counter. | |
108 | */ | |
109 | void mnt_ref_fs(struct libmnt_fs *fs) | |
110 | { | |
111 | if (fs) { | |
112 | fs->refcount++; | |
83a78332 | 113 | /*DBG(FS, ul_debugobj(fs, "ref=%d", fs->refcount));*/ |
26d0c0ae KZ |
114 | } |
115 | } | |
116 | ||
117 | /** | |
118 | * mnt_unref_fs: | |
119 | * @fs: fs pointer | |
120 | * | |
47cca899 | 121 | * De-increments reference counter, on zero the @fs is automatically |
26d0c0ae KZ |
122 | * deallocated by mnt_free_fs(). |
123 | */ | |
124 | void mnt_unref_fs(struct libmnt_fs *fs) | |
125 | { | |
126 | if (fs) { | |
127 | fs->refcount--; | |
83a78332 | 128 | /*DBG(FS, ul_debugobj(fs, "unref=%d", fs->refcount));*/ |
26d0c0ae KZ |
129 | if (fs->refcount <= 0) |
130 | mnt_free_fs(fs); | |
131 | } | |
309139c7 KZ |
132 | } |
133 | ||
134 | static inline int update_str(char **dest, const char *src) | |
9ecdf48f | 135 | { |
8b95253f KZ |
136 | size_t sz; |
137 | char *x; | |
138 | ||
139 | assert(dest); | |
9ecdf48f | 140 | |
8b95253f KZ |
141 | if (!src) { |
142 | free(*dest); | |
143 | *dest = NULL; | |
9ecdf48f | 144 | return 0; /* source (old) is empty */ |
8b95253f | 145 | } |
9ecdf48f | 146 | |
8b95253f KZ |
147 | sz = strlen(src) + 1; |
148 | x = realloc(*dest, sz); | |
149 | if (!x) | |
56be757f | 150 | return -ENOMEM; |
8b95253f KZ |
151 | *dest = x; |
152 | memcpy(*dest, src, sz); | |
9ecdf48f KZ |
153 | return 0; |
154 | } | |
155 | ||
8b95253f KZ |
156 | static inline int cpy_str_at_offset(void *new, const void *old, size_t offset) |
157 | { | |
fef00631 BE |
158 | char **o = (char **) ((char *) old + offset); |
159 | char **n = (char **) ((char *) new + offset); | |
8b95253f | 160 | |
309139c7 | 161 | if (*n) |
d58b3157 | 162 | return 0; /* already set, don't overwrite */ |
309139c7 KZ |
163 | |
164 | return update_str(n, *o); | |
8b95253f KZ |
165 | } |
166 | ||
9ecdf48f KZ |
167 | /** |
168 | * mnt_copy_fs: | |
309139c7 KZ |
169 | * @dest: destination FS |
170 | * @src: source FS | |
171 | * | |
172 | * If @dest is NULL, then a new FS is allocated, if any @dest field is already | |
d58b3157 | 173 | * set, then the field is NOT overwritten. |
9ecdf48f KZ |
174 | * |
175 | * This function does not copy userdata (se mnt_fs_set_userdata()). A new copy is | |
176 | * not linked with any existing mnt_tab. | |
177 | * | |
309139c7 | 178 | * Returns: @dest or NULL in case of error |
9ecdf48f | 179 | */ |
309139c7 KZ |
180 | struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest, |
181 | const struct libmnt_fs *src) | |
9ecdf48f | 182 | { |
309139c7 | 183 | const struct libmnt_fs *org = dest; |
9ecdf48f | 184 | |
52a285bf KZ |
185 | if (!src) |
186 | return NULL; | |
309139c7 KZ |
187 | if (!dest) { |
188 | dest = mnt_new_fs(); | |
189 | if (!dest) | |
190 | return NULL; | |
042057d8 KH |
191 | |
192 | dest->tab = NULL; | |
309139c7 | 193 | } |
9ecdf48f | 194 | |
309139c7 KZ |
195 | dest->id = src->id; |
196 | dest->parent = src->parent; | |
197 | dest->devno = src->devno; | |
f7f29b56 | 198 | dest->tid = src->tid; |
309139c7 KZ |
199 | |
200 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, source))) | |
9ecdf48f | 201 | goto err; |
309139c7 | 202 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, tagname))) |
9ecdf48f | 203 | goto err; |
309139c7 | 204 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, tagval))) |
9ecdf48f | 205 | goto err; |
309139c7 | 206 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, root))) |
9ecdf48f | 207 | goto err; |
ce4dd666 KZ |
208 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, swaptype))) |
209 | goto err; | |
309139c7 | 210 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, target))) |
9ecdf48f | 211 | goto err; |
309139c7 | 212 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, fstype))) |
9ecdf48f | 213 | goto err; |
f2b3a3a3 KZ |
214 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, optstr))) |
215 | goto err; | |
309139c7 | 216 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, vfs_optstr))) |
9ecdf48f | 217 | goto err; |
309139c7 | 218 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, fs_optstr))) |
9ecdf48f | 219 | goto err; |
309139c7 | 220 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, user_optstr))) |
76a06ca4 | 221 | goto err; |
309139c7 | 222 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, attrs))) |
76a06ca4 | 223 | goto err; |
c4c66355 KZ |
224 | if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, bindsrc))) |
225 | goto err; | |
76a06ca4 | 226 | |
309139c7 KZ |
227 | dest->freq = src->freq; |
228 | dest->passno = src->passno; | |
229 | dest->flags = src->flags; | |
ce4dd666 KZ |
230 | dest->size = src->size; |
231 | dest->usedsize = src->usedsize; | |
232 | dest->priority = src->priority; | |
9ecdf48f | 233 | |
309139c7 | 234 | return dest; |
9ecdf48f | 235 | err: |
309139c7 KZ |
236 | if (!org) |
237 | mnt_free_fs(dest); | |
9ecdf48f KZ |
238 | return NULL; |
239 | } | |
240 | ||
0f32f1e2 | 241 | /* |
f84fa6f7 KZ |
242 | * This function copies all @fs description except information that does not |
243 | * belong to /etc/mtab (e.g. VFS and userspace mount options with MNT_NOMTAB | |
244 | * mask). | |
245 | * | |
246 | * Returns: copy of @fs. | |
247 | */ | |
68164f6c | 248 | struct libmnt_fs *mnt_copy_mtab_fs(const struct libmnt_fs *fs) |
f84fa6f7 | 249 | { |
68164f6c | 250 | struct libmnt_fs *n = mnt_new_fs(); |
f84fa6f7 | 251 | |
4569bbea | 252 | assert(fs); |
f84fa6f7 KZ |
253 | if (!n) |
254 | return NULL; | |
255 | ||
68164f6c | 256 | if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, source))) |
f84fa6f7 | 257 | goto err; |
68164f6c | 258 | if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, target))) |
f84fa6f7 | 259 | goto err; |
68164f6c | 260 | if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, fstype))) |
f84fa6f7 KZ |
261 | goto err; |
262 | ||
263 | if (fs->vfs_optstr) { | |
264 | char *p = NULL; | |
265 | mnt_optstr_get_options(fs->vfs_optstr, &p, | |
266 | mnt_get_builtin_optmap(MNT_LINUX_MAP), | |
267 | MNT_NOMTAB); | |
268 | n->vfs_optstr = p; | |
269 | } | |
270 | ||
271 | if (fs->user_optstr) { | |
272 | char *p = NULL; | |
273 | mnt_optstr_get_options(fs->user_optstr, &p, | |
274 | mnt_get_builtin_optmap(MNT_USERSPACE_MAP), | |
275 | MNT_NOMTAB); | |
276 | n->user_optstr = p; | |
277 | } | |
278 | ||
68164f6c | 279 | if (cpy_str_at_offset(n, fs, offsetof(struct libmnt_fs, fs_optstr))) |
f84fa6f7 KZ |
280 | goto err; |
281 | ||
f2b3a3a3 KZ |
282 | /* we cannot copy original optstr, the new optstr has to be without |
283 | * non-mtab options -- so, let's generate a new string */ | |
284 | n->optstr = mnt_fs_strdup_options(n); | |
285 | ||
f84fa6f7 KZ |
286 | n->freq = fs->freq; |
287 | n->passno = fs->passno; | |
288 | n->flags = fs->flags; | |
289 | ||
290 | return n; | |
291 | err: | |
292 | mnt_free_fs(n); | |
293 | return NULL; | |
294 | ||
295 | } | |
296 | ||
26b4f9e4 KZ |
297 | /** |
298 | * mnt_fs_get_userdata: | |
68164f6c | 299 | * @fs: struct libmnt_file instance |
26b4f9e4 | 300 | * |
192c6aad | 301 | * Returns: private data set by mnt_fs_set_userdata() or NULL. |
26b4f9e4 | 302 | */ |
68164f6c | 303 | void *mnt_fs_get_userdata(struct libmnt_fs *fs) |
26b4f9e4 | 304 | { |
14104e93 KZ |
305 | if (!fs) |
306 | return NULL; | |
14104e93 | 307 | return fs->userdata; |
26b4f9e4 KZ |
308 | } |
309 | ||
310 | /** | |
311 | * mnt_fs_set_userdata: | |
68164f6c | 312 | * @fs: struct libmnt_file instance |
0f32f1e2 | 313 | * @data: user data |
26b4f9e4 KZ |
314 | * |
315 | * The "userdata" are library independent data. | |
316 | * | |
56be757f | 317 | * Returns: 0 or negative number in case of error (if @fs is NULL). |
26b4f9e4 | 318 | */ |
68164f6c | 319 | int mnt_fs_set_userdata(struct libmnt_fs *fs, void *data) |
26b4f9e4 KZ |
320 | { |
321 | if (!fs) | |
56be757f | 322 | return -EINVAL; |
26b4f9e4 KZ |
323 | fs->userdata = data; |
324 | return 0; | |
325 | } | |
326 | ||
d115ee9b KZ |
327 | /** |
328 | * mnt_fs_get_srcpath: | |
68164f6c | 329 | * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs |
d115ee9b KZ |
330 | * |
331 | * The mount "source path" is: | |
192c6aad KZ |
332 | * - a directory for 'bind' mounts (in fstab or mtab only) |
333 | * - a device name for standard mounts | |
d115ee9b KZ |
334 | * |
335 | * See also mnt_fs_get_tag() and mnt_fs_get_source(). | |
336 | * | |
192c6aad | 337 | * Returns: mount source path or NULL in case of error or when the path |
d115ee9b | 338 | * is not defined. |
d115ee9b | 339 | */ |
68164f6c | 340 | const char *mnt_fs_get_srcpath(struct libmnt_fs *fs) |
d115ee9b | 341 | { |
d115ee9b KZ |
342 | if (!fs) |
343 | return NULL; | |
344 | ||
345 | /* fstab-like fs */ | |
346 | if (fs->tagname) | |
347 | return NULL; /* the source contains a "NAME=value" */ | |
348 | return fs->source; | |
349 | } | |
350 | ||
351 | /** | |
3d735589 | 352 | * mnt_fs_get_source: |
68164f6c | 353 | * @fs: struct libmnt_file (fstab/mtab/mountinfo) fs |
d115ee9b | 354 | * |
192c6aad | 355 | * Returns: mount source. Note that the source could be unparsed TAG |
d115ee9b KZ |
356 | * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag(). |
357 | */ | |
68164f6c | 358 | const char *mnt_fs_get_source(struct libmnt_fs *fs) |
d115ee9b KZ |
359 | { |
360 | return fs ? fs->source : NULL; | |
361 | } | |
362 | ||
5af0769d | 363 | /* |
d58b3157 | 364 | * Used by the parser ONLY (@source has to be freed on error) |
5af0769d | 365 | */ |
68164f6c | 366 | int __mnt_fs_set_source_ptr(struct libmnt_fs *fs, char *source) |
d115ee9b | 367 | { |
b2d0b74d KZ |
368 | char *t = NULL, *v = NULL; |
369 | ||
d115ee9b KZ |
370 | assert(fs); |
371 | ||
2c6b25f0 KZ |
372 | if (source && blkid_parse_tag_string(source, &t, &v) == 0 && |
373 | !mnt_valid_tagname(t)) { | |
374 | /* parsable but unknown tag -- ignore */ | |
375 | free(t); | |
376 | free(v); | |
377 | t = v = NULL; | |
d115ee9b KZ |
378 | } |
379 | ||
b2d0b74d KZ |
380 | if (fs->source != source) |
381 | free(fs->source); | |
382 | ||
383 | free(fs->tagname); | |
384 | free(fs->tagval); | |
385 | ||
d115ee9b | 386 | fs->source = source; |
b2d0b74d KZ |
387 | fs->tagname = t; |
388 | fs->tagval = v; | |
d115ee9b KZ |
389 | return 0; |
390 | } | |
391 | ||
392 | /** | |
393 | * mnt_fs_set_source: | |
394 | * @fs: fstab/mtab/mountinfo entry | |
395 | * @source: new source | |
396 | * | |
192c6aad KZ |
397 | * This function creates a private copy (strdup()) of @source. |
398 | * | |
56be757f | 399 | * Returns: 0 on success or negative number in case of error. |
d115ee9b | 400 | */ |
68164f6c | 401 | int mnt_fs_set_source(struct libmnt_fs *fs, const char *source) |
d115ee9b | 402 | { |
f5017242 | 403 | char *p = NULL; |
b2d0b74d | 404 | int rc; |
d115ee9b | 405 | |
f5017242 | 406 | if (!fs) |
56be757f | 407 | return -EINVAL; |
d0ce7c07 | 408 | |
f5017242 KZ |
409 | if (source) { |
410 | p = strdup(source); | |
411 | if (!p) | |
412 | return -ENOMEM; | |
413 | } | |
d115ee9b | 414 | |
b2d0b74d KZ |
415 | rc = __mnt_fs_set_source_ptr(fs, p); |
416 | if (rc) | |
417 | free(p); | |
418 | return rc; | |
d115ee9b KZ |
419 | } |
420 | ||
6699e742 KZ |
421 | /** |
422 | * mnt_fs_streq_srcpath: | |
423 | * @fs: fs | |
424 | * @path: source path | |
425 | * | |
73afd3f8 RM |
426 | * Compares @fs source path with @path. The redundant slashes are ignored. |
427 | * This function compares strings and does not canonicalize the paths. | |
d4e89dea | 428 | * See also more heavy and generic mnt_fs_match_source(). |
6699e742 KZ |
429 | * |
430 | * Returns: 1 if @fs source path equal to @path, otherwise 0. | |
431 | */ | |
ab8c6e05 KZ |
432 | int mnt_fs_streq_srcpath(struct libmnt_fs *fs, const char *path) |
433 | { | |
6699e742 | 434 | const char *p; |
ab8c6e05 | 435 | |
6699e742 | 436 | if (!fs) |
ab8c6e05 KZ |
437 | return 0; |
438 | ||
6699e742 | 439 | p = mnt_fs_get_srcpath(fs); |
ab8c6e05 | 440 | |
6699e742 | 441 | if (!mnt_fs_is_pseudofs(fs)) |
d4e89dea | 442 | return streq_paths(p, path); |
6699e742 KZ |
443 | |
444 | if (!p && !path) | |
445 | return 1; | |
446 | ||
447 | return p && path && strcmp(p, path) == 0; | |
ab8c6e05 KZ |
448 | } |
449 | ||
9d5eb4c4 TH |
450 | /** |
451 | * mnt_fs_get_table: | |
452 | * @fs: table entry | |
453 | * @tb: table that contains @fs | |
454 | * | |
455 | * Returns: 0 or negative number on error (if @fs or @tb is NULL). | |
2089538a KZ |
456 | * |
457 | * Since: 2.34 | |
9d5eb4c4 TH |
458 | */ |
459 | int mnt_fs_get_table(struct libmnt_fs *fs, struct libmnt_table **tb) | |
460 | { | |
461 | if (!fs || !tb) | |
462 | return -EINVAL; | |
463 | ||
464 | *tb = fs->tab; | |
465 | return 0; | |
466 | } | |
467 | ||
6699e742 KZ |
468 | /** |
469 | * mnt_fs_streq_target: | |
470 | * @fs: fs | |
471 | * @path: mount point | |
472 | * | |
73afd3f8 RM |
473 | * Compares @fs target path with @path. The redundant slashes are ignored. |
474 | * This function compares strings and does not canonicalize the paths. | |
d4e89dea | 475 | * See also more generic mnt_fs_match_target(). |
6699e742 KZ |
476 | * |
477 | * Returns: 1 if @fs target path equal to @path, otherwise 0. | |
478 | */ | |
479 | int mnt_fs_streq_target(struct libmnt_fs *fs, const char *path) | |
480 | { | |
d4e89dea | 481 | return fs && streq_paths(mnt_fs_get_target(fs), path); |
6699e742 | 482 | } |
ab8c6e05 | 483 | |
d115ee9b KZ |
484 | /** |
485 | * mnt_fs_get_tag: | |
486 | * @fs: fs | |
487 | * @name: returns pointer to NAME string | |
488 | * @value: returns pointer to VALUE string | |
489 | * | |
490 | * "TAG" is NAME=VALUE (e.g. LABEL=foo) | |
491 | * | |
d58b3157 OO |
492 | * The TAG is the first column in the fstab file. The TAG or "srcpath" always has |
493 | * to be set for all entries. | |
d115ee9b KZ |
494 | * |
495 | * See also mnt_fs_get_source(). | |
496 | * | |
192c6aad KZ |
497 | * <informalexample> |
498 | * <programlisting> | |
d115ee9b | 499 | * char *src; |
68164f6c | 500 | * struct libmnt_fs *fs = mnt_table_find_target(tb, "/home", MNT_ITER_FORWARD); |
d115ee9b KZ |
501 | * |
502 | * if (!fs) | |
503 | * goto err; | |
504 | * | |
505 | * src = mnt_fs_get_srcpath(fs); | |
506 | * if (!src) { | |
507 | * char *tag, *val; | |
508 | * if (mnt_fs_get_tag(fs, &tag, &val) == 0) | |
509 | * printf("%s: %s\n", tag, val); // LABEL or UUID | |
510 | * } else | |
511 | * printf("device: %s\n", src); // device or bind path | |
192c6aad KZ |
512 | * </programlisting> |
513 | * </informalexample> | |
d115ee9b | 514 | * |
d58b3157 | 515 | * Returns: 0 on success or negative number in case a TAG is not defined. |
d115ee9b | 516 | */ |
68164f6c | 517 | int mnt_fs_get_tag(struct libmnt_fs *fs, const char **name, const char **value) |
d115ee9b KZ |
518 | { |
519 | if (fs == NULL || !fs->tagname) | |
56be757f | 520 | return -EINVAL; |
d115ee9b KZ |
521 | if (name) |
522 | *name = fs->tagname; | |
523 | if (value) | |
524 | *value = fs->tagval; | |
525 | return 0; | |
526 | } | |
527 | ||
528 | /** | |
529 | * mnt_fs_get_target: | |
530 | * @fs: fstab/mtab/mountinfo entry pointer | |
531 | * | |
192c6aad | 532 | * Returns: pointer to mountpoint path or NULL |
d115ee9b | 533 | */ |
68164f6c | 534 | const char *mnt_fs_get_target(struct libmnt_fs *fs) |
d115ee9b | 535 | { |
d115ee9b KZ |
536 | return fs ? fs->target : NULL; |
537 | } | |
538 | ||
539 | /** | |
540 | * mnt_fs_set_target: | |
541 | * @fs: fstab/mtab/mountinfo entry | |
deb1c903 | 542 | * @tgt: mountpoint |
d115ee9b | 543 | * |
deb1c903 | 544 | * This function creates a private copy (strdup()) of @tgt. |
192c6aad | 545 | * |
56be757f | 546 | * Returns: 0 on success or negative number in case of error. |
d115ee9b | 547 | */ |
deb1c903 | 548 | int mnt_fs_set_target(struct libmnt_fs *fs, const char *tgt) |
d115ee9b | 549 | { |
deb1c903 | 550 | return strdup_to_struct_member(fs, target, tgt); |
d115ee9b KZ |
551 | } |
552 | ||
c70d9d76 | 553 | static int mnt_fs_get_flags(struct libmnt_fs *fs) |
309139c7 KZ |
554 | { |
555 | return fs ? fs->flags : 0; | |
556 | } | |
557 | ||
4b9d67a2 KZ |
558 | /** |
559 | * mnt_fs_get_propagation: | |
560 | * @fs: mountinfo entry | |
d58b3157 | 561 | * @flags: returns propagation MS_* flags as present in the mountinfo file |
4b9d67a2 | 562 | * |
d58b3157 OO |
563 | * Note that this function sets @flags to zero if no propagation flags are found |
564 | * in the mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored | |
4b9d67a2 KZ |
565 | * in the mountinfo file. |
566 | * | |
567 | * Returns: 0 on success or negative number in case of error. | |
568 | */ | |
569 | int mnt_fs_get_propagation(struct libmnt_fs *fs, unsigned long *flags) | |
570 | { | |
571 | if (!fs || !flags) | |
572 | return -EINVAL; | |
573 | ||
574 | *flags = 0; | |
575 | ||
576 | if (!fs->opt_fields) | |
577 | return 0; | |
578 | ||
579 | /* | |
580 | * The optional fields format is incompatible with mount options | |
581 | * ... we have to parse the field here. | |
582 | */ | |
583 | *flags |= strstr(fs->opt_fields, "shared:") ? MS_SHARED : MS_PRIVATE; | |
584 | ||
585 | if (strstr(fs->opt_fields, "master:")) | |
586 | *flags |= MS_SLAVE; | |
587 | if (strstr(fs->opt_fields, "unbindable")) | |
588 | *flags |= MS_UNBINDABLE; | |
589 | ||
590 | return 0; | |
591 | } | |
592 | ||
309139c7 KZ |
593 | /** |
594 | * mnt_fs_is_kernel: | |
595 | * @fs: filesystem | |
596 | * | |
597 | * Returns: 1 if the filesystem description is read from kernel e.g. /proc/mounts. | |
598 | */ | |
599 | int mnt_fs_is_kernel(struct libmnt_fs *fs) | |
600 | { | |
c70d9d76 KZ |
601 | return mnt_fs_get_flags(fs) & MNT_FS_KERNEL; |
602 | } | |
603 | ||
604 | /** | |
605 | * mnt_fs_is_swaparea: | |
606 | * @fs: filesystem | |
607 | * | |
608 | * Returns: 1 if the filesystem uses "swap" as a type | |
609 | */ | |
610 | int mnt_fs_is_swaparea(struct libmnt_fs *fs) | |
611 | { | |
612 | return mnt_fs_get_flags(fs) & MNT_FS_SWAP; | |
613 | } | |
614 | ||
615 | /** | |
616 | * mnt_fs_is_pseudofs: | |
617 | * @fs: filesystem | |
618 | * | |
619 | * Returns: 1 if the filesystem is a pseudo fs type (proc, cgroups) | |
620 | */ | |
b928ab01 | 621 | int mnt_fs_is_pseudofs(struct libmnt_fs *fs) |
c70d9d76 KZ |
622 | { |
623 | return mnt_fs_get_flags(fs) & MNT_FS_PSEUDO; | |
624 | } | |
625 | ||
626 | /** | |
627 | * mnt_fs_is_netfs: | |
628 | * @fs: filesystem | |
629 | * | |
630 | * Returns: 1 if the filesystem is a network filesystem | |
631 | */ | |
632 | int mnt_fs_is_netfs(struct libmnt_fs *fs) | |
633 | { | |
634 | return mnt_fs_get_flags(fs) & MNT_FS_NET; | |
309139c7 KZ |
635 | } |
636 | ||
d115ee9b KZ |
637 | /** |
638 | * mnt_fs_get_fstype: | |
639 | * @fs: fstab/mtab/mountinfo entry pointer | |
640 | * | |
192c6aad | 641 | * Returns: pointer to filesystem type. |
d115ee9b | 642 | */ |
68164f6c | 643 | const char *mnt_fs_get_fstype(struct libmnt_fs *fs) |
d115ee9b | 644 | { |
d115ee9b KZ |
645 | return fs ? fs->fstype : NULL; |
646 | } | |
647 | ||
d58b3157 | 648 | /* Used by the struct libmnt_file parser only */ |
68164f6c | 649 | int __mnt_fs_set_fstype_ptr(struct libmnt_fs *fs, char *fstype) |
d115ee9b KZ |
650 | { |
651 | assert(fs); | |
652 | ||
b2d0b74d KZ |
653 | if (fstype != fs->fstype) |
654 | free(fs->fstype); | |
655 | ||
d115ee9b KZ |
656 | fs->fstype = fstype; |
657 | fs->flags &= ~MNT_FS_PSEUDO; | |
658 | fs->flags &= ~MNT_FS_NET; | |
5dfc9843 | 659 | fs->flags &= ~MNT_FS_SWAP; |
d115ee9b KZ |
660 | |
661 | /* save info about pseudo filesystems */ | |
8485e709 KZ |
662 | if (fs->fstype) { |
663 | if (mnt_fstype_is_pseudofs(fs->fstype)) | |
664 | fs->flags |= MNT_FS_PSEUDO; | |
665 | else if (mnt_fstype_is_netfs(fs->fstype)) | |
666 | fs->flags |= MNT_FS_NET; | |
667 | else if (!strcmp(fs->fstype, "swap")) | |
668 | fs->flags |= MNT_FS_SWAP; | |
669 | } | |
d115ee9b KZ |
670 | return 0; |
671 | } | |
672 | ||
673 | /** | |
674 | * mnt_fs_set_fstype: | |
675 | * @fs: fstab/mtab/mountinfo entry | |
676 | * @fstype: filesystem type | |
677 | * | |
192c6aad KZ |
678 | * This function creates a private copy (strdup()) of @fstype. |
679 | * | |
56be757f | 680 | * Returns: 0 on success or negative number in case of error. |
d115ee9b | 681 | */ |
68164f6c | 682 | int mnt_fs_set_fstype(struct libmnt_fs *fs, const char *fstype) |
d115ee9b | 683 | { |
8485e709 | 684 | char *p = NULL; |
d115ee9b | 685 | |
8485e709 | 686 | if (!fs) |
56be757f | 687 | return -EINVAL; |
8485e709 KZ |
688 | if (fstype) { |
689 | p = strdup(fstype); | |
690 | if (!p) | |
691 | return -ENOMEM; | |
692 | } | |
f5017242 | 693 | return __mnt_fs_set_fstype_ptr(fs, p); |
d115ee9b KZ |
694 | } |
695 | ||
76a06ca4 KZ |
696 | /* |
697 | * Merges @vfs and @fs options strings into a new string. | |
698 | * This function cares about 'ro/rw' options. The 'ro' is | |
699 | * always used if @vfs or @fs is read-only. | |
700 | * For example: | |
701 | * | |
702 | * mnt_merge_optstr("rw,noexec", "ro,journal=update") | |
703 | * | |
704 | * returns: "ro,noexec,journal=update" | |
705 | * | |
706 | * mnt_merge_optstr("rw,noexec", "rw,journal=update") | |
707 | * | |
708 | * returns: "rw,noexec,journal=update" | |
709 | */ | |
710 | static char *merge_optstr(const char *vfs, const char *fs) | |
711 | { | |
712 | char *res, *p; | |
713 | size_t sz; | |
714 | int ro = 0, rw = 0; | |
715 | ||
716 | if (!vfs && !fs) | |
717 | return NULL; | |
718 | if (!vfs || !fs) | |
719 | return strdup(fs ? fs : vfs); | |
720 | if (!strcmp(vfs, fs)) | |
721 | return strdup(vfs); /* e.g. "aaa" and "aaa" */ | |
722 | ||
d58b3157 | 723 | /* leave space for the leading "r[ow],", "," and the trailing zero */ |
76a06ca4 KZ |
724 | sz = strlen(vfs) + strlen(fs) + 5; |
725 | res = malloc(sz); | |
726 | if (!res) | |
727 | return NULL; | |
728 | p = res + 3; /* make a room for rw/ro flag */ | |
729 | ||
730 | snprintf(p, sz - 3, "%s,%s", vfs, fs); | |
731 | ||
732 | /* remove 'rw' flags */ | |
733 | rw += !mnt_optstr_remove_option(&p, "rw"); /* from vfs */ | |
734 | rw += !mnt_optstr_remove_option(&p, "rw"); /* from fs */ | |
735 | ||
736 | /* remove 'ro' flags if necessary */ | |
737 | if (rw != 2) { | |
738 | ro += !mnt_optstr_remove_option(&p, "ro"); | |
739 | if (ro + rw < 2) | |
740 | ro += !mnt_optstr_remove_option(&p, "ro"); | |
741 | } | |
742 | ||
743 | if (!strlen(p)) | |
744 | memcpy(res, ro ? "ro" : "rw", 3); | |
745 | else | |
746 | memcpy(res, ro ? "ro," : "rw,", 3); | |
747 | return res; | |
748 | } | |
749 | ||
d115ee9b | 750 | /** |
76a06ca4 | 751 | * mnt_fs_strdup_options: |
d115ee9b KZ |
752 | * @fs: fstab/mtab/mountinfo entry pointer |
753 | * | |
d58b3157 | 754 | * Merges all mount options (VFS, FS and userspace) to one options string |
9e930041 | 755 | * and returns the result. This function does not modify @fs. |
76a06ca4 KZ |
756 | * |
757 | * Returns: pointer to string (can be freed by free(3)) or NULL in case of error. | |
d115ee9b | 758 | */ |
68164f6c | 759 | char *mnt_fs_strdup_options(struct libmnt_fs *fs) |
d115ee9b | 760 | { |
76a06ca4 KZ |
761 | char *res; |
762 | ||
37290a53 KZ |
763 | if (!fs) |
764 | return NULL; | |
765 | ||
76a06ca4 | 766 | errno = 0; |
f2b3a3a3 KZ |
767 | if (fs->optstr) |
768 | return strdup(fs->optstr); | |
769 | ||
76a06ca4 | 770 | res = merge_optstr(fs->vfs_optstr, fs->fs_optstr); |
87a07a4c | 771 | if (!res && errno) |
76a06ca4 | 772 | return NULL; |
74ce680a SK |
773 | if (fs->user_optstr && |
774 | mnt_optstr_append_option(&res, fs->user_optstr, NULL)) { | |
775 | free(res); | |
776 | res = NULL; | |
76a06ca4 KZ |
777 | } |
778 | return res; | |
d115ee9b KZ |
779 | } |
780 | ||
f2b3a3a3 KZ |
781 | /** |
782 | * mnt_fs_get_options: | |
783 | * @fs: fstab/mtab/mountinfo entry pointer | |
784 | * | |
785 | * Returns: pointer to string or NULL in case of error. | |
786 | */ | |
787 | const char *mnt_fs_get_options(struct libmnt_fs *fs) | |
788 | { | |
f2b3a3a3 KZ |
789 | return fs ? fs->optstr : NULL; |
790 | } | |
791 | ||
e47a1931 OO |
792 | /** |
793 | * mnt_fs_get_optional_fields | |
794 | * @fs: mountinfo entry pointer | |
795 | * | |
796 | * Returns: pointer to string with mountinfo optional fields | |
797 | * or NULL in case of error. | |
798 | */ | |
799 | const char *mnt_fs_get_optional_fields(struct libmnt_fs *fs) | |
800 | { | |
e47a1931 OO |
801 | return fs ? fs->opt_fields : NULL; |
802 | } | |
f2b3a3a3 | 803 | |
76a06ca4 KZ |
804 | /** |
805 | * mnt_fs_set_options: | |
806 | * @fs: fstab/mtab/mountinfo entry pointer | |
0f32f1e2 | 807 | * @optstr: options string |
76a06ca4 | 808 | * |
d58b3157 | 809 | * Splits @optstr to VFS, FS and userspace mount options and updates relevant |
76a06ca4 KZ |
810 | * parts of @fs. |
811 | * | |
d58b3157 | 812 | * Returns: 0 on success, or negative number in case of error. |
76a06ca4 | 813 | */ |
68164f6c | 814 | int mnt_fs_set_options(struct libmnt_fs *fs, const char *optstr) |
d115ee9b | 815 | { |
f2b3a3a3 | 816 | char *v = NULL, *f = NULL, *u = NULL, *n = NULL; |
192c6aad | 817 | |
be1a5180 | 818 | if (!fs) |
56be757f | 819 | return -EINVAL; |
76a06ca4 KZ |
820 | if (optstr) { |
821 | int rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0); | |
56be757f KZ |
822 | if (rc) |
823 | return rc; | |
f2b3a3a3 | 824 | n = strdup(optstr); |
c470cbfc NK |
825 | if (!n) { |
826 | free(u); | |
827 | free(v); | |
828 | free(f); | |
f2b3a3a3 | 829 | return -ENOMEM; |
c470cbfc | 830 | } |
3661b841 | 831 | } |
192c6aad | 832 | |
d115ee9b KZ |
833 | free(fs->fs_optstr); |
834 | free(fs->vfs_optstr); | |
76a06ca4 | 835 | free(fs->user_optstr); |
f2b3a3a3 | 836 | free(fs->optstr); |
d6fead1e | 837 | |
3661b841 KZ |
838 | fs->fs_optstr = f; |
839 | fs->vfs_optstr = v; | |
76a06ca4 | 840 | fs->user_optstr = u; |
f2b3a3a3 KZ |
841 | fs->optstr = n; |
842 | ||
192c6aad | 843 | return 0; |
d115ee9b KZ |
844 | } |
845 | ||
76a06ca4 KZ |
846 | /** |
847 | * mnt_fs_append_options: | |
848 | * @fs: fstab/mtab/mountinfo entry | |
849 | * @optstr: mount options | |
850 | * | |
851 | * Parses (splits) @optstr and appends results to VFS, FS and userspace lists | |
852 | * of options. | |
853 | * | |
d58b3157 | 854 | * If @optstr is NULL, then @fs is not modified and 0 is returned. |
76a06ca4 KZ |
855 | * |
856 | * Returns: 0 on success or negative number in case of error. | |
857 | */ | |
68164f6c | 858 | int mnt_fs_append_options(struct libmnt_fs *fs, const char *optstr) |
b2d0b74d | 859 | { |
76a06ca4 | 860 | char *v = NULL, *f = NULL, *u = NULL; |
b2d0b74d KZ |
861 | int rc; |
862 | ||
76a06ca4 KZ |
863 | if (!fs) |
864 | return -EINVAL; | |
865 | if (!optstr) | |
866 | return 0; | |
867 | ||
b00dd55a | 868 | rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0); |
1e670193 KZ |
869 | if (rc) |
870 | return rc; | |
871 | ||
76a06ca4 KZ |
872 | if (!rc && v) |
873 | rc = mnt_optstr_append_option(&fs->vfs_optstr, v, NULL); | |
874 | if (!rc && f) | |
f2b3a3a3 | 875 | rc = mnt_optstr_append_option(&fs->fs_optstr, f, NULL); |
76a06ca4 | 876 | if (!rc && u) |
f2b3a3a3 KZ |
877 | rc = mnt_optstr_append_option(&fs->user_optstr, u, NULL); |
878 | if (!rc) | |
879 | rc = mnt_optstr_append_option(&fs->optstr, optstr, NULL); | |
880 | ||
881 | free(v); | |
882 | free(f); | |
883 | free(u); | |
76a06ca4 | 884 | |
b2d0b74d KZ |
885 | return rc; |
886 | } | |
887 | ||
3661b841 | 888 | /** |
76a06ca4 KZ |
889 | * mnt_fs_prepend_options: |
890 | * @fs: fstab/mtab/mountinfo entry | |
891 | * @optstr: mount options | |
892 | * | |
d58b3157 | 893 | * Parses (splits) @optstr and prepends the results to VFS, FS and userspace lists |
76a06ca4 KZ |
894 | * of options. |
895 | * | |
d58b3157 | 896 | * If @optstr is NULL, then @fs is not modified and 0 is returned. |
76a06ca4 KZ |
897 | * |
898 | * Returns: 0 on success or negative number in case of error. | |
899 | */ | |
68164f6c | 900 | int mnt_fs_prepend_options(struct libmnt_fs *fs, const char *optstr) |
76a06ca4 KZ |
901 | { |
902 | char *v = NULL, *f = NULL, *u = NULL; | |
903 | int rc; | |
904 | ||
76a06ca4 KZ |
905 | if (!fs) |
906 | return -EINVAL; | |
907 | if (!optstr) | |
908 | return 0; | |
909 | ||
b00dd55a | 910 | rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0); |
1e670193 KZ |
911 | if (rc) |
912 | return rc; | |
913 | ||
76a06ca4 KZ |
914 | if (!rc && v) |
915 | rc = mnt_optstr_prepend_option(&fs->vfs_optstr, v, NULL); | |
916 | if (!rc && f) | |
917 | rc = mnt_optstr_prepend_option(&fs->fs_optstr, f, NULL); | |
918 | if (!rc && u) | |
919 | rc = mnt_optstr_prepend_option(&fs->user_optstr, u, NULL); | |
f2b3a3a3 KZ |
920 | if (!rc) |
921 | rc = mnt_optstr_prepend_option(&fs->optstr, optstr, NULL); | |
922 | ||
923 | free(v); | |
924 | free(f); | |
925 | free(u); | |
76a06ca4 KZ |
926 | |
927 | return rc; | |
928 | } | |
929 | ||
930 | /* | |
931 | * mnt_fs_get_fs_options: | |
932 | * @fs: fstab/mtab/mountinfo entry pointer | |
933 | * | |
934 | * Returns: pointer to superblock (fs-depend) mount option string or NULL. | |
935 | */ | |
68164f6c | 936 | const char *mnt_fs_get_fs_options(struct libmnt_fs *fs) |
76a06ca4 | 937 | { |
76a06ca4 KZ |
938 | return fs ? fs->fs_optstr : NULL; |
939 | } | |
940 | ||
76a06ca4 KZ |
941 | /** |
942 | * mnt_fs_get_vfs_options: | |
943 | * @fs: fstab/mtab entry pointer | |
944 | * | |
945 | * Returns: pointer to fs-independent (VFS) mount option string or NULL. | |
946 | */ | |
68164f6c | 947 | const char *mnt_fs_get_vfs_options(struct libmnt_fs *fs) |
76a06ca4 | 948 | { |
76a06ca4 KZ |
949 | return fs ? fs->vfs_optstr : NULL; |
950 | } | |
951 | ||
76a06ca4 | 952 | /** |
68164f6c | 953 | * mnt_fs_get_user_options: |
76a06ca4 KZ |
954 | * @fs: fstab/mtab entry pointer |
955 | * | |
956 | * Returns: pointer to userspace mount option string or NULL. | |
957 | */ | |
68164f6c | 958 | const char *mnt_fs_get_user_options(struct libmnt_fs *fs) |
76a06ca4 | 959 | { |
76a06ca4 | 960 | return fs ? fs->user_optstr : NULL; |
569f95b7 KZ |
961 | } |
962 | ||
d115ee9b | 963 | /** |
76a06ca4 KZ |
964 | * mnt_fs_get_attributes: |
965 | * @fs: fstab/mtab entry pointer | |
d115ee9b | 966 | * |
76a06ca4 | 967 | * Returns: pointer to attributes string or NULL. |
d115ee9b | 968 | */ |
68164f6c | 969 | const char *mnt_fs_get_attributes(struct libmnt_fs *fs) |
d115ee9b | 970 | { |
76a06ca4 | 971 | return fs ? fs->attrs : NULL; |
d115ee9b KZ |
972 | } |
973 | ||
974 | /** | |
76a06ca4 KZ |
975 | * mnt_fs_set_attributes: |
976 | * @fs: fstab/mtab/mountinfo entry | |
977 | * @optstr: options string | |
d115ee9b | 978 | * |
76a06ca4 | 979 | * Sets mount attributes. The attributes are mount(2) and mount(8) independent |
d58b3157 | 980 | * options, these options are not sent to the kernel and are not interpreted by |
a362ae60 | 981 | * libmount. The attributes are stored in /run/mount/utab only. |
76a06ca4 | 982 | * |
d58b3157 | 983 | * The attributes are managed by libmount in userspace only. It's possible |
76a06ca4 | 984 | * that information stored in userspace will not be available for libmount |
7007991f | 985 | * after CLONE_FS unshare. Be careful, and don't use attributes if possible. |
76a06ca4 KZ |
986 | * |
987 | * Returns: 0 on success or negative number in case of error. | |
d115ee9b | 988 | */ |
68164f6c | 989 | int mnt_fs_set_attributes(struct libmnt_fs *fs, const char *optstr) |
d115ee9b | 990 | { |
deb1c903 | 991 | return strdup_to_struct_member(fs, attrs, optstr); |
76a06ca4 KZ |
992 | } |
993 | ||
994 | /** | |
995 | * mnt_fs_append_attributes | |
996 | * @fs: fstab/mtab/mountinfo entry | |
997 | * @optstr: options string | |
998 | * | |
999 | * Appends mount attributes. (See mnt_fs_set_attributes()). | |
1000 | * | |
1001 | * Returns: 0 on success or negative number in case of error. | |
1002 | */ | |
68164f6c | 1003 | int mnt_fs_append_attributes(struct libmnt_fs *fs, const char *optstr) |
76a06ca4 KZ |
1004 | { |
1005 | if (!fs) | |
1006 | return -EINVAL; | |
1007 | if (!optstr) | |
1008 | return 0; | |
1009 | return mnt_optstr_append_option(&fs->attrs, optstr, NULL); | |
1010 | } | |
1011 | ||
1012 | /** | |
1013 | * mnt_fs_prepend_attributes | |
1014 | * @fs: fstab/mtab/mountinfo entry | |
1015 | * @optstr: options string | |
1016 | * | |
1017 | * Prepends mount attributes. (See mnt_fs_set_attributes()). | |
1018 | * | |
1019 | * Returns: 0 on success or negative number in case of error. | |
1020 | */ | |
68164f6c | 1021 | int mnt_fs_prepend_attributes(struct libmnt_fs *fs, const char *optstr) |
76a06ca4 KZ |
1022 | { |
1023 | if (!fs) | |
1024 | return -EINVAL; | |
1025 | if (!optstr) | |
1026 | return 0; | |
1027 | return mnt_optstr_prepend_option(&fs->attrs, optstr, NULL); | |
d115ee9b KZ |
1028 | } |
1029 | ||
1030 | ||
1031 | /** | |
1032 | * mnt_fs_get_freq: | |
1033 | * @fs: fstab/mtab/mountinfo entry pointer | |
1034 | * | |
3d735589 | 1035 | * Returns: dump frequency in days. |
d115ee9b | 1036 | */ |
68164f6c | 1037 | int mnt_fs_get_freq(struct libmnt_fs *fs) |
d115ee9b | 1038 | { |
d115ee9b KZ |
1039 | return fs ? fs->freq : 0; |
1040 | } | |
1041 | ||
1042 | /** | |
1043 | * mnt_fs_set_freq: | |
efe73c3e | 1044 | * @fs: fstab/mtab entry pointer |
d115ee9b KZ |
1045 | * @freq: dump frequency in days |
1046 | * | |
56be757f | 1047 | * Returns: 0 on success or negative number in case of error. |
d115ee9b | 1048 | */ |
68164f6c | 1049 | int mnt_fs_set_freq(struct libmnt_fs *fs, int freq) |
d115ee9b | 1050 | { |
d115ee9b | 1051 | if (!fs) |
56be757f | 1052 | return -EINVAL; |
d115ee9b KZ |
1053 | fs->freq = freq; |
1054 | return 0; | |
1055 | } | |
1056 | ||
1057 | /** | |
1058 | * mnt_fs_get_passno: | |
efe73c3e | 1059 | * @fs: fstab/mtab entry pointer |
d115ee9b | 1060 | * |
192c6aad | 1061 | * Returns: "pass number on parallel fsck". |
d115ee9b | 1062 | */ |
68164f6c | 1063 | int mnt_fs_get_passno(struct libmnt_fs *fs) |
d115ee9b | 1064 | { |
d115ee9b KZ |
1065 | return fs ? fs->passno: 0; |
1066 | } | |
1067 | ||
1068 | /** | |
1069 | * mnt_fs_set_passno: | |
efe73c3e | 1070 | * @fs: fstab/mtab entry pointer |
d115ee9b KZ |
1071 | * @passno: pass number |
1072 | * | |
56be757f | 1073 | * Returns: 0 on success or negative number in case of error. |
d115ee9b | 1074 | */ |
68164f6c | 1075 | int mnt_fs_set_passno(struct libmnt_fs *fs, int passno) |
d115ee9b | 1076 | { |
d115ee9b | 1077 | if (!fs) |
56be757f | 1078 | return -EINVAL; |
d115ee9b KZ |
1079 | fs->passno = passno; |
1080 | return 0; | |
1081 | } | |
1082 | ||
0b3953a3 KZ |
1083 | /** |
1084 | * mnt_fs_get_root: | |
1085 | * @fs: /proc/self/mountinfo entry | |
1086 | * | |
1087 | * Returns: root of the mount within the filesystem or NULL | |
1088 | */ | |
68164f6c | 1089 | const char *mnt_fs_get_root(struct libmnt_fs *fs) |
0b3953a3 | 1090 | { |
0b3953a3 KZ |
1091 | return fs ? fs->root : NULL; |
1092 | } | |
1093 | ||
9ecdf48f KZ |
1094 | /** |
1095 | * mnt_fs_set_root: | |
1096 | * @fs: mountinfo entry | |
deb1c903 | 1097 | * @path: root path |
9ecdf48f | 1098 | * |
56be757f | 1099 | * Returns: 0 on success or negative number in case of error. |
9ecdf48f | 1100 | */ |
deb1c903 | 1101 | int mnt_fs_set_root(struct libmnt_fs *fs, const char *path) |
9ecdf48f | 1102 | { |
deb1c903 | 1103 | return strdup_to_struct_member(fs, root, path); |
9ecdf48f KZ |
1104 | } |
1105 | ||
ce4dd666 KZ |
1106 | /** |
1107 | * mnt_fs_get_swaptype: | |
1108 | * @fs: /proc/swaps entry | |
1109 | * | |
1110 | * Returns: swap type or NULL | |
1111 | */ | |
1112 | const char *mnt_fs_get_swaptype(struct libmnt_fs *fs) | |
1113 | { | |
ce4dd666 KZ |
1114 | return fs ? fs->swaptype : NULL; |
1115 | } | |
1116 | ||
1117 | /** | |
1118 | * mnt_fs_get_size: | |
1119 | * @fs: /proc/swaps entry | |
1120 | * | |
1121 | * Returns: size | |
1122 | */ | |
1123 | off_t mnt_fs_get_size(struct libmnt_fs *fs) | |
1124 | { | |
ce4dd666 KZ |
1125 | return fs ? fs->size : 0; |
1126 | } | |
1127 | ||
1128 | /** | |
1129 | * mnt_fs_get_usedsize: | |
1130 | * @fs: /proc/swaps entry | |
1131 | * | |
1132 | * Returns: used size | |
1133 | */ | |
1134 | off_t mnt_fs_get_usedsize(struct libmnt_fs *fs) | |
1135 | { | |
ce4dd666 KZ |
1136 | return fs ? fs->usedsize : 0; |
1137 | } | |
1138 | ||
1139 | /** | |
1140 | * mnt_fs_get_priority: | |
1141 | * @fs: /proc/swaps entry | |
1142 | * | |
1143 | * Returns: priority | |
1144 | */ | |
1145 | int mnt_fs_get_priority(struct libmnt_fs *fs) | |
1146 | { | |
ce4dd666 KZ |
1147 | return fs ? fs->priority : 0; |
1148 | } | |
1149 | ||
1150 | /** | |
1151 | * mnt_fs_set_priority: | |
1152 | * @fs: /proc/swaps entry | |
81b176c4 | 1153 | * @prio: priority |
ce4dd666 | 1154 | * |
a81b1946 KZ |
1155 | * Since: 2.28 |
1156 | * | |
ce4dd666 KZ |
1157 | * Returns: 0 or -1 in case of error |
1158 | */ | |
1159 | int mnt_fs_set_priority(struct libmnt_fs *fs, int prio) | |
1160 | { | |
ce4dd666 KZ |
1161 | if (!fs) |
1162 | return -EINVAL; | |
1163 | fs->priority = prio; | |
1164 | return 0; | |
1165 | } | |
1166 | ||
dd369652 KZ |
1167 | /** |
1168 | * mnt_fs_get_bindsrc: | |
a362ae60 | 1169 | * @fs: /run/mount/utab entry |
dd369652 KZ |
1170 | * |
1171 | * Returns: full path that was used for mount(2) on MS_BIND | |
1172 | */ | |
68164f6c | 1173 | const char *mnt_fs_get_bindsrc(struct libmnt_fs *fs) |
dd369652 | 1174 | { |
dd369652 KZ |
1175 | return fs ? fs->bindsrc : NULL; |
1176 | } | |
1177 | ||
1178 | /** | |
1179 | * mnt_fs_set_bindsrc: | |
1180 | * @fs: filesystem | |
1181 | * @src: path | |
1182 | * | |
1183 | * Returns: 0 on success or negative number in case of error. | |
1184 | */ | |
68164f6c | 1185 | int mnt_fs_set_bindsrc(struct libmnt_fs *fs, const char *src) |
dd369652 | 1186 | { |
deb1c903 | 1187 | return strdup_to_struct_member(fs, bindsrc, src); |
dd369652 KZ |
1188 | } |
1189 | ||
efe73c3e KZ |
1190 | /** |
1191 | * mnt_fs_get_id: | |
1192 | * @fs: /proc/self/mountinfo entry | |
1193 | * | |
56be757f | 1194 | * Returns: mount ID (unique identifier of the mount) or negative number in case of error. |
efe73c3e | 1195 | */ |
68164f6c | 1196 | int mnt_fs_get_id(struct libmnt_fs *fs) |
efe73c3e | 1197 | { |
56be757f | 1198 | return fs ? fs->id : -EINVAL; |
efe73c3e KZ |
1199 | } |
1200 | ||
1201 | /** | |
1202 | * mnt_fs_get_parent_id: | |
1203 | * @fs: /proc/self/mountinfo entry | |
1204 | * | |
56be757f | 1205 | * Returns: parent mount ID or negative number in case of error. |
efe73c3e | 1206 | */ |
68164f6c | 1207 | int mnt_fs_get_parent_id(struct libmnt_fs *fs) |
efe73c3e | 1208 | { |
56be757f | 1209 | return fs ? fs->parent : -EINVAL; |
efe73c3e KZ |
1210 | } |
1211 | ||
1212 | /** | |
1213 | * mnt_fs_get_devno: | |
0b3953a3 | 1214 | * @fs: /proc/self/mountinfo entry |
efe73c3e KZ |
1215 | * |
1216 | * Returns: value of st_dev for files on filesystem or 0 in case of error. | |
1217 | */ | |
68164f6c | 1218 | dev_t mnt_fs_get_devno(struct libmnt_fs *fs) |
efe73c3e | 1219 | { |
efe73c3e KZ |
1220 | return fs ? fs->devno : 0; |
1221 | } | |
1222 | ||
f7f29b56 KZ |
1223 | /** |
1224 | * mnt_fs_get_tid: | |
a3bb7e65 | 1225 | * @fs: /proc/tid/mountinfo entry |
f7f29b56 | 1226 | * |
d58b3157 | 1227 | * Returns: TID (task ID) for filesystems read from the mountinfo file |
f7f29b56 KZ |
1228 | */ |
1229 | pid_t mnt_fs_get_tid(struct libmnt_fs *fs) | |
1230 | { | |
f7f29b56 KZ |
1231 | return fs ? fs->tid : 0; |
1232 | } | |
1233 | ||
d115ee9b KZ |
1234 | /** |
1235 | * mnt_fs_get_option: | |
1236 | * @fs: fstab/mtab/mountinfo entry pointer | |
1237 | * @name: option name | |
d58b3157 | 1238 | * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL |
d115ee9b KZ |
1239 | * @valsz: returns size of options value or 0 |
1240 | * | |
d58b3157 | 1241 | * Returns: 0 on success, 1 when @name not found or negative number in case of error. |
d115ee9b | 1242 | */ |
68164f6c | 1243 | int mnt_fs_get_option(struct libmnt_fs *fs, const char *name, |
d115ee9b KZ |
1244 | char **value, size_t *valsz) |
1245 | { | |
76a06ca4 KZ |
1246 | char rc = 1; |
1247 | ||
ba2bdf41 KZ |
1248 | if (!fs) |
1249 | return -EINVAL; | |
76a06ca4 KZ |
1250 | if (fs->fs_optstr) |
1251 | rc = mnt_optstr_get_option(fs->fs_optstr, name, value, valsz); | |
1252 | if (rc == 1 && fs->vfs_optstr) | |
1253 | rc = mnt_optstr_get_option(fs->vfs_optstr, name, value, valsz); | |
1254 | if (rc == 1 && fs->user_optstr) | |
1255 | rc = mnt_optstr_get_option(fs->user_optstr, name, value, valsz); | |
1256 | return rc; | |
1257 | } | |
1258 | ||
1259 | /** | |
1260 | * mnt_fs_get_attribute: | |
1261 | * @fs: fstab/mtab/mountinfo entry pointer | |
1262 | * @name: option name | |
d58b3157 | 1263 | * @value: returns pointer to the beginning of the value (e.g. name=VALUE) or NULL |
76a06ca4 KZ |
1264 | * @valsz: returns size of options value or 0 |
1265 | * | |
d58b3157 | 1266 | * Returns: 0 on success, 1 when @name not found or negative number in case of error. |
76a06ca4 | 1267 | */ |
68164f6c | 1268 | int mnt_fs_get_attribute(struct libmnt_fs *fs, const char *name, |
76a06ca4 KZ |
1269 | char **value, size_t *valsz) |
1270 | { | |
1271 | char rc = 1; | |
1272 | ||
4569bbea KZ |
1273 | if (!fs) |
1274 | return -EINVAL; | |
76a06ca4 KZ |
1275 | if (fs->attrs) |
1276 | rc = mnt_optstr_get_option(fs->attrs, name, value, valsz); | |
1277 | return rc; | |
d115ee9b KZ |
1278 | } |
1279 | ||
cb90e24e OO |
1280 | /** |
1281 | * mnt_fs_get_comment: | |
1282 | * @fs: fstab/mtab/mountinfo entry pointer | |
1283 | * | |
1284 | * Returns: 0 on success, 1 when not found the @name or negative number in case of error. | |
1285 | */ | |
1286 | const char *mnt_fs_get_comment(struct libmnt_fs *fs) | |
1287 | { | |
cb90e24e OO |
1288 | if (!fs) |
1289 | return NULL; | |
1290 | return fs->comment; | |
1291 | } | |
1292 | ||
1293 | /** | |
1294 | * mnt_fs_set_comment: | |
1295 | * @fs: fstab entry pointer | |
1296 | * @comm: comment string | |
1297 | * | |
d22f2822 | 1298 | * Note that the comment has to be terminated by '\n' (new line), otherwise |
d58b3157 | 1299 | * the whole filesystem entry will be written as a comment to the tabfile (e.g. |
d22f2822 OO |
1300 | * fstab). |
1301 | * | |
cb90e24e OO |
1302 | * Returns: 0 on success or <0 in case of error. |
1303 | */ | |
1304 | int mnt_fs_set_comment(struct libmnt_fs *fs, const char *comm) | |
1305 | { | |
deb1c903 | 1306 | return strdup_to_struct_member(fs, comment, comm); |
cb90e24e OO |
1307 | } |
1308 | ||
1309 | /** | |
1310 | * mnt_fs_append_comment: | |
1311 | * @fs: fstab entry pointer | |
7b1333fa | 1312 | * @comm: comment string |
cb90e24e | 1313 | * |
d22f2822 OO |
1314 | * See also mnt_fs_set_comment(). |
1315 | * | |
cb90e24e OO |
1316 | * Returns: 0 on success or <0 in case of error. |
1317 | */ | |
1318 | int mnt_fs_append_comment(struct libmnt_fs *fs, const char *comm) | |
1319 | { | |
cb90e24e OO |
1320 | if (!fs) |
1321 | return -EINVAL; | |
1322 | ||
1323 | return append_string(&fs->comment, comm); | |
1324 | } | |
1325 | ||
3fca8422 KZ |
1326 | /** |
1327 | * mnt_fs_match_target: | |
1328 | * @fs: filesystem | |
1329 | * @target: mountpoint path | |
1330 | * @cache: tags/paths cache or NULL | |
1331 | * | |
1332 | * Possible are three attempts: | |
1333 | * 1) compare @target with @fs->target | |
8642cd7b | 1334 | * |
3fca8422 | 1335 | * 2) realpath(@target) with @fs->target |
8642cd7b | 1336 | * |
fa705b54 | 1337 | * 3) realpath(@target) with realpath(@fs->target) if @fs is not from |
8642cd7b KZ |
1338 | * /proc/self/mountinfo. |
1339 | * | |
1340 | * However, if mnt_cache_set_targets(cache, mtab) was called, and the | |
1341 | * path @target or @fs->target is found in the @mtab, the canonicalization is | |
1342 | * is not performed (see mnt_resolve_target()). | |
3fca8422 KZ |
1343 | * |
1344 | * The 2nd and 3rd attempts are not performed when @cache is NULL. | |
1345 | * | |
d58b3157 | 1346 | * Returns: 1 if @fs target is equal to @target, else 0. |
3fca8422 | 1347 | */ |
16b8db49 KZ |
1348 | int mnt_fs_match_target(struct libmnt_fs *fs, const char *target, |
1349 | struct libmnt_cache *cache) | |
3fca8422 KZ |
1350 | { |
1351 | int rc = 0; | |
1352 | ||
1353 | if (!fs || !target || !fs->target) | |
1354 | return 0; | |
1355 | ||
1356 | /* 1) native paths */ | |
6699e742 | 1357 | rc = mnt_fs_streq_target(fs, target); |
3fca8422 KZ |
1358 | |
1359 | if (!rc && cache) { | |
1360 | /* 2) - canonicalized and non-canonicalized */ | |
8642cd7b | 1361 | char *cn = mnt_resolve_target(target, cache); |
ab131f00 | 1362 | rc = (cn && mnt_fs_streq_target(fs, cn)); |
3fca8422 KZ |
1363 | |
1364 | /* 3) - canonicalized and canonicalized */ | |
45e8cdba | 1365 | if (!rc && cn && !mnt_fs_is_kernel(fs) && !mnt_fs_is_swaparea(fs)) { |
0382ba32 | 1366 | char *tcn = mnt_resolve_target(fs->target, cache); |
3fca8422 KZ |
1367 | rc = (tcn && strcmp(cn, tcn) == 0); |
1368 | } | |
1369 | } | |
1370 | ||
1371 | return rc; | |
1372 | } | |
1373 | ||
1374 | /** | |
1375 | * mnt_fs_match_source: | |
1376 | * @fs: filesystem | |
f12aac6e | 1377 | * @source: tag or path (device or so) or NULL |
3fca8422 KZ |
1378 | * @cache: tags/paths cache or NULL |
1379 | * | |
d58b3157 | 1380 | * Four attempts are possible: |
3fca8422 KZ |
1381 | * 1) compare @source with @fs->source |
1382 | * 2) compare realpath(@source) with @fs->source | |
1383 | * 3) compare realpath(@source) with realpath(@fs->source) | |
1384 | * 4) compare realpath(@source) with evaluated tag from @fs->source | |
1385 | * | |
1386 | * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The | |
1387 | * 2nd and 3rd attempts are not performed if @fs->source is tag. | |
1388 | * | |
d58b3157 | 1389 | * Returns: 1 if @fs source is equal to @source, else 0. |
3fca8422 | 1390 | */ |
16b8db49 KZ |
1391 | int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, |
1392 | struct libmnt_cache *cache) | |
3fca8422 | 1393 | { |
3fca8422 KZ |
1394 | char *cn; |
1395 | const char *src, *t, *v; | |
1396 | ||
f12aac6e KZ |
1397 | if (!fs) |
1398 | return 0; | |
1399 | ||
ab8c6e05 KZ |
1400 | /* 1) native paths... */ |
1401 | if (mnt_fs_streq_srcpath(fs, source) == 1) | |
f12aac6e KZ |
1402 | return 1; |
1403 | ||
ab8c6e05 | 1404 | if (!source || !fs->source) |
3fca8422 KZ |
1405 | return 0; |
1406 | ||
ab8c6e05 KZ |
1407 | /* ... and tags */ |
1408 | if (fs->tagname && strcmp(source, fs->source) == 0) | |
3ef87248 | 1409 | return 1; |
3fca8422 | 1410 | |
3ef87248 KZ |
1411 | if (!cache) |
1412 | return 0; | |
3fca8422 KZ |
1413 | if (fs->flags & (MNT_FS_NET | MNT_FS_PSEUDO)) |
1414 | return 0; | |
1415 | ||
1416 | cn = mnt_resolve_spec(source, cache); | |
1417 | if (!cn) | |
1418 | return 0; | |
1419 | ||
1420 | /* 2) canonicalized and native */ | |
1421 | src = mnt_fs_get_srcpath(fs); | |
ab8c6e05 | 1422 | if (src && mnt_fs_streq_srcpath(fs, cn)) |
3ef87248 | 1423 | return 1; |
3fca8422 KZ |
1424 | |
1425 | /* 3) canonicalized and canonicalized */ | |
3ef87248 | 1426 | if (src) { |
3fca8422 | 1427 | src = mnt_resolve_path(src, cache); |
3ef87248 KZ |
1428 | if (src && !strcmp(cn, src)) |
1429 | return 1; | |
3fca8422 | 1430 | } |
3ef87248 | 1431 | if (src || mnt_fs_get_tag(fs, &t, &v)) |
d58b3157 | 1432 | /* src path does not match and the tag is not defined */ |
3fca8422 KZ |
1433 | return 0; |
1434 | ||
1435 | /* read @source's tags to the cache */ | |
ba7232a1 | 1436 | if (mnt_cache_read_tags(cache, cn) < 0) { |
3fca8422 KZ |
1437 | if (errno == EACCES) { |
1438 | /* we don't have permissions to read TAGs from | |
d58b3157 | 1439 | * @source, but can translate the @fs tag to devname. |
3fca8422 KZ |
1440 | * |
1441 | * (because libblkid uses udev symlinks and this is | |
1442 | * accessible for non-root uses) | |
1443 | */ | |
1444 | char *x = mnt_resolve_tag(t, v, cache); | |
1445 | if (x && !strcmp(x, cn)) | |
1446 | return 1; | |
1447 | } | |
1448 | return 0; | |
1449 | } | |
1450 | ||
d58b3157 | 1451 | /* 4) has the @source a tag that matches with the tag from @fs ? */ |
3ef87248 KZ |
1452 | if (mnt_cache_device_has_tag(cache, cn, t, v)) |
1453 | return 1; | |
3fca8422 | 1454 | |
3ef87248 | 1455 | return 0; |
3fca8422 KZ |
1456 | } |
1457 | ||
1458 | /** | |
1459 | * mnt_fs_match_fstype: | |
1460 | * @fs: filesystem | |
1461 | * @types: filesystem name or comma delimited list of filesystems | |
1462 | * | |
1463 | * For more details see mnt_match_fstype(). | |
1464 | * | |
d58b3157 | 1465 | * Returns: 1 if @fs type is matching to @types, else 0. The function returns |
3fca8422 KZ |
1466 | * 0 when types is NULL. |
1467 | */ | |
68164f6c | 1468 | int mnt_fs_match_fstype(struct libmnt_fs *fs, const char *types) |
3fca8422 KZ |
1469 | { |
1470 | return mnt_match_fstype(fs->fstype, types); | |
1471 | } | |
1472 | ||
1473 | /** | |
1474 | * mnt_fs_match_options: | |
1475 | * @fs: filesystem | |
1476 | * @options: comma delimited list of options (and nooptions) | |
1477 | * | |
1478 | * For more details see mnt_match_options(). | |
1479 | * | |
d58b3157 | 1480 | * Returns: 1 if @fs type is matching to @options, else 0. The function returns |
3fca8422 KZ |
1481 | * 0 when types is NULL. |
1482 | */ | |
68164f6c | 1483 | int mnt_fs_match_options(struct libmnt_fs *fs, const char *options) |
3fca8422 | 1484 | { |
d84508cf | 1485 | return mnt_match_options(mnt_fs_get_options(fs), options); |
3fca8422 KZ |
1486 | } |
1487 | ||
d115ee9b KZ |
1488 | /** |
1489 | * mnt_fs_print_debug | |
1490 | * @fs: fstab/mtab/mountinfo entry | |
486d3972 | 1491 | * @file: file stream |
d115ee9b | 1492 | * |
56be757f | 1493 | * Returns: 0 on success or negative number in case of error. |
d115ee9b | 1494 | */ |
68164f6c | 1495 | int mnt_fs_print_debug(struct libmnt_fs *fs, FILE *file) |
d115ee9b | 1496 | { |
4569bbea | 1497 | if (!fs || !file) |
56be757f | 1498 | return -EINVAL; |
8d31f146 | 1499 | fprintf(file, "------ fs:\n"); |
77417bc0 KZ |
1500 | fprintf(file, "source: %s\n", mnt_fs_get_source(fs)); |
1501 | fprintf(file, "target: %s\n", mnt_fs_get_target(fs)); | |
1502 | fprintf(file, "fstype: %s\n", mnt_fs_get_fstype(fs)); | |
76a06ca4 | 1503 | |
f2b3a3a3 KZ |
1504 | if (mnt_fs_get_options(fs)) |
1505 | fprintf(file, "optstr: %s\n", mnt_fs_get_options(fs)); | |
76a06ca4 KZ |
1506 | if (mnt_fs_get_vfs_options(fs)) |
1507 | fprintf(file, "VFS-optstr: %s\n", mnt_fs_get_vfs_options(fs)); | |
1508 | if (mnt_fs_get_fs_options(fs)) | |
1509 | fprintf(file, "FS-opstr: %s\n", mnt_fs_get_fs_options(fs)); | |
68164f6c KZ |
1510 | if (mnt_fs_get_user_options(fs)) |
1511 | fprintf(file, "user-optstr: %s\n", mnt_fs_get_user_options(fs)); | |
e47a1931 OO |
1512 | if (mnt_fs_get_optional_fields(fs)) |
1513 | fprintf(file, "optional-fields: '%s'\n", mnt_fs_get_optional_fields(fs)); | |
76a06ca4 KZ |
1514 | if (mnt_fs_get_attributes(fs)) |
1515 | fprintf(file, "attributes: %s\n", mnt_fs_get_attributes(fs)); | |
dd369652 KZ |
1516 | |
1517 | if (mnt_fs_get_root(fs)) | |
77417bc0 | 1518 | fprintf(file, "root: %s\n", mnt_fs_get_root(fs)); |
ce4dd666 KZ |
1519 | |
1520 | if (mnt_fs_get_swaptype(fs)) | |
1521 | fprintf(file, "swaptype: %s\n", mnt_fs_get_swaptype(fs)); | |
1522 | if (mnt_fs_get_size(fs)) | |
1523 | fprintf(file, "size: %jd\n", mnt_fs_get_size(fs)); | |
1524 | if (mnt_fs_get_usedsize(fs)) | |
1525 | fprintf(file, "usedsize: %jd\n", mnt_fs_get_usedsize(fs)); | |
1526 | if (mnt_fs_get_priority(fs)) | |
1527 | fprintf(file, "priority: %d\n", mnt_fs_get_priority(fs)); | |
1528 | ||
dd369652 KZ |
1529 | if (mnt_fs_get_bindsrc(fs)) |
1530 | fprintf(file, "bindsrc: %s\n", mnt_fs_get_bindsrc(fs)); | |
9dd75aa6 | 1531 | if (mnt_fs_get_freq(fs)) |
77417bc0 | 1532 | fprintf(file, "freq: %d\n", mnt_fs_get_freq(fs)); |
9dd75aa6 | 1533 | if (mnt_fs_get_passno(fs)) |
77417bc0 | 1534 | fprintf(file, "pass: %d\n", mnt_fs_get_passno(fs)); |
9dd75aa6 | 1535 | if (mnt_fs_get_id(fs)) |
77417bc0 | 1536 | fprintf(file, "id: %d\n", mnt_fs_get_id(fs)); |
9dd75aa6 | 1537 | if (mnt_fs_get_parent_id(fs)) |
77417bc0 | 1538 | fprintf(file, "parent: %d\n", mnt_fs_get_parent_id(fs)); |
9dd75aa6 | 1539 | if (mnt_fs_get_devno(fs)) |
77417bc0 | 1540 | fprintf(file, "devno: %d:%d\n", major(mnt_fs_get_devno(fs)), |
f7f29b56 KZ |
1541 | minor(mnt_fs_get_devno(fs))); |
1542 | if (mnt_fs_get_tid(fs)) | |
1543 | fprintf(file, "tid: %d\n", mnt_fs_get_tid(fs)); | |
cb90e24e OO |
1544 | if (mnt_fs_get_comment(fs)) |
1545 | fprintf(file, "comment: '%s'\n", mnt_fs_get_comment(fs)); | |
f7f29b56 | 1546 | |
d115ee9b KZ |
1547 | return 0; |
1548 | } | |
8b95253f KZ |
1549 | |
1550 | /** | |
1551 | * mnt_free_mntent: | |
1552 | * @mnt: mount entry | |
1553 | * | |
d58b3157 | 1554 | * Deallocates the "mntent.h" mount entry. |
8b95253f KZ |
1555 | */ |
1556 | void mnt_free_mntent(struct mntent *mnt) | |
1557 | { | |
1558 | if (mnt) { | |
1559 | free(mnt->mnt_fsname); | |
1560 | free(mnt->mnt_dir); | |
1561 | free(mnt->mnt_type); | |
1562 | free(mnt->mnt_opts); | |
1563 | free(mnt); | |
1564 | } | |
1565 | } | |
1566 | ||
1567 | /** | |
1568 | * mnt_fs_to_mntent: | |
1569 | * @fs: filesystem | |
1570 | * @mnt: mount description (as described in mntent.h) | |
1571 | * | |
d58b3157 | 1572 | * Copies the information from @fs to struct mntent @mnt. If @mnt is already set, |
8b95253f KZ |
1573 | * then the struct mntent items are reallocated and updated. See also |
1574 | * mnt_free_mntent(). | |
1575 | * | |
d58b3157 | 1576 | * Returns: 0 on success and a negative number in case of error. |
8b95253f | 1577 | */ |
68164f6c | 1578 | int mnt_fs_to_mntent(struct libmnt_fs *fs, struct mntent **mnt) |
8b95253f KZ |
1579 | { |
1580 | int rc; | |
1581 | struct mntent *m; | |
1582 | ||
1583 | if (!fs || !mnt) | |
1584 | return -EINVAL; | |
1585 | ||
1586 | m = *mnt; | |
1587 | if (!m) { | |
1588 | m = calloc(1, sizeof(*m)); | |
1589 | if (!m) | |
1590 | return -ENOMEM; | |
1591 | } | |
1592 | ||
309139c7 | 1593 | if ((rc = update_str(&m->mnt_fsname, mnt_fs_get_source(fs)))) |
8b95253f | 1594 | goto err; |
309139c7 | 1595 | if ((rc = update_str(&m->mnt_dir, mnt_fs_get_target(fs)))) |
8b95253f | 1596 | goto err; |
309139c7 | 1597 | if ((rc = update_str(&m->mnt_type, mnt_fs_get_fstype(fs)))) |
8b95253f | 1598 | goto err; |
76a06ca4 KZ |
1599 | |
1600 | errno = 0; | |
1601 | m->mnt_opts = mnt_fs_strdup_options(fs); | |
1602 | if (!m->mnt_opts && errno) { | |
1603 | rc = -errno; | |
8b95253f | 1604 | goto err; |
76a06ca4 KZ |
1605 | } |
1606 | ||
8b95253f KZ |
1607 | m->mnt_freq = mnt_fs_get_freq(fs); |
1608 | m->mnt_passno = mnt_fs_get_passno(fs); | |
1609 | ||
de511a88 KZ |
1610 | if (!m->mnt_fsname) { |
1611 | m->mnt_fsname = strdup("none"); | |
1612 | if (!m->mnt_fsname) | |
1613 | goto err; | |
1614 | } | |
8b95253f KZ |
1615 | *mnt = m; |
1616 | ||
1617 | return 0; | |
1618 | err: | |
1619 | if (m != *mnt) | |
1620 | mnt_free_mntent(m); | |
1621 | return rc; | |
1622 | } |