b3f87c
From 3f9f1fa90a087186dcc96060537543d2685616d8 Mon Sep 17 00:00:00 2001
b3f87c
From: Vojtech Trefny <vtrefny@redhat.com>
b3f87c
Date: Mon, 1 Oct 2018 16:06:42 +0200
b3f87c
Subject: [PATCH 1/2] Use libblkid to check swap status before swapon
b3f87c
b3f87c
libblkid probe is more reliable than our custom check.
b3f87c
---
b3f87c
 configure.ac            |   2 +-
b3f87c
 src/plugins/Makefile.am |   4 +-
b3f87c
 src/plugins/swap.c      | 149 ++++++++++++++++++++++++++++++++--------
b3f87c
 3 files changed, 124 insertions(+), 31 deletions(-)
b3f87c
b3f87c
diff --git a/configure.ac b/configure.ac
b3f87c
index 6285a48..7ac5089 100644
b3f87c
--- a/configure.ac
b3f87c
+++ b/configure.ac
b3f87c
@@ -227,7 +227,7 @@ AS_IF([test "x$with_fs" != "xno"],
b3f87c
               AC_SUBST([PARTED_FS_CFLAGS], [])])],
b3f87c
       [])
b3f87c
 
b3f87c
-AS_IF([test "x$with_fs" != "xno" -o "x$with_crypto" != "xno"],
b3f87c
+AS_IF([test "x$with_fs" != "xno" -o "x$with_crypto" != "xno" -o "x$with_swap" != "xno"],
b3f87c
       [LIBBLOCKDEV_PKG_CHECK_MODULES([BLKID], [blkid >= 2.23.0])
b3f87c
       # older versions of libblkid don't support BLKID_SUBLKS_BADCSUM so let's just
b3f87c
       # define it as 0 (neutral value for bit combinations of flags)
b3f87c
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
b3f87c
index e7b4bf0..6219a40 100644
b3f87c
--- a/src/plugins/Makefile.am
b3f87c
+++ b/src/plugins/Makefile.am
b3f87c
@@ -149,8 +149,8 @@ libbd_nvdimm_la_SOURCES = nvdimm.c nvdimm.h check_deps.c check_deps.h
b3f87c
 endif
b3f87c
 
b3f87c
 if WITH_SWAP
b3f87c
-libbd_swap_la_CFLAGS = $(GLIB_CFLAGS) -Wall -Wextra -Werror
b3f87c
-libbd_swap_la_LIBADD = $(GLIB_LIBS) ${builddir}/../utils/libbd_utils.la
b3f87c
+libbd_swap_la_CFLAGS = $(GLIB_CFLAGS) $(BLKID_CFLAGS) -Wall -Wextra -Werror
b3f87c
+libbd_swap_la_LIBADD = $(GLIB_LIBS) $(BLKID_LIBS) ${builddir}/../utils/libbd_utils.la
b3f87c
 libbd_swap_la_LDFLAGS = -L${srcdir}/../utils/ -version-info 2:0:0 -Wl,--no-undefined
b3f87c
 libbd_swap_la_CPPFLAGS = -I${builddir}/../../include/
b3f87c
 libbd_swap_la_SOURCES = swap.c swap.h check_deps.c check_deps.h
b3f87c
diff --git a/src/plugins/swap.c b/src/plugins/swap.c
b3f87c
index bc52637..bfe653f 100644
b3f87c
--- a/src/plugins/swap.c
b3f87c
+++ b/src/plugins/swap.c
b3f87c
@@ -21,6 +21,8 @@
b3f87c
 #include <string.h>
b3f87c
 #include <unistd.h>
b3f87c
 #include <sys/swap.h>
b3f87c
+#include <fcntl.h>
b3f87c
+#include <blkid.h>
b3f87c
 #include <blockdev/utils.h>
b3f87c
 
b3f87c
 #include "swap.h"
b3f87c
@@ -179,13 +181,14 @@ gboolean bd_swap_mkswap (const gchar *device, const gchar *label, const BDExtraA
b3f87c
  * Tech category: %BD_SWAP_TECH_SWAP-%BD_SWAP_TECH_MODE_ACTIVATE_DEACTIVATE
b3f87c
  */
b3f87c
 gboolean bd_swap_swapon (const gchar *device, gint priority, GError **error) {
b3f87c
-    GIOChannel *dev_file = NULL;
b3f87c
-    GIOStatus io_status = G_IO_STATUS_ERROR;
b3f87c
-    GError *tmp_error = NULL;
b3f87c
-    gsize num_read = 0;
b3f87c
-    gchar dev_status[11];
b3f87c
-    dev_status[10] = '\0';
b3f87c
-    gint page_size;
b3f87c
+    blkid_probe probe = NULL;
b3f87c
+    gint fd = 0;
b3f87c
+    gint status = 0;
b3f87c
+    guint n_try = 0;
b3f87c
+    const gchar *value = NULL;
b3f87c
+    gint64 status_len = 0;
b3f87c
+    gint64 swap_pagesize = 0;
b3f87c
+    gint64 sys_pagesize = 0;
b3f87c
     gint flags = 0;
b3f87c
     gint ret = 0;
b3f87c
     guint64 progress_id = 0;
b3f87c
@@ -198,53 +201,143 @@ gboolean bd_swap_swapon (const gchar *device, gint priority, GError **error) {
b3f87c
 
b3f87c
     bd_utils_report_progress (progress_id, 0, "Analysing the swap device");
b3f87c
     /* check the device if it is an activatable swap */
b3f87c
-    dev_file = g_io_channel_new_file (device, "r", error);
b3f87c
-    if (!dev_file) {
b3f87c
-        /* error is already populated */
b3f87c
+    probe = blkid_new_probe ();
b3f87c
+    if (!probe) {
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+                     "Failed to create a new probe");
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
         return FALSE;
b3f87c
     }
b3f87c
 
b3f87c
-    page_size = getpagesize ();
b3f87c
-    page_size = MAX (2048, page_size);
b3f87c
-    io_status = g_io_channel_seek_position (dev_file, page_size - 10, G_SEEK_SET, &tmp_error);
b3f87c
-    if (io_status != G_IO_STATUS_NORMAL) {
b3f87c
+    fd = open (device, O_RDONLY|O_CLOEXEC);
b3f87c
+    if (fd == -1) {
b3f87c
         g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
-                     "Failed to determine device's state: %s", tmp_error->message);
b3f87c
-        g_clear_error (&tmp_error);
b3f87c
-        g_io_channel_shutdown (dev_file, FALSE, &tmp_error);
b3f87c
+                     "Failed to open the device '%s'", device);
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
         return FALSE;
b3f87c
     }
b3f87c
 
b3f87c
-    io_status = g_io_channel_read_chars (dev_file, dev_status, 10, &num_read, &tmp_error);
b3f87c
-    if ((io_status != G_IO_STATUS_NORMAL) || (num_read != 10)) {
b3f87c
+    /* we may need to try mutliple times with some delays in case the device is
b3f87c
+       busy at the very moment */
b3f87c
+    for (n_try=5, status=-1; (status != 0) && (n_try > 0); n_try--) {
b3f87c
+        status = blkid_probe_set_device (probe, fd, 0, 0);
b3f87c
+        if (status != 0)
b3f87c
+            g_usleep (100 * 1000); /* microseconds */
b3f87c
+    }
b3f87c
+    if (status != 0) {
b3f87c
         g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
-                     "Failed to determine device's state: %s", tmp_error->message);
b3f87c
-        g_clear_error (&tmp_error);
b3f87c
-        g_io_channel_shutdown (dev_file, FALSE, &tmp_error);
b3f87c
-        g_clear_error (&tmp_error);
b3f87c
+                     "Failed to create a probe for the device '%s'", device);
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
         return FALSE;
b3f87c
     }
b3f87c
 
b3f87c
-    g_io_channel_shutdown (dev_file, FALSE, &tmp_error);
b3f87c
-    g_clear_error (&tmp_error);
b3f87c
+    blkid_probe_enable_superblocks (probe, 1);
b3f87c
+    blkid_probe_set_superblocks_flags (probe, BLKID_SUBLKS_TYPE | BLKID_SUBLKS_MAGIC);
b3f87c
 
b3f87c
-    if (g_str_has_prefix (dev_status, "SWAP-SPACE")) {
b3f87c
+    /* we may need to try mutliple times with some delays in case the device is
b3f87c
+       busy at the very moment */
b3f87c
+    for (n_try=5, status=-1; !(status == 0 || status == 1) && (n_try > 0); n_try--) {
b3f87c
+        status = blkid_do_safeprobe (probe);
b3f87c
+        if (status < 0)
b3f87c
+            g_usleep (100 * 1000); /* microseconds */
b3f87c
+    }
b3f87c
+    if (status < 0) {
b3f87c
+        /* -1 or -2 = error during probing*/
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+                     "Failed to probe the device '%s'", device);
b3f87c
+        bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
+        return FALSE;
b3f87c
+    } else if (status == 1) {
b3f87c
+        /* 1 = nothing detected */
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+                     "No superblock detected on the device '%s'", device);
b3f87c
+        bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
+        return FALSE;
b3f87c
+    }
b3f87c
+
b3f87c
+    status = blkid_probe_lookup_value (probe, "TYPE", &value, NULL);
b3f87c
+    if (status != 0) {
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+                     "Failed to get format type for the device '%s'", device);
b3f87c
+        bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
+        return FALSE;
b3f87c
+    }
b3f87c
+
b3f87c
+    if (g_strcmp0 (value, "swap") != 0) {
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+                     "Device '%s' is not formatted as swap", device);
b3f87c
+        bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
+        return FALSE;
b3f87c
+    }
b3f87c
+
b3f87c
+    status = blkid_probe_lookup_value (probe, "SBMAGIC", &value, NULL);
b3f87c
+    if (status != 0) {
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+                     "Failed to get swap status on the device '%s'", device);
b3f87c
+        bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
+        return FALSE;
b3f87c
+    }
b3f87c
+
b3f87c
+    if (g_strcmp0 (value, "SWAP-SPACE") == 0) {
b3f87c
         g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE,
b3f87c
                      "Old swap format, cannot activate.");
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
         return FALSE;
