]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add support to parse /proc/swaps
authorKarel Zak <kzak@redhat.com>
Tue, 3 Apr 2012 11:20:32 +0000 (13:20 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 3 Apr 2012 11:20:32 +0000 (13:20 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/docs/libmount-sections.txt
libmount/src/fs.c
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/mountP.h
libmount/src/tab_parse.c
libmount/src/utils.c

index d1318acdeb80e64465c5fdf9071aa9e3803342f6..c5173ccd17335102ec02c3035cc23e7545591086 100644 (file)
@@ -168,11 +168,15 @@ mnt_fs_get_option
 mnt_fs_get_options
 mnt_fs_get_parent_id
 mnt_fs_get_passno
+mnt_fs_get_priority
 mnt_fs_get_root
+mnt_fs_get_size
 mnt_fs_get_source
 mnt_fs_get_srcpath
+mnt_fs_get_swaptype
 mnt_fs_get_tag
 mnt_fs_get_target
+mnt_fs_get_usedsize
 mnt_fs_get_userdata
 mnt_fs_get_user_options
 mnt_fs_get_vfs_options
@@ -273,11 +277,12 @@ mnt_table_get_root_fs
 mnt_table_is_fs_mounted
 mnt_table_next_child_fs
 mnt_table_next_fs
-mnt_table_parse_file
 mnt_table_parse_dir
+mnt_table_parse_file
 mnt_table_parse_fstab
 mnt_table_parse_mtab
 mnt_table_parse_stream
+mnt_table_parse_swaps
 mnt_table_remove_fs
 mnt_table_set_cache
 mnt_table_set_iter
@@ -313,6 +318,7 @@ mnt_fstype_is_netfs
 mnt_fstype_is_pseudofs
 mnt_get_fstab_path
 mnt_get_mtab_path
+mnt_get_swaps_path
 mnt_has_regular_mtab
 mnt_mangle
 mnt_match_fstype
index 167d7acef9f391b9ead7ac50db6d446e03050f30..22addb9f42f4fda1857d7e62d7545de34dc589cf 100644 (file)
@@ -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:
@@ -1016,6 +1022,69 @@ int mnt_fs_set_root(struct libmnt_fs *fs, const char *root)
        return 0;
 }
 
+/**
+ * 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))
index fbabec5c8fda65f90075da7f8e28ae29807afe91..a3eaa9ea63e58dd6831f05c52c844b9317446033 100644 (file)
@@ -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));
index 48860e870cecf58f1752547d3a4c9f2ebaae0356..c09f6ce2a3dd84f1e67bae5304f1057271c1e37d 100644 (file)
@@ -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;
index fa0edf50cdf00a91dfd703dba3cde4bc9ab8f7c9..ee5e94fb28ba415ff906b1c7b0d788467331f431 100644 (file)
@@ -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 */
 };
 
 
index 6d3e21d21b549a14553db19b3d41675f2850380a..73a7f83c8b54aadb3e25e486e625d8a1acd79ac1 100644 (file)
@@ -268,6 +268,56 @@ enomem:
        return -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_*)
  *
@@ -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
@@ -656,6 +721,34 @@ int mnt_table_set_parser_errcb(struct libmnt_table *tb,
        return 0;
 }
 
+/**
+ * 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
index ca1eb88d873dabbceb8457365769d07f3bc592e8..e740d83d0c457b3887d877c9e5f06244c9c75a8e 100644 (file)
@@ -704,6 +704,17 @@ done:
        return 0;
 }
 
+/**
+ * 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:
  *