commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[hurd] 05/06: Add getting swap information from swapon and procfs


From: Samuel Thibault
Subject: [hurd] 05/06: Add getting swap information from swapon and procfs
Date: Wed, 16 Mar 2016 01:36:35 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch upstream
in repository hurd.

commit 4f51b0e104481fb6d337140eeaa51af8c674d236
Author: Samuel Thibault <address@hidden>
Date:   Wed Mar 16 01:48:40 2016 +0100

    Add getting swap information from swapon and procfs
    
    * hurd/default_pager.defs (default_pager_storage_info): New RPC.
    * hurd/default_pager_reply.defs: Skip default_pager_storage_info RPC.
    * hurd/default_pager_types.h: Include <mach/machine/vm_types.h>.
    (vm_size_array_t): New type.
    * mach-defpager/priv.h (part): Add `name' field.
    * mach-defpager/default_pager.c (new_partition): Allocate and fill
    `part->name' field. Free it on error.
    (destroy_paging_partition): Free `part->name' field.
    (S_default_pager_storage_info): New function.
    * procfs/Makefile (SRCS): Add default_pagerUser.c.
    * procfs/rootdir.c: Include "default_pager_U.h".
    (rootdir_gc_swaps): New function.
    (rootdir_entries): Add "swaps" entry.
    * sutils/swapon.c: Include <argz.h>
    (show): New variable.
    (options): Add --show/-S option.
    (def_pager, dev_master): New variables
    (swaponoff): Move getting `def_pager' to...
    (get_def_pager): ... new function.
    (main): Support 'S' option.
    * trans/proxy-defpager.c (S_default_pager_storage_info): New function.
---
 hurd/default_pager.defs       |   9 ++++
 hurd/default_pager_reply.defs |   2 +
 hurd/default_pager_types.h    |   2 +
 mach-defpager/default_pager.c | 100 +++++++++++++++++++++++++++++++++++++++
 mach-defpager/priv.h          |   1 +
 procfs/Makefile               |   2 +-
 procfs/rootdir.c              |  58 +++++++++++++++++++++++
 sutils/swapon.c               | 107 ++++++++++++++++++++++++++++++------------
 trans/proxy-defpager.c        |  13 +++++
 9 files changed, 262 insertions(+), 32 deletions(-)

diff --git a/hurd/default_pager.defs b/hurd/default_pager.defs
index a97bff2..14a5ec4 100644
--- a/hurd/default_pager.defs
+++ b/hurd/default_pager.defs
@@ -98,3 +98,12 @@ routine default_pager_object_set_size(
                memory_object           : memory_object_t;
        msgseqno seqno                  : mach_port_seqno_t;
                object_size_limit       : vm_size_t);
+
+routine default_pager_storage_info(
+               default_pager           : mach_port_t;
+       out     size                    : vm_size_array_t =
+                       array[] of vm_size_t, dealloc;
+       out     free                    : vm_size_array_t =
+                       array[] of vm_size_t, dealloc;
+       out     name                    : data_t);
+
diff --git a/hurd/default_pager_reply.defs b/hurd/default_pager_reply.defs
index 0f9ff86..02e0e91 100644
--- a/hurd/default_pager_reply.defs
+++ b/hurd/default_pager_reply.defs
@@ -15,3 +15,5 @@ skip;                         /* default_pager_paging_storage 
*/
 simpleroutine default_pager_object_set_size_reply(
                reply_port: mach_port_send_once_t;
                RETURN_CODE_ARG);
+
+skip;                          /* default_pager_storage_info */
diff --git a/hurd/default_pager_types.h b/hurd/default_pager_types.h
index 7cd14a3..99ed3fa 100644
--- a/hurd/default_pager_types.h
+++ b/hurd/default_pager_types.h
@@ -21,8 +21,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 #define _DEFAULT_PAGER_TYPES_H
 
 #include <mach/std_types.h>            /* For mach_port_t et al. */
+#include <mach/machine/vm_types.h>     /* For vm_size_t.  */
 #include <device/device_types.h>       /* For recnum_t.  */
 
 typedef recnum_t *recnum_array_t;
+typedef vm_size_t *vm_size_array_t;
 
 #endif
diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c
index 83382c0..5379795 100644
--- a/mach-defpager/default_pager.c
+++ b/mach-defpager/default_pager.c
@@ -164,6 +164,7 @@ new_partition (const char *name, struct file_direct *fdp,
        mach_msg_type_number_t rsize;
        int rc;
        unsigned int id = part_id(name);
+       unsigned int n = strlen(name);
 
        pthread_mutex_lock(&all_partitions.lock);
        {
@@ -185,6 +186,8 @@ new_partition (const char *name, struct file_direct *fdp,
 
        part = (partition_t) kalloc(sizeof(struct part));
        pthread_mutex_init(&part->p_lock, NULL);
+       part->name      = (char*) kalloc(n + 1);
+       strcpy(part->name, name);
        part->total_size = size;
        part->free      = size;
        part->id        = id;
@@ -333,6 +336,7 @@ new_partition (const char *name, struct file_direct *fdp,
                            name);
                    vm_deallocate(mach_task_self(), raddr, rsize);
                    kfree(part->bitmap, bmsize);
+                   kfree(part->name, strlen(part->name) + 1);
                    kfree(part, sizeof *part);
                    return 0;
                  }
@@ -384,6 +388,7 @@ new_partition (const char *name, struct file_direct *fdp,
                    "SKIPPING %s (%uk partition)!",
                    name, part->total_size * (vm_page_size / 1024));
            kfree(part->bitmap, bmsize);
+           kfree(part->name, strlen(part->name) + 1);
            kfree(part, sizeof *part);
            part = 0;
          }
@@ -1905,6 +1910,7 @@ dprintf("Partition x%x (id x%x) for %s, all_ok %d\n", 
part, id, name, all_ok);
                set_partition_of(pindex, 0);
                *pp_private = part->file;
                kfree(part->bitmap, howmany(part->total_size, NB_BM) * 
sizeof(bm_entry_t));
+               kfree(part->name, strlen(part->name) + 1);
                kfree(part, sizeof(struct part));
                dprintf("%s Removed paging partition %s\n", my_name, name);
                return KERN_SUCCESS;
@@ -3224,6 +3230,100 @@ S_default_pager_info (mach_port_t pager,
 }
 
 kern_return_t
+S_default_pager_storage_info (mach_port_t pager,
+                             vm_size_array_t *size,
+                             mach_msg_type_number_t *sizeCnt,
+                             vm_size_array_t *free,
+                             mach_msg_type_number_t *freeCnt,
+                             data_t *name,
+                             mach_msg_type_number_t *nameCnt)
+{
+       int             i, n, m;
+       int             len = 0;
+       char            *names;
+       kern_return_t   kr;
+       vm_offset_t     addr;
+       vm_size_array_t osize = *size;
+       vm_size_array_t ofree = *free;
+       data_t          oname = *name;
+
+       if (pager != default_pager_default_port)
+               return KERN_INVALID_ARGUMENT;
+
+       pthread_mutex_lock(&all_partitions.lock);
+
+       n = all_partitions.n_partitions;
+
+       len = 0;
+       m = 0;
+       for (i = 0; i < n; i++) {
+               partition_t part = partition_of(i);
+               if (part == 0)
+                       continue;
+               m++;
+               len += strlen(part->name) + 1;
+       }
+
+       if (*sizeCnt < m)
+       {
+               kr = vm_allocate(default_pager_self, &addr,
+                                round_page(m * sizeof(*size)), TRUE);
+               if (kr != KERN_SUCCESS);
+                       goto nomemory;
+               *size = (vm_size_array_t) addr;
+       }
+       *sizeCnt = m;
+
+       if (*freeCnt < m)
+       {
+               kr = vm_allocate(default_pager_self, &addr,
+                                round_page(m * sizeof(*free)), TRUE);
+               if (kr != KERN_SUCCESS);
+                       goto nomemory;
+               *free = (vm_size_array_t) addr;
+       }
+       *freeCnt = m;
+
+       if (*nameCnt < len)
+       {
+               kr = vm_allocate(default_pager_self, &addr,
+                                round_page(len), TRUE);
+               if (kr != KERN_SUCCESS);
+                       goto nomemory;
+               *name = (data_t) addr;
+       }
+       *nameCnt = len;
+
+       names = *name;
+       for (i = 0; i < n; i++) {
+               partition_t part = partition_of(i);
+               if (part == 0)
+                       continue;
+
+               (*size)[i] = ptoa(part->total_size);
+               (*free)[i] = ptoa(part->free);
+               names = stpcpy(names, part->name) + 1;
+       }
+
+       pthread_mutex_unlock(&all_partitions.lock);
+
+       return KERN_SUCCESS;
+
+nomemory:
+       pthread_mutex_unlock(&all_partitions.lock);
+       if (*size != osize)
+               (void) vm_deallocate(default_pager_self, (vm_offset_t) *size,
+                                    round_page(m * sizeof(*size)));
+       if (*free != ofree)
+               (void) vm_deallocate(default_pager_self, (vm_offset_t) *free,
+                                    round_page(m * sizeof(*free)));
+       if (*name != oname)
+               (void) vm_deallocate(default_pager_self, (vm_offset_t) *name,
+                                    len);
+       return KERN_RESOURCE_SHORTAGE;
+}
+
+kern_return_t
 S_default_pager_objects (mach_port_t pager,
                         default_pager_object_array_t *objectsp,
                         natural_t *ocountp,
diff --git a/mach-defpager/priv.h b/mach-defpager/priv.h
index 3684565..a884452 100644
--- a/mach-defpager/priv.h
+++ b/mach-defpager/priv.h
@@ -51,6 +51,7 @@ typedef unsigned int  bm_entry_t;
  */
 struct part {
        pthread_mutex_t p_lock;         /* for bitmap/free */
+       char            *name;          /* name */
        vm_size_t       total_size;     /* total number of blocks */
        vm_size_t       free;           /* number of blocks free */
        unsigned int    id;             /* named lookup */
diff --git a/procfs/Makefile b/procfs/Makefile
index 12fc9ee..13ee026 100644
--- a/procfs/Makefile
+++ b/procfs/Makefile
@@ -21,7 +21,7 @@ makemode := server
 
 target = procfs
 
-SRCS = procfs.c netfs.c procfs_dir.c process.c proclist.c rootdir.c dircat.c 
main.c mach_debugUser.c
+SRCS = procfs.c netfs.c procfs_dir.c process.c proclist.c rootdir.c dircat.c 
main.c mach_debugUser.c default_pagerUser.c
 LCLHDRS = dircat.h main.h process.h procfs.h procfs_dir.h proclist.h rootdir.h
 
 OBJS = $(SRCS:.c=.o)
diff --git a/procfs/rootdir.c b/procfs/rootdir.c
index 93fef8d..dd693c8 100644
--- a/procfs/rootdir.c
+++ b/procfs/rootdir.c
@@ -21,6 +21,7 @@
 #include <mach/vm_param.h>
 #include <mach/vm_statistics.h>
 #include <mach/vm_cache_statistics.h>
+#include "default_pager_U.h"
 #include <mach/default_pager.h>
 #include <mach_debug/mach_debug_types.h>
 #include <hurd/paths.h>
@@ -521,6 +522,56 @@ rootdir_gc_filesystems (void *hook, char **contents, 
ssize_t *contents_len)
   fclose (m);
   return err;
 }
+
+static error_t
+rootdir_gc_swaps (void *hook, char **contents, ssize_t *contents_len)
+{
+  mach_port_t defpager;
+  error_t err = 0;
+  FILE *m;
+  vm_size_t *free = NULL;
+  size_t nfree = 0;
+  vm_size_t *size = NULL;
+  size_t nsize = 0;
+  char *names = NULL, *name;
+  size_t names_len = 0;
+  size_t i;
+
+  m = open_memstream (contents, (size_t *) contents_len);
+  if (m == NULL)
+    return errno;
+
+  defpager = file_name_lookup (_SERVERS_DEFPAGER, O_READ, 0);
+  if (defpager == MACH_PORT_NULL)
+    {
+      err = errno;
+      goto out_fclose;
+    }
+
+  err = default_pager_storage_info (defpager, &free, &nfree, &size, &nsize,
+                                   &names, &names_len);
+  if (err)
+    goto out;
+
+  fprintf(m, "Filename\tType\t\tSize\tUsed\tPriority\n");
+  name = names;
+  for (i = 0; i < nfree; i++)
+    {
+      fprintf (m, "/dev/%s\tpartition\t%zu\t%zu\t-1\n",
+              name, size[i] >> 10, (size[i] - free[i]) >> 10);
+      name = argz_next (names, names_len, name);
+    }
+
+  vm_deallocate (mach_task_self(), (vm_offset_t) free, nfree * sizeof(*free));
+  vm_deallocate (mach_task_self(), (vm_offset_t) size, nsize * sizeof(*size));
+  vm_deallocate (mach_task_self(), (vm_offset_t) names, names_len);
+
+out:
+  mach_port_deallocate (mach_task_self (), defpager);
+out_fclose:
+  fclose (m);
+  return err;
+}
 
 /* Glue logic and entries table */
 
@@ -703,6 +754,13 @@ static const struct procfs_dir_entry rootdir_entries[] = {
       .cleanup_contents = procfs_cleanup_contents_with_free,
     },
   },
+  {
+    .name = "swaps",
+    .hook = & (struct procfs_node_ops) {
+      .get_contents = rootdir_gc_swaps,
+      .cleanup_contents = procfs_cleanup_contents_with_free,
+    },
+  },
 #ifdef PROFILE
   /* In order to get a usable gmon.out file, we must apparently use exit(). */
   {
diff --git a/sutils/swapon.c b/sutils/swapon.c
index 2403f1c..ae830ba 100644
--- a/sutils/swapon.c
+++ b/sutils/swapon.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <argp.h>
+#include <argz.h>
 #include <error.h>
 #include <assert.h>
 #include <sys/mman.h>
@@ -42,7 +43,7 @@ const char *argp_program_version = STANDARD_HURD_VERSION 
(swapoff);
 const char *argp_program_version = STANDARD_HURD_VERSION (swapon);
 #endif
 
-static int ignore_signature, require_signature, quiet, ifexists;
+static int ignore_signature, require_signature, show, quiet, ifexists;
 
 static struct argp_option options[] =
 {
@@ -54,6 +55,8 @@ static struct argp_option options[] =
    "Do not check for a Linux swap signature page"},
   {"require-signature", 's', 0, 0,
    "Require a Linux swap signature page"},
+  {"show", 'S', 0, 0,
+   "Show devices currently in use"},
   {"silent",     'q', 0,      0, "Print only diagnostic messages"},
   {"quiet",      'q', 0,      OPTION_ALIAS | OPTION_HIDDEN },
   {"verbose",    'v', 0,      0, "Be verbose"},
@@ -81,6 +84,39 @@ static char *doc =
      verbose ("%s: Linux 2.2 swap signature v1, %zuk swap-space" fmt, \
              name, freepages * (LINUX_PAGE_SIZE / 1024) ,##arg)
 
+
+static mach_port_t def_pager = MACH_PORT_NULL;
+static mach_port_t dev_master = MACH_PORT_NULL;
+
+static void get_def_pager(void)
+{
+  int err;
+  mach_port_t host;
+
+  if (def_pager != MACH_PORT_NULL)
+    return;
+
+  err = get_privileged_ports (&host, &dev_master);
+  if (err == EPERM)
+    {
+      /* We are not root, so try opening the /servers node.  */
+      def_pager = file_name_lookup (_SERVERS_DEFPAGER, O_WRITE, 0);
+      if (def_pager == MACH_PORT_NULL)
+         error (11, errno, _SERVERS_DEFPAGER);
+    }
+  else
+    {
+      if (err)
+       error (12, err, "Cannot get privileged ports");
+
+      err = vm_set_default_memory_manager (host, &def_pager);
+      mach_port_deallocate (mach_task_self (), host);
+      if (err)
+       error (13, err, "Cannot get default pager port");
+      if (def_pager == MACH_PORT_NULL)
+       error (14, 0, "No default pager (memory manager) is running!");
+    }
+}
 
 /* Examine the store in *STOREP to see if it has a Linux-compatible
    swap signature page as created by the Linux `mkswap' utility.  If
@@ -326,8 +362,6 @@ swaponoff (const char *file, int add, int skipnotexisting)
 {
   error_t err;
   struct store *store;
-  static mach_port_t def_pager = MACH_PORT_NULL;
-  static mach_port_t dev_master = MACH_PORT_NULL;
   static int old_protocol;
   int quiet_now = 0;
 
@@ -384,34 +418,7 @@ swaponoff (const char *file, int add, int skipnotexisting)
       return EINVAL;
     }
 
-  if (def_pager == MACH_PORT_NULL)
-    {
-      mach_port_t host;
-
-      err = get_privileged_ports (&host, &dev_master);
-      if (err == EPERM)
-       {
-         /* We are not root, so try opening the /servers node.  */
-         def_pager = file_name_lookup (_SERVERS_DEFPAGER, O_WRITE, 0);
-         if (def_pager == MACH_PORT_NULL)
-           {
-             error (11, errno, _SERVERS_DEFPAGER);
-             return 0;
-           }
-       }
-      else
-       {
-         if (err)
-           error (12, err, "Cannot get privileged ports");
-
-         err = vm_set_default_memory_manager (host, &def_pager);
-         mach_port_deallocate (mach_task_self (), host);
-         if (err)
-           error (13, err, "Cannot get default pager port");
-         if (def_pager == MACH_PORT_NULL)
-           error (14, 0, "No default pager (memory manager) is running!");
-       }
-    }
+  get_def_pager();
 
   if (old_protocol)
     {
@@ -487,6 +494,10 @@ main (int argc, char *argv[])
          ignore_signature = 0;
          break;
 
+       case 'S':
+         show = 1;
+         break;
+
        case 'q':
          quiet = 1;
          break;
@@ -547,5 +558,39 @@ main (int argc, char *argv[])
        }
     }
 
