summaryrefslogtreecommitdiff
path: root/mach-defpager
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2016-03-16 01:48:40 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2016-03-16 01:48:40 +0100
commit4f51b0e104481fb6d337140eeaa51af8c674d236 (patch)
tree452aacaf7f586e2ccd22bda15a92419d9616065b /mach-defpager
parent0bc52ecb504401e089e1aa335c56e0c5db6d8e32 (diff)
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.
Diffstat (limited to 'mach-defpager')
-rw-r--r--mach-defpager/default_pager.c100
-rw-r--r--mach-defpager/priv.h1
2 files changed, 101 insertions, 0 deletions
diff --git a/mach-defpager/default_pager.c b/mach-defpager/default_pager.c
index 83382c05..53797958 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 36845657..a8844521 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 */