summaryrefslogtreecommitdiffstats
path: root/libmount/src
diff options
context:
space:
mode:
authorKarel Zak2012-04-03 13:20:32 +0200
committerKarel Zak2012-04-03 13:20:32 +0200
commitce4dd666f4e4cab7f0a41274c6b48da8e41860fd (patch)
tree00e2b8b3912ebf543239067ccae538d413b086fc /libmount/src
parentlibmount: clean up MNT_FMT_* usage in parser (diff)
downloadkernel-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.c79
-rw-r--r--libmount/src/libmount.h.in7
-rw-r--r--libmount/src/libmount.sym6
-rw-r--r--libmount/src/mountP.h11
-rw-r--r--libmount/src/tab_parse.c95
-rw-r--r--libmount/src/utils.c11
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.