diff options
author | Karel Zak | 2012-04-03 13:20:32 +0200 |
---|---|---|
committer | Karel Zak | 2012-04-03 13:20:32 +0200 |
commit | ce4dd666f4e4cab7f0a41274c6b48da8e41860fd (patch) | |
tree | 00e2b8b3912ebf543239067ccae538d413b086fc /libmount/src | |
parent | libmount: clean up MNT_FMT_* usage in parser (diff) | |
download | kernel-qcow2-util-linux-ce4dd666f4e4cab7f0a41274c6b48da8e41860fd.tar.gz kernel-qcow2-util-linux-ce4dd666f4e4cab7f0a41274c6b48da8e41860fd.tar.xz kernel-qcow2-util-linux-ce4dd666f4e4cab7f0a41274c6b48da8e41860fd.zip |
libmount: add support to parse /proc/swaps
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src')
-rw-r--r-- | libmount/src/fs.c | 79 | ||||
-rw-r--r-- | libmount/src/libmount.h.in | 7 | ||||
-rw-r--r-- | libmount/src/libmount.sym | 6 | ||||
-rw-r--r-- | libmount/src/mountP.h | 11 | ||||
-rw-r--r-- | libmount/src/tab_parse.c | 95 | ||||
-rw-r--r-- | libmount/src/utils.c | 11 |
6 files changed, 206 insertions, 3 deletions
diff --git a/libmount/src/fs.c b/libmount/src/fs.c index 167d7acef..22addb9f4 100644 --- a/libmount/src/fs.c +++ b/libmount/src/fs.c @@ -53,6 +53,7 @@ void mnt_free_fs(struct libmnt_fs *fs) free(fs->tagname); free(fs->tagval); free(fs->root); + free(fs->swaptype); free(fs->target); free(fs->fstype); free(fs->optstr); @@ -147,6 +148,8 @@ struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest, goto err; if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, root))) goto err; + if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, swaptype))) + goto err; if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, target))) goto err; if (cpy_str_at_offset(dest, src, offsetof(struct libmnt_fs, fstype))) @@ -167,6 +170,9 @@ struct libmnt_fs *mnt_copy_fs(struct libmnt_fs *dest, dest->freq = src->freq; dest->passno = src->passno; dest->flags = src->flags; + dest->size = src->size; + dest->usedsize = src->usedsize; + dest->priority = src->priority; return dest; err: @@ -1017,6 +1023,69 @@ int mnt_fs_set_root(struct libmnt_fs *fs, const char *root) } /** + * mnt_fs_get_swaptype: + * @fs: /proc/swaps entry + * + * Returns: swap type or NULL + */ +const char *mnt_fs_get_swaptype(struct libmnt_fs *fs) +{ + assert(fs); + return fs ? fs->swaptype : NULL; +} + +/** + * mnt_fs_get_size: + * @fs: /proc/swaps entry + * + * Returns: size + */ +off_t mnt_fs_get_size(struct libmnt_fs *fs) +{ + assert(fs); + return fs ? fs->size : 0; +} + +/** + * mnt_fs_get_usedsize: + * @fs: /proc/swaps entry + * + * Returns: used size + */ +off_t mnt_fs_get_usedsize(struct libmnt_fs *fs) +{ + assert(fs); + return fs ? fs->usedsize : 0; +} + +/** + * mnt_fs_get_priority: + * @fs: /proc/swaps entry + * + * Returns: priority + */ +int mnt_fs_get_priority(struct libmnt_fs *fs) +{ + assert(fs); + return fs ? fs->priority : 0; +} + +/** + * mnt_fs_set_priority: + * @fs: /proc/swaps entry + * + * Returns: 0 or -1 in case of error + */ +int mnt_fs_set_priority(struct libmnt_fs *fs, int prio) +{ + assert(fs); + if (!fs) + return -EINVAL; + fs->priority = prio; + return 0; +} + +/** * mnt_fs_get_bindsrc: * @fs: /run/mount/utab entry * @@ -1314,6 +1383,16 @@ int mnt_fs_print_debug(struct libmnt_fs *fs, FILE *file) if (mnt_fs_get_root(fs)) fprintf(file, "root: %s\n", mnt_fs_get_root(fs)); + + if (mnt_fs_get_swaptype(fs)) + fprintf(file, "swaptype: %s\n", mnt_fs_get_swaptype(fs)); + if (mnt_fs_get_size(fs)) + fprintf(file, "size: %jd\n", mnt_fs_get_size(fs)); + if (mnt_fs_get_usedsize(fs)) + fprintf(file, "usedsize: %jd\n", mnt_fs_get_usedsize(fs)); + if (mnt_fs_get_priority(fs)) + fprintf(file, "priority: %d\n", mnt_fs_get_priority(fs)); + if (mnt_fs_get_bindsrc(fs)) fprintf(file, "bindsrc: %s\n", mnt_fs_get_bindsrc(fs)); if (mnt_fs_get_freq(fs)) diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index fbabec5c8..a3eaa9ea6 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -131,6 +131,7 @@ extern int mnt_fstype_is_pseudofs(const char *type); extern int mnt_match_fstype(const char *type, const char *pattern); extern int mnt_match_options(const char *optstr, const char *pattern); extern const char *mnt_get_fstab_path(void); +extern const char *mnt_get_swaps_path(void); extern const char *mnt_get_mtab_path(void); extern int mnt_has_regular_mtab(const char **mtab, int *writable); @@ -259,6 +260,11 @@ extern int mnt_fs_get_id(struct libmnt_fs *fs); extern int mnt_fs_get_parent_id(struct libmnt_fs *fs); extern dev_t mnt_fs_get_devno(struct libmnt_fs *fs); +extern const char *mnt_fs_get_swaptype(struct libmnt_fs *fs); +extern off_t mnt_fs_get_size(struct libmnt_fs *fs); +extern off_t mnt_fs_get_usedsize(struct libmnt_fs *fs); +extern int mnt_fs_get_priority(struct libmnt_fs *fs); + extern int mnt_fs_match_target(struct libmnt_fs *fs, const char *target, struct libmnt_cache *cache); extern int mnt_fs_match_source(struct libmnt_fs *fs, const char *source, @@ -284,6 +290,7 @@ extern int mnt_table_parse_file(struct libmnt_table *tb, const char *filename); extern int mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname); extern int mnt_table_parse_fstab(struct libmnt_table *tb, const char *filename); +extern int mnt_table_parse_swaps(struct libmnt_table *tb, const char *filename); extern int mnt_table_parse_mtab(struct libmnt_table *tb, const char *filename); extern int mnt_table_set_parser_errcb(struct libmnt_table *tb, int (*cb)(struct libmnt_table *tb, const char *filename, int line)); diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym index 48860e870..c09f6ce2a 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -233,4 +233,10 @@ global: mnt_context_is_loopdel; mnt_context_is_nocanonicalize; mnt_context_is_nohelpers; + mnt_table_parse_swaps; + mnt_get_swaps_path; + mnt_fs_get_swaptype; + mnt_fs_get_size; + mnt_fs_get_usedsize; + mnt_fs_get_priority; } MOUNT_2.21; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index fa0edf50c..ee5e94fb2 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -194,7 +194,7 @@ struct libmnt_fs { char *bindsrc; /* utab, full path from fstab[1] for bind mounts */ - char *source; /* fstab[1], mountinfo[10]: + char *source; /* fstab[1], mountinfo[10], swaps[1]: * source dev, file, dir or TAG */ char *tagname; /* fstab[1]: tag name - "LABEL", "UUID", ..*/ char *tagval; /* tag value */ @@ -212,6 +212,12 @@ struct libmnt_fs { int freq; /* fstab[5]: dump frequency in days */ int passno; /* fstab[6]: pass number on parallel fsck */ + /* /proc/swaps */ + char *swaptype; /* swaps[2]: device type (partition, file, ...) */ + off_t size; /* swaps[3]: swaparea size */ + off_t usedsize; /* swaps[4]: used size */ + int priority; /* swaps[5]: swap priority */ + int flags; /* MNT_FS_* flags */ void *userdata; /* library independent data */ @@ -255,7 +261,8 @@ enum { MNT_FMT_FSTAB, /* /etc/{fs,m}tab */ MNT_FMT_MTAB = MNT_FMT_FSTAB, /* alias */ MNT_FMT_MOUNTINFO, /* /proc/#/mountinfo */ - MNT_FMT_UTAB /* /dev/.mount/utab */ + MNT_FMT_UTAB, /* /run/mount/utab */ + MNT_FMT_SWAPS /* /proc/swaps */ }; diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c index 6d3e21d21..73a7f83c8 100644 --- a/libmount/src/tab_parse.c +++ b/libmount/src/tab_parse.c @@ -269,6 +269,56 @@ enomem: } /* + * Parses one line from /proc/swaps + */ +static int mnt_parse_swaps_line(struct libmnt_fs *fs, char *s) +{ + uintmax_t fsz, usz; + int rc; + char *src = NULL; + + rc = sscanf(s, UL_SCNsA" " /* (1) source */ + UL_SCNsA" " /* (2) type */ + "%jd" /* (3) size */ + "%jd" /* (4) used */ + "%d", /* priority */ + + &src, + &fs->swaptype, + &fsz, + &usz, + &fs->priority); + + if (rc == 5) { + size_t sz; + + fs->size = fsz; + fs->usedsize = usz; + + unmangle_string(src); + + /* remove "(deleted)" suffix */ + sz = strlen(src); + if (sz > PATH_DELETED_SUFFIX_SZ) { + char *p = src + (sz - PATH_DELETED_SUFFIX_SZ); + if (strcmp(p, PATH_DELETED_SUFFIX) == 0) + *p = '\0'; + } + + rc = mnt_fs_set_source(fs, src); + if (!rc) + mnt_fs_set_fstype(fs, "swap"); + free(src); + } else { + DBG(TAB, mnt_debug("tab parse error: [sscanf rc=%d]: '%s'", rc, s)); + rc = -EINVAL; + } + + return rc; +} + + +/* * Returns {m,fs}tab or mountinfo file format (MNT_FMT_*) * * Note that we aren't trying to guess utab file format, because this file has @@ -281,9 +331,14 @@ static int guess_table_format(char *line) { unsigned int a, b; + DBG(TAB, mnt_debug("trying to guess table type")); + if (sscanf(line, "%u %u", &a, &b) == 2) return MNT_FMT_MOUNTINFO; + if (strncmp(line, "Filename\t", 9) == 0) + return MNT_FMT_SWAPS; + return MNT_FMT_FSTAB; /* fstab, mtab or /proc/mounts */ } @@ -302,6 +357,7 @@ static int mnt_table_parse_next(struct libmnt_table *tb, FILE *f, struct libmnt_ assert(fs); /* read the next non-blank non-comment line */ +next_line: do { if (fgets(buf, sizeof(buf), f) == NULL) return -EINVAL; @@ -327,8 +383,11 @@ static int mnt_table_parse_next(struct libmnt_table *tb, FILE *f, struct libmnt_ s = skip_spaces(buf); } while (*s == '\0' || *s == '#'); - if (tb->fmt == MNT_FMT_GUESS) + if (tb->fmt == MNT_FMT_GUESS) { tb->fmt = guess_table_format(s); + if (tb->fmt == MNT_FMT_SWAPS) + goto next_line; /* skip swap header */ + } switch (tb->fmt) { case MNT_FMT_FSTAB: @@ -340,6 +399,11 @@ static int mnt_table_parse_next(struct libmnt_table *tb, FILE *f, struct libmnt_ case MNT_FMT_UTAB: rc = mnt_parse_utab_line(fs, s); break; + case MNT_FMT_SWAPS: + if (strncmp(s, "Filename\t", 9) == 0) + goto next_line; /* skip swap header */ + rc = mnt_parse_swaps_line(fs, s); + break; default: rc = -1; /* unknown format */ break; @@ -350,6 +414,7 @@ static int mnt_table_parse_next(struct libmnt_table *tb, FILE *f, struct libmnt_ err: DBG(TAB, mnt_debug_h(tb, "%s:%d: %s parse error", filename, *nlines, tb->fmt == MNT_FMT_MOUNTINFO ? "mountinfo" : + tb->fmt == MNT_FMT_SWAPS ? "swaps" : tb->fmt == MNT_FMT_FSTAB ? "tab" : "utab")); /* by default all errors are recoverable, otherwise behavior depends on @@ -657,6 +722,34 @@ int mnt_table_set_parser_errcb(struct libmnt_table *tb, } /** + * mnt_table_parse_swaps: + * @tb: table + * @filename: overwrites default (/proc/swaps or $LIBMOUNT_SWAPS) or NULL + * + * This function parses /proc/swaps and appends new lines to the @tab. + * + * See also mnt_table_set_parser_errcb(). + * + * Returns: 0 on success or negative number in case of error. + */ +int mnt_table_parse_swaps(struct libmnt_table *tb, const char *filename) +{ + assert(tb); + + if (!tb) + return -EINVAL; + if (!filename) { + filename = mnt_get_swaps_path(); + if (!filename) + return -EINVAL; + } + + tb->fmt = MNT_FMT_SWAPS; + + return mnt_table_parse_file(tb, filename); +} + +/** * mnt_table_parse_fstab: * @tb: table * @filename: overwrites default (/etc/fstab or $LIBMOUNT_FSTAB) or NULL diff --git a/libmount/src/utils.c b/libmount/src/utils.c index ca1eb88d8..e740d83d0 100644 --- a/libmount/src/utils.c +++ b/libmount/src/utils.c @@ -705,6 +705,17 @@ done: } /** + * mnt_get_swaps_path: + * + * Returns: path to /proc/swaps or $LIBMOUNT_SWAPS. + */ +const char *mnt_get_swaps_path(void) +{ + const char *p = safe_getenv("LIBMOUNT_SWAPS"); + return p ? : _PATH_PROC_SWAPS; +} + +/** * mnt_get_fstab_path: * * Returns: path to /etc/fstab or $LIBMOUNT_FSTAB. |