b3f87c
-    } else if (g_str_has_prefix (dev_status, "S1SUSPEND") || g_str_has_prefix (dev_status, "S2SUSPEND")) {
b3f87c
+    } else if (g_strcmp0 (value, "S1SUSPEND") == 0 || g_strcmp0 (value, "S2SUSPEND") == 0) {
b3f87c
         g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE,
b3f87c
                      "Suspended system on the swap device, cannot activate.");
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
         return FALSE;
b3f87c
-    } else if (!g_str_has_prefix (dev_status, "SWAPSPACE2")) {
b3f87c
+    } else if (g_strcmp0 (value, "SWAPSPACE2") != 0) {
b3f87c
         g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE,
b3f87c
                      "Unknown swap space format, cannot activate.");
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
+        return FALSE;
b3f87c
+    }
b3f87c
+
b3f87c
+    status_len = (gint64) strlen (value);
b3f87c
+
b3f87c
+    status = blkid_probe_lookup_value (probe, "SBMAGIC_OFFSET", &value, NULL);
b3f87c
+    if (status != 0 || !value) {
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+                     "Failed to get swap status on the device '%s'", device);
b3f87c
+        bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
+        blkid_free_probe (probe);
b3f87c
+        close (fd);
b3f87c
+        return FALSE;
b3f87c
+    }
b3f87c
+
b3f87c
+    swap_pagesize = status_len + g_ascii_strtoll (value, (char **)NULL, 10);
b3f87c
+
b3f87c
+    blkid_free_probe (probe);
b3f87c
+    close (fd);
b3f87c
+
b3f87c
+    sys_pagesize = getpagesize ();
b3f87c
+
b3f87c
+    if (swap_pagesize != sys_pagesize) {
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+                     "Swap format pagesize (%"G_GINT64_FORMAT") and system pagesize (%"G_GINT64_FORMAT") don't match",
b3f87c
+                     swap_pagesize, sys_pagesize);
b3f87c
+        bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
         return FALSE;