+  if (show)
+    {
+      vm_size_t *free = NULL;
+      size_t nfree = 0;
+      vm_size_t *size = NULL;
+      size_t nsize = 0;
+      char *names = NULL, *name;
+      size_t names_len = 0;
+      size_t i;
+      int err;
+
+      get_def_pager();
+
+      err = default_pager_storage_info (def_pager, &free, &nfree, &size, 
&nsize,
+                                       &names, &names_len);
+      if (err)
+       error (3, 0, "Can not get default pager storage information");
+
+      printf("Filename\tType\t\tSize\tUsed\tPriority\n");
+      name = names;
+      for (i = 0; i < nfree; i++)
+       {
+         printf ("/dev/%s\tpartition\t%zuM\t%zuM\t-1\n",
+                 name, size[i] >> 20, (size[i] - free[i]) >> 20);
+         name = argz_next (names, names_len, name);
+       }
+
+      vm_deallocate (mach_task_self(), (vm_offset_t) free,
+                    nfree * sizeof(*free));
+      vm_deallocate (mach_task_self(), (vm_offset_t) size,
+                    nsize * sizeof(*size));
+      vm_deallocate (mach_task_self(), (vm_offset_t) names, names_len);
+    }
+
   return 0;
 }
diff --git a/trans/proxy-defpager.c b/trans/proxy-defpager.c
index 4fdeb35..9a8436a 100644
--- a/trans/proxy-defpager.c
+++ b/trans/proxy-defpager.c
@@ -64,6 +64,19 @@ S_default_pager_info (mach_port_t default_pager, 
default_pager_info_t *info)
 }
 
 kern_return_t
+S_default_pager_storage_info (mach_port_t default_pager,
+                             vm_size_array_t *size,
+                             mach_msg_type_number_t *sizeCnt,
+                             vm_size_array_t *free,
+                             mach_msg_type_number_t *freeCnt,
+                             data_t *name,
+                             mach_msg_type_number_t *nameCnt)
+{
+  return allowed (default_pager, O_READ)
+    ?: default_pager_storage_info (real_defpager, size, sizeCnt, free, 
freeCnt, name, nameCnt);
+}
+
+kern_return_t
 S_default_pager_objects (mach_port_t default_pager,
                         default_pager_object_array_t *objects,
                         mach_msg_type_number_t *objectsCnt,

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]