summaryrefslogtreecommitdiffstats
path: root/sys-utils/swapon.c
diff options
context:
space:
mode:
authorKarel Zak2012-04-17 12:49:11 +0200
committerKarel Zak2012-04-17 12:49:11 +0200
commit64b588814e5f081a7ab37f820984aa7a2de9eee9 (patch)
tree7ca9e568d60ef32873c478b0e0d45c0bcef2b14e /sys-utils/swapon.c
parentmount: (new) improve error messages (diff)
downloadkernel-qcow2-util-linux-64b588814e5f081a7ab37f820984aa7a2de9eee9.tar.gz
kernel-qcow2-util-linux-64b588814e5f081a7ab37f820984aa7a2de9eee9.tar.xz
kernel-qcow2-util-linux-64b588814e5f081a7ab37f820984aa7a2de9eee9.zip
swapon: use libmount for /proc/swaps parsing
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/swapon.c')
-rw-r--r--sys-utils/swapon.c164
1 files changed, 65 insertions, 99 deletions
diff --git a/sys-utils/swapon.c b/sys-utils/swapon.c
index e1e8455a7..a28ff3c1b 100644
--- a/sys-utils/swapon.c
+++ b/sys-utils/swapon.c
@@ -16,6 +16,7 @@
#include <ctype.h>
#include <blkid.h>
+#include <libmount.h>
#include "bitops.h"
#include "blkdev.h"
@@ -151,110 +152,60 @@ swapoff_usage(FILE *out, int n) {
/*
* contents of /proc/swaps
*/
-static int numSwaps;
-static char **swapFiles; /* array of swap file and partition names */
+static struct libmnt_table *swaps;
+static struct libmnt_cache *mntcache;
-static void
-read_proc_swaps(void) {
- FILE *swaps;
- char line[1024];
- char *p, **q;
- size_t sz;
-
- numSwaps = 0;
- swapFiles = NULL;
-
- swaps = fopen(_PATH_PROC_SWAPS, "r");
- if (swaps == NULL)
- return; /* nothing wrong */
-
- /* skip the first line */
- if (!fgets(line, sizeof(line), swaps)) {
- /* do not whine about an empty file */
- if (ferror(swaps))
- warn(_("%s: unexpected file format"), _PATH_PROC_SWAPS);
- fclose(swaps);
- return;
+static struct libmnt_table *get_swaps_table(void)
+{
+ if (!swaps) {
+ swaps = mnt_new_table();
+ if (!swaps)
+ return NULL;
+ if (!mntcache)
+ mntcache = mnt_new_cache();
+
+ mnt_table_set_cache(swaps, mntcache);
+ if (mnt_table_parse_swaps(swaps, NULL) != 0)
+ return NULL;
}
- /* make sure the first line is the header */
- if (line[0] != '\0' && strncmp(line, "Filename\t", 9))
- goto valid_first_line;
-
- while (fgets(line, sizeof(line), swaps)) {
- valid_first_line:
- /*
- * Cut the line "swap_device ... more info" after device.
- * This will fail with names with embedded spaces.
- */
- for (p = line; *p && *p != ' '; p++);
- *p = '\0';
-
- /* the kernel can use " (deleted)" suffix for paths
- * in /proc/swaps, we have to remove this junk.
- */
- sz = strlen(line);
- if (sz > PATH_DELETED_SUFFIX_SZ) {
- p = line + (sz - PATH_DELETED_SUFFIX_SZ);
- if (strcmp(p, PATH_DELETED_SUFFIX) == 0)
- *p = '\0';
- }
-
- q = xrealloc(swapFiles, (numSwaps+1) * sizeof(*swapFiles));
- swapFiles = q;
- if ((p = unmangle(line, NULL)) == NULL)
- break;
-
- swapFiles[numSwaps++] = canonicalize_path(p);
- free(p);
- }
- fclose(swaps);
+ return swaps;
}
-/* note that swapFiles are always canonicalized */
-static int
-is_in_proc_swaps(const char *fname) {
- int i;
-
- for (i = 0; i < numSwaps; i++)
- if (swapFiles[i] && !strcmp(fname, swapFiles[i]))
- return 1;
- return 0;
+static int is_active_swap(const char *filename)
+{
+ struct libmnt_table *st = get_swaps_table();
+ return st && mnt_table_find_srcpath(st, filename, MNT_ITER_BACKWARD);
}
static int
display_summary(void)
{
- FILE *swaps;
- char line[1024] ;
+ struct libmnt_table *st = get_swaps_table();
+ struct libmnt_iter *itr;
+ struct libmnt_fs *fs;
- if ((swaps = fopen(_PATH_PROC_SWAPS, "r")) == NULL) {
- warn(_("%s: open failed"), _PATH_PROC_SWAPS);
+ if (!st)
return -1;
- }
- while (fgets(line, sizeof(line), swaps)) {
- char *p, *dev, *cn;
- if (!strncmp(line, "Filename\t", 9)) {
- printf("%s", line);
- continue;
- }
- for (p = line; *p && *p != ' '; p++);
- *p = '\0';
- for (++p; *p && isblank((unsigned int) *p); p++);
+ itr = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!itr)
+ err(EXIT_FAILURE, _("failed to initialize libmount iterator"));
- dev = unmangle(line, NULL);
- if (!dev)
- continue;
- cn = canonicalize_path(dev);
- if (cn)
- printf("%-39s %s", cn, p);
- free(dev);
- free(cn);
+ if (mnt_table_get_nents(st) > 0)
+ printf(_("%-39s\tType\tSize\tUsed\tPriority\n"), _("Filename"));
+
+ while (mnt_table_next_fs(st, itr, &fs) == 0) {
+ printf("%-39s\t%s\t%jd\t%jd\t%d\n",
+ mnt_fs_get_source(fs),
+ mnt_fs_get_swaptype(fs),
+ mnt_fs_get_size(fs),
+ mnt_fs_get_usedsize(fs),
+ mnt_fs_get_priority(fs));
}
- fclose(swaps);
- return 0 ;
+ mnt_free_iter(itr);
+ return 0;
}
/* calls mkswap */
@@ -655,8 +606,6 @@ swapon_all(void) {
struct mntent *fstab;
int status = 0;
- read_proc_swaps();
-
fp = setmntent(_PATH_MNTTAB, "r");
if (fp == NULL)
err(2, _("%s: open failed"), _PATH_MNTTAB);
@@ -695,7 +644,7 @@ swapon_all(void) {
continue;
}
- if (!is_in_proc_swaps(special) &&
+ if (!is_active_swap(special) &&
(!nofail || !access(special, R_OK)))
status |= do_swapon(special, pri, dsc, CANONIC);
@@ -853,9 +802,18 @@ main_swapoff(int argc, char *argv[]) {
* exists as ordinary file, not in procfs.
* do_swapoff() exits immediately on EPERM.
*/
- read_proc_swaps();
- for(i=0; i<numSwaps; i++)
- status |= do_swapoff(swapFiles[i], QUIET, CANONIC);
+ struct libmnt_table *st = get_swaps_table();
+
+ if (st && mnt_table_get_nents(st) > 0) {
+ struct libmnt_iter *itr = mnt_new_iter(MNT_ITER_BACKWARD);
+ struct libmnt_fs *fs;
+
+ while (itr && mnt_table_next_fs(st, itr, &fs) == 0)
+ status |= do_swapoff(mnt_fs_get_source(fs),
+ QUIET, CANONIC);
+
+ mnt_free_iter(itr);
+ }
/*
* Unswap stuff mentioned in /etc/fstab.
@@ -876,7 +834,7 @@ main_swapoff(int argc, char *argv[]) {
if (!special)
continue;
- if (!is_in_proc_swaps(special))
+ if (!is_active_swap(special))
do_swapoff(special, QUIET, CANONIC);
}
fclose(fp);
@@ -888,6 +846,8 @@ main_swapoff(int argc, char *argv[]) {
int
main(int argc, char *argv[]) {
+ int status;
+
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
@@ -899,11 +859,17 @@ main(int argc, char *argv[]) {
progname = p ? p+1 : argv[0];
}
+ mnt_init_debug(0);
+
if (streq(progname, "swapon"))
- return main_swapon(argc, argv);
+ status = main_swapon(argc, argv);
else if (streq(progname, "swapoff"))
- return main_swapoff(argc, argv);
-
- errx(EXIT_FAILURE, _("'%s' is unsupported program name "
+ status = main_swapoff(argc, argv);
+ else
+ errx(EXIT_FAILURE, _("'%s' is unsupported program name "
"(must be 'swapon' or 'swapoff')."), progname);
+
+ mnt_free_table(swaps);
+ mnt_free_cache(mntcache);
+ return status;
}