b3f87c
     }
b3f87c
 
b3f87c
-- 
b3f87c
2.17.1
b3f87c
b3f87c
b3f87c
From f6508829e7cac138e4961a1c3ef6170d6f67bfd9 Mon Sep 17 00:00:00 2001
b3f87c
From: Vojtech Trefny <vtrefny@redhat.com>
b3f87c
Date: Thu, 4 Oct 2018 08:07:55 +0200
b3f87c
Subject: [PATCH 2/2] Add error codes and Python exceptions for swapon fails
b3f87c
b3f87c
We need to be able to tell why swapon failed so our users can
b3f87c
decide what to do.
b3f87c
---
b3f87c
 src/lib/plugin_apis/swap.api        |  4 ++++
b3f87c
 src/plugins/swap.c                  | 10 +++++-----
b3f87c
 src/plugins/swap.h                  |  4 ++++
b3f87c
 src/python/gi/overrides/BlockDev.py | 19 +++++++++++++++++--
b3f87c
 tests/swap_test.py                  | 13 +++++++++++++
b3f87c
 5 files changed, 43 insertions(+), 7 deletions(-)
b3f87c
b3f87c
diff --git a/src/lib/plugin_apis/swap.api b/src/lib/plugin_apis/swap.api
b3f87c
index d0906fe..3fcc0e5 100644
b3f87c
--- a/src/lib/plugin_apis/swap.api
b3f87c
+++ b/src/lib/plugin_apis/swap.api
b3f87c
@@ -10,6 +10,10 @@ typedef enum {
b3f87c
     BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
     BD_SWAP_ERROR_ACTIVATE,
b3f87c
     BD_SWAP_ERROR_TECH_UNAVAIL,
b3f87c
+    BD_SWAP_ERROR_ACTIVATE_OLD,
b3f87c
+    BD_SWAP_ERROR_ACTIVATE_SUSPEND,
b3f87c
+    BD_SWAP_ERROR_ACTIVATE_UNKNOWN,
b3f87c
+    BD_SWAP_ERROR_ACTIVATE_PAGESIZE,
b3f87c
 } BDSwapError;
