#include #include #include #ifdef HAVE_SYS_SWAP_H # include #endif #include "nls.h" #include "c.h" #include "xalloc.h" #include "closestream.h" #include "swapprober.h" #include "swapon-common.h" #if !defined(HAVE_SWAPOFF) && defined(SYS_swapoff) # include # define swapoff(path) syscall(SYS_swapoff, path) #endif static int verbose; static int all; #define QUIET 1 #define CANONIC 1 /* * This function works like mnt_resolve_tag(), but it's able to read UUID/LABEL * from regular swap files too (according to entries in /proc/swaps). Note that * mnt_resolve_tag() and mnt_resolve_spec() works with system visible block * devices only. */ static char *swapoff_resolve_tag(const char *name, const char *value, struct libmnt_cache *cache) { char *path; struct libmnt_table *tb; struct libmnt_iter *itr; struct libmnt_fs *fs; /* this is usual case for block devices (and it's really fast as it uses * udev /dev/disk/by-* symlinks by default */ path = mnt_resolve_tag(name, value, cache); if (path) return path; /* try regular files from /proc/swaps */ tb = get_swaps(); if (!tb) return NULL; itr = mnt_new_iter(MNT_ITER_BACKWARD); if (!itr) err(EXIT_FAILURE, _("failed to initialize libmount iterator")); while (tb && mnt_table_next_fs(tb, itr, &fs) == 0) { blkid_probe pr = NULL; const char *src = mnt_fs_get_source(fs); const char *type = mnt_fs_get_swaptype(fs); const char *data = NULL; if (!src || !type || strcmp(type, "file") != 0) continue; pr = get_swap_prober(src); if (!pr) continue; blkid_probe_lookup_value(pr, name, &data, NULL); if (data && strcmp(data, value) == 0) path = xstrdup(src); blkid_free_probe(pr); if (path) break; } mnt_free_iter(itr); return path; } static int do_swapoff(const char *orig_special, int quiet, int canonic) { const char *special = orig_special; if (verbose) printf(_("swapoff %s\n"), orig_special); if (!canonic) { char *n, *v; special = mnt_resolve_spec(orig_special, mntcache); if (!special && blkid_parse_tag_string(orig_special, &n, &v) == 0) { special = swapoff_resolve_tag(n, v, mntcache); free(n); free(v); } if (!special) return cannot_find(orig_special); } if (swapoff(special) == 0) return 0; /* success */ if (errno == EPERM) errx(EXIT_FAILURE, _("Not superuser.")); if (!quiet || errno == ENOMEM) warn(_("%s: swapoff failed"), orig_special); return -1; } static int swapoff_by(const char *name, const char *value, int quiet) { const char *special = swapoff_resolve_tag(name, value, mntcache); return special ? do_swapoff(special, quiet, CANONIC) : cannot_find(value); } static void __attribute__((__noreturn__)) usage(void) { FILE *out = stdout; fputs(USAGE_HEADER, out); fprintf(out, _(" %s [options] []\n"), program_invocation_short_name); fputs(USAGE_SEPARATOR, out); fputs(_("Disable devices and files for paging and swapping.\n"), out); fputs(USAGE_OPTIONS, out); fputs(_(" -a, --all disable all swaps from /proc/swaps\n" " -v, --verbose verbose mode\n"), out); fputs(USAGE_SEPARATOR, out); printf(USAGE_HELP_OPTIONS(24)); fputs(_("\nThe parameter:\n" \ " -L