b3f87c
 
b3f87c
 typedef enum {
b3f87c
diff --git a/src/plugins/swap.c b/src/plugins/swap.c
b3f87c
index bfe653f..28db6f3 100644
b3f87c
--- a/src/plugins/swap.c
b3f87c
+++ b/src/plugins/swap.c
b3f87c
@@ -292,21 +292,21 @@ gboolean bd_swap_swapon (const gchar *device, gint priority, GError **error) {
b3f87c
     }
b3f87c
 
b3f87c
     if (g_strcmp0 (value, "SWAP-SPACE") == 0) {
b3f87c
-        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE,
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE_OLD,
b3f87c
                      "Old swap format, cannot activate.");
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
         blkid_free_probe (probe);
b3f87c
         close (fd);
b3f87c
         return FALSE;
b3f87c
     } else if (g_strcmp0 (value, "S1SUSPEND") == 0 || g_strcmp0 (value, "S2SUSPEND") == 0) {
b3f87c
-        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE,
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE_SUSPEND,
b3f87c
                      "Suspended system on the swap device, cannot activate.");
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
         blkid_free_probe (probe);
b3f87c
         close (fd);
b3f87c
         return FALSE;
b3f87c
     } else if (g_strcmp0 (value, "SWAPSPACE2") != 0) {
b3f87c
-        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE,
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE_UNKNOWN,
b3f87c
                      "Unknown swap space format, cannot activate.");
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
         blkid_free_probe (probe);
b3f87c
@@ -318,7 +318,7 @@ gboolean bd_swap_swapon (const gchar *device, gint priority, GError **error) {
b3f87c
 
b3f87c
     status = blkid_probe_lookup_value (probe, "SBMAGIC_OFFSET", &value, NULL);
b3f87c
     if (status != 0 || !value) {
b3f87c
-        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE_PAGESIZE,
b3f87c
                      "Failed to get swap status on the device '%s'", device);
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
         blkid_free_probe (probe);
b3f87c
@@ -334,7 +334,7 @@ gboolean bd_swap_swapon (const gchar *device, gint priority, GError **error) {
b3f87c
     sys_pagesize = getpagesize ();
b3f87c
 
b3f87c
     if (swap_pagesize != sys_pagesize) {
b3f87c
-        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
+        g_set_error (error, BD_SWAP_ERROR, BD_SWAP_ERROR_ACTIVATE_PAGESIZE,
b3f87c
                      "Swap format pagesize (%"G_GINT64_FORMAT") and system pagesize (%"G_GINT64_FORMAT") don't match",
b3f87c
                      swap_pagesize, sys_pagesize);
b3f87c
         bd_utils_report_finished (progress_id, (*error)->message);
b3f87c
diff --git a/src/plugins/swap.h b/src/plugins/swap.h
b3f87c
index a01c873..9947bad 100644
b3f87c
--- a/src/plugins/swap.h
b3f87c
+++ b/src/plugins/swap.h
b3f87c
@@ -12,6 +12,10 @@ typedef enum {
b3f87c
     BD_SWAP_ERROR_UNKNOWN_STATE,
b3f87c
     BD_SWAP_ERROR_ACTIVATE,
b3f87c
     BD_SWAP_ERROR_TECH_UNAVAIL,
b3f87c
+    BD_SWAP_ERROR_ACTIVATE_OLD,
b3f87c
+    BD_SWAP_ERROR_ACTIVATE_SUSPEND,
b3f87c
+    BD_SWAP_ERROR_ACTIVATE_UNKNOWN,
b3f87c
+    BD_SWAP_ERROR_ACTIVATE_PAGESIZE,
b3f87c
 } BDSwapError;
b3f87c
 
b3f87c
 typedef enum {
b3f87c
diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py
b3f87c
index c2ef2f4..e608887 100644
b3f87c
--- a/src/python/gi/overrides/BlockDev.py
b3f87c
+++ b/src/python/gi/overrides/BlockDev.py
b3f87c
@@ -1031,7 +1031,17 @@ __all__.append("MpathError")
b3f87c
 
b3f87c
 class SwapError(BlockDevError):
b3f87c
     pass
b3f87c
-__all__.append("SwapError")
b3f87c
+class SwapActivateError(SwapError):
b3f87c
+    pass
b3f87c
+class SwapOldError(SwapActivateError):
b3f87c
+    pass
b3f87c
+class SwapSuspendError(SwapActivateError):
b3f87c
+    pass
b3f87c
+class SwapUnknownError(SwapActivateError):
b3f87c
+    pass
b3f87c
+class SwapPagesizeError(SwapActivateError):
b3f87c
+    pass
b3f87c
+__all__.extend(("SwapError", "SwapActivateError", "SwapOldError", "SwapSuspendError", "SwapUnknownError", "SwapPagesizeError"))
b3f87c
 
b3f87c
 class KbdError(BlockDevError):
b3f87c
     pass
b3f87c
@@ -1070,6 +1080,11 @@ __all__.append("BlockDevNotImplementedError")
b3f87c
 not_implemented_rule = XRule(GLib.Error, re.compile(r".*The function '.*' called, but not implemented!"), None, BlockDevNotImplementedError)
b3f87c
 
b3f87c
 fs_nofs_rule = XRule(GLib.Error, None, 3, FSNoFSError)
b3f87c
+swap_activate_rule = XRule(GLib.Error, None, 1, SwapActivateError)
b3f87c
+swap_old_rule = XRule(GLib.Error, None, 3, SwapOldError)
b3f87c
+swap_suspend_rule = XRule(GLib.Error, None, 4, SwapSuspendError)
b3f87c
+swap_unknown_rule = XRule(GLib.Error, None, 5, SwapUnknownError)
b3f87c
+swap_pagesize_rule = XRule(GLib.Error, None, 6, SwapPagesizeError)
b3f87c
 
b3f87c
 btrfs = ErrorProxy("btrfs", BlockDev, [(GLib.Error, BtrfsError)], [not_implemented_rule])
b3f87c
 __all__.append("btrfs")
b3f87c
@@ -1092,7 +1107,7 @@ __all__.append("md")
b3f87c
 mpath = ErrorProxy("mpath", BlockDev, [(GLib.Error, MpathError)], [not_implemented_rule])
b3f87c
 __all__.append("mpath")
b3f87c
 
b3f87c
-swap = ErrorProxy("swap", BlockDev, [(GLib.Error, SwapError)], [not_implemented_rule])
b3f87c
+swap = ErrorProxy("swap", BlockDev, [(GLib.Error, SwapError)], [not_implemented_rule, swap_activate_rule, swap_old_rule, swap_suspend_rule, swap_unknown_rule, swap_pagesize_rule])
b3f87c
 __all__.append("swap")
b3f87c
 
b3f87c
 kbd = ErrorProxy("kbd", BlockDev, [(GLib.Error, KbdError)], [not_implemented_rule])
b3f87c
diff --git a/tests/swap_test.py b/tests/swap_test.py
b3f87c
index 05d0c19..395fdf5 100644
b3f87c
--- a/tests/swap_test.py
b3f87c
+++ b/tests/swap_test.py
b3f87c
@@ -97,6 +97,19 @@ class SwapTestCase(SwapTest):
b3f87c
         _ret, out, _err = run_command("blkid -ovalue -sLABEL -p %s" % self.loop_dev)
b3f87c
         self.assertEqual(out, "BlockDevSwap")
b3f87c
 
b3f87c
+    def test_swapon_pagesize(self):
b3f87c
+        """Verify that activating swap with different pagesize fails"""
b3f87c
+
b3f87c
+        # create swap with 64k pagesize
b3f87c
+        ret, out, err = run_command("mkswap --pagesize 65536 %s" % self.loop_dev)
b3f87c
+        if ret != 0:
b3f87c
+            self.fail("Failed to prepare swap for pagesize test: %s %s" % (out, err))
b3f87c
+
b3f87c
+        # activation should fail because swap has different pagesize
b3f87c
+        with self.assertRaises(BlockDev.SwapPagesizeError):
b3f87c
+            BlockDev.swap.swapon(self.loop_dev)
b3f87c
+
b3f87c
+
b3f87c
 class SwapUnloadTest(SwapTest):
b3f87c
     def setUp(self):
b3f87c
         # make sure the library is initialized with all plugins loaded for other
b3f87c
-- 
b3f87c
2.17.1
b3f87c