From 6f2296c5ac808a50ca336b43235f91a9fc02347f Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Mon, 22 Sep 2014 11:23:52 +0200 Subject: new procfs patch series --- .../procfs-0001-procfs-implement-proc-N-maps.patch | 143 ++++++++++++++++ ...fs-0002-procfs-implement-proc-filesystems.patch | 105 ++++++++++++ ...rocfs-0003-procfs-implement-proc-N-mounts.patch | 67 ++++++++ ...ocfs-do-not-test-whether-hurd-mtab-exists.patch | 45 +++++ ...fs-generalize-the-translator-linkage-code.patch | 141 ++++++++++++++++ .../procfs-0006-procfs-reorganize-rootdir.c.patch | 187 +++++++++++++++++++++ ...rovide-magic-retry-response-for-proc-self.patch | 177 +++++++++++++++++++ debian/patches/procfs-filesystems.patch | 105 ------------ debian/patches/procfs-maps.patch | 143 ---------------- debian/patches/series | 10 +- 10 files changed, 873 insertions(+), 250 deletions(-) create mode 100644 debian/patches/procfs-0001-procfs-implement-proc-N-maps.patch create mode 100644 debian/patches/procfs-0002-procfs-implement-proc-filesystems.patch create mode 100644 debian/patches/procfs-0003-procfs-implement-proc-N-mounts.patch create mode 100644 debian/patches/procfs-0004-procfs-do-not-test-whether-hurd-mtab-exists.patch create mode 100644 debian/patches/procfs-0005-procfs-generalize-the-translator-linkage-code.patch create mode 100644 debian/patches/procfs-0006-procfs-reorganize-rootdir.c.patch create mode 100644 debian/patches/procfs-0007-procfs-provide-magic-retry-response-for-proc-self.patch delete mode 100644 debian/patches/procfs-filesystems.patch delete mode 100644 debian/patches/procfs-maps.patch (limited to 'debian') diff --git a/debian/patches/procfs-0001-procfs-implement-proc-N-maps.patch b/debian/patches/procfs-0001-procfs-implement-proc-N-maps.patch new file mode 100644 index 00000000..ff3dc5bb --- /dev/null +++ b/debian/patches/procfs-0001-procfs-implement-proc-N-maps.patch @@ -0,0 +1,143 @@ +From 77c514cb7d3dd577576df13353b350052c37003a Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Thu, 18 Sep 2014 18:38:04 +0200 +Subject: [PATCH 1/7] procfs: implement /proc/N/maps + +Fixes https://savannah.gnu.org/bugs/?32770 . + +* procfs/process.c (process_file_gc_maps): New function. +(entries): Use the new function to implement /proc/N/maps. +--- + procfs/process.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 103 insertions(+), 1 deletion(-) + +diff --git a/procfs/process.c b/procfs/process.c +index 4854148..a9b1a59 100644 +--- a/procfs/process.c ++++ b/procfs/process.c +@@ -1,5 +1,5 @@ + /* Hurd /proc filesystem, implementation of process directories. +- Copyright (C) 2010 Free Software Foundation, Inc. ++ Copyright (C) 2010,14 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -109,6 +109,100 @@ process_file_gc_environ (struct proc_stat *ps, char **contents) + } + + static ssize_t ++process_file_gc_maps (struct proc_stat *ps, char **contents) ++{ ++ error_t err; ++ FILE *s; ++ size_t contents_len; ++ vm_offset_t addr = 0; ++ vm_size_t size; ++ vm_prot_t prot, max_prot; ++ mach_port_t obj; ++ vm_offset_t offs; ++ vm_inherit_t inh; ++ int shared; ++ ++ /* Unfortunately we cannot resolve memory objects to their backing ++ file (yet), so we use the port name as identifier. To avoid the ++ same name from being used again and again, we defer the ++ deallocation until the end of the function. We use a simple ++ linked list for this purpose. */ ++ struct mem_obj ++ { ++ mach_port_t port; ++ struct mem_obj *next; ++ }; ++ struct mem_obj *objects = NULL; ++ ++ s = open_memstream (contents, &contents_len); ++ if (s == NULL) ++ { ++ *contents = NULL; ++ return 0; ++ } ++ ++ while (1) ++ { ++ err = ++ vm_region (ps->task, &addr, &size, &prot, &max_prot, &inh, ++ &shared, &obj, &offs); ++ if (err) ++ break; ++ ++ fprintf (s, "%0*x-%0*x %c%c%c%c %0*x %s %d ", ++ /* Address range. */ ++ 2*sizeof s, addr, ++ 2*sizeof s, addr + size, ++ /* Permissions. */ ++ prot & VM_PROT_READ? 'r': '-', ++ prot & VM_PROT_WRITE? 'w': '-', ++ prot & VM_PROT_EXECUTE? 'x': '-', ++ shared? 's': 'p', ++ /* Offset. */ ++ 2*sizeof s, offs, ++ /* Device. */ ++ "00:00", ++ /* Inode. */ ++ 0); ++ ++ /* Pathname. */ ++ if (MACH_PORT_VALID (obj)) ++ { ++ struct mem_obj *o = malloc (sizeof *o); ++ if (o) ++ { ++ o->port = obj; ++ o->next = objects; ++ objects = o; ++ } ++ else ++ mach_port_deallocate (mach_task_self (), obj); ++ ++ fprintf (s, "[mem_obj=%d]\n", obj); ++ } ++ else ++ fprintf (s, "\n"); ++ ++ addr += size; ++ } ++ ++ while (objects) ++ { ++ struct mem_obj *o = objects; ++ mach_port_deallocate (mach_task_self (), o->port); ++ objects = o->next; ++ free (o); ++ } ++ ++ /* This is a bit awkward, fortunately vm_region should not fail. */ ++ if (err != KERN_NO_SPACE) ++ fprintf (s, "%s\n", strerror (err)); ++ ++ fclose (s); ++ return contents_len; ++} ++ ++static ssize_t + process_file_gc_stat (struct proc_stat *ps, char **contents) + { + struct procinfo *pi = proc_stat_proc_info (ps); +@@ -348,6 +442,14 @@ static struct procfs_dir_entry entries[] = { + }, + }, + { ++ .name = "maps", ++ .hook = & (struct process_file_desc) { ++ .get_contents = process_file_gc_maps, ++ .needs = PSTAT_TASK, ++ .mode = 0400, ++ }, ++ }, ++ { + .name = "stat", + .hook = & (struct process_file_desc) { + .get_contents = process_file_gc_stat, +-- +2.1.0 + diff --git a/debian/patches/procfs-0002-procfs-implement-proc-filesystems.patch b/debian/patches/procfs-0002-procfs-implement-proc-filesystems.patch new file mode 100644 index 00000000..b2f0bfe3 --- /dev/null +++ b/debian/patches/procfs-0002-procfs-implement-proc-filesystems.patch @@ -0,0 +1,105 @@ +From b3fcc07220f528889f00a08e40f9a801afc6f6bb Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Thu, 18 Sep 2014 19:38:04 +0200 +Subject: [PATCH 2/7] procfs: implement /proc/filesystems + +* procfs/rootdir.c (rootdir_gc_filesystems): New function. +(rootdir_entries): Use the new function to implement /proc/filesystems. +--- + procfs/rootdir.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 60 insertions(+), 1 deletion(-) + +diff --git a/procfs/rootdir.c b/procfs/rootdir.c +index 9541059..f92e73d 100644 +--- a/procfs/rootdir.c ++++ b/procfs/rootdir.c +@@ -1,5 +1,5 @@ + /* Hurd /proc filesystem, permanent files of the root directory. +- Copyright (C) 2010,13 Free Software Foundation, Inc. ++ Copyright (C) 2010,13,14 Free Software Foundation, Inc. + + This file is part of the GNU Hurd. + +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include "procfs.h" + #include "procfs_dir.h" + #include "main.h" +@@ -532,6 +533,57 @@ rootdir_gc_slabinfo (void *hook, char **contents, ssize_t *contents_len) + cache_info, cache_info_count * sizeof *cache_info); + return err; + } ++ ++static error_t ++rootdir_gc_filesystems (void *hook, char **contents, ssize_t *contents_len) ++{ ++ error_t err = 0; ++ size_t i; ++ int glob_ret; ++ glob_t matches; ++ FILE *m; ++ ++ m = open_memstream (contents, contents_len); ++ if (m == NULL) ++ return errno; ++ ++ glob_ret = glob (_HURD "*fs", 0, NULL, &matches); ++ switch (glob_ret) ++ { ++ case 0: ++ for (i = 0; i < matches.gl_pathc; i++) ++ { ++ /* Get ith entry, shave off the prefix. */ ++ char *name = &matches.gl_pathv[i][sizeof _HURD - 1]; ++ ++ /* Linux naming convention is a bit inconsistent. */ ++ if (strncmp (name, "ext", 3) == 0 ++ || strcmp (name, "procfs") == 0) ++ /* Drop the fs suffix. */ ++ name[strlen (name) - 2] = 0; ++ ++ fprintf (m, "\t%s\n", name); ++ } ++ ++ globfree (&matches); ++ break; ++ ++ case GLOB_NOMATCH: ++ /* Poor fellow. */ ++ break; ++ ++ case GLOB_NOSPACE: ++ err = ENOMEM; ++ break; ++ ++ default: ++ /* This should not happen. */ ++ err = EGRATUITOUS; ++ } ++ ++ fclose (m); ++ return err; ++} + + /* Glue logic and entries table */ + +@@ -632,6 +684,13 @@ static const struct procfs_dir_entry rootdir_entries[] = { + .cleanup_contents = procfs_cleanup_contents_with_free, + }, + }, ++ { ++ .name = "filesystems", ++ .hook = & (struct procfs_node_ops) { ++ .get_contents = rootdir_gc_filesystems, ++ .cleanup_contents = procfs_cleanup_contents_with_free, ++ }, ++ }, + #ifdef PROFILE + /* In order to get a usable gmon.out file, we must apparently use exit(). */ + { +-- +2.1.0 + diff --git a/debian/patches/procfs-0003-procfs-implement-proc-N-mounts.patch b/debian/patches/procfs-0003-procfs-implement-proc-N-mounts.patch new file mode 100644 index 00000000..45decfeb --- /dev/null +++ b/debian/patches/procfs-0003-procfs-implement-proc-N-mounts.patch @@ -0,0 +1,67 @@ +From 815204e71cde5b6c6e09edd8e46337f264206908 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Fri, 19 Sep 2014 07:54:04 +0200 +Subject: [PATCH 3/7] procfs: implement /proc/N/mounts + +* procfs/process.c (process_gc_mounts): New function. +(process_symlink_make_node): Likewise. +(entries): Use the new functions to provide a symlink to ../mounts. +--- + procfs/process.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/procfs/process.c b/procfs/process.c +index a9b1a59..f5da0d2 100644 +--- a/procfs/process.c ++++ b/procfs/process.c +@@ -202,6 +202,16 @@ process_file_gc_maps (struct proc_stat *ps, char **contents) + return contents_len; + } + ++static error_t ++process_gc_mounts (void *hook, char **contents, ssize_t *contents_len) ++{ ++#define MOUNTSLINK "../mounts" ++ *contents = MOUNTSLINK; ++ *contents_len = sizeof MOUNTSLINK - 1; ++#undef MOUNTSLINK ++ return 0; ++} ++ + static ssize_t + process_file_gc_stat (struct proc_stat *ps, char **contents) + { +@@ -420,6 +430,14 @@ process_stat_make_node (void *dir_hook, const void *entry_hook) + return np; + } + ++static struct node * ++process_symlink_make_node (void *dir_hook, const void *entry_hook) ++{ ++ struct node *np = procfs_make_node (entry_hook, dir_hook); ++ if (np) ++ procfs_node_chtype (np, S_IFLNK); ++ return np; ++} + + /* Implementation of the process directory per se. */ + +@@ -450,6 +468,15 @@ static struct procfs_dir_entry entries[] = { + }, + }, + { ++ .name = "mounts", ++ .hook = & (struct procfs_node_ops) { ++ .get_contents = process_gc_mounts, ++ }, ++ .ops = { ++ .make_node = process_symlink_make_node, ++ }, ++ }, ++ { + .name = "stat", + .hook = & (struct process_file_desc) { + .get_contents = process_file_gc_stat, +-- +2.1.0 + diff --git a/debian/patches/procfs-0004-procfs-do-not-test-whether-hurd-mtab-exists.patch b/debian/patches/procfs-0004-procfs-do-not-test-whether-hurd-mtab-exists.patch new file mode 100644 index 00000000..97577ec6 --- /dev/null +++ b/debian/patches/procfs-0004-procfs-do-not-test-whether-hurd-mtab-exists.patch @@ -0,0 +1,45 @@ +From cf724544bb644bf081d7a83524ca6ac25ed198f1 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Fri, 19 Sep 2014 08:18:33 +0200 +Subject: [PATCH 4/7] procfs: do not test whether /hurd/mtab exists + +Now that procfs is merged into the Hurd repository we can just assume +that the mtab translator exists. + +* procfs/rootdir.c (rootdir_mounts_exists): Drop function. +(rootdir_entries): Adjust accordingly. +--- + procfs/rootdir.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/procfs/rootdir.c b/procfs/rootdir.c +index f92e73d..81e36f7 100644 +--- a/procfs/rootdir.c ++++ b/procfs/rootdir.c +@@ -463,15 +463,6 @@ rootdir_mounts_get_translator (void *hook, char **argz, size_t *argz_len) + return 0; + } + +-static int +-rootdir_mounts_exists (void *dir_hook, const void *entry_hook) +-{ +- static int translator_exists = -1; +- if (translator_exists == -1) +- translator_exists = access (_HURD_MTAB, F_OK|X_OK) == 0; +- return translator_exists; +-} +- + static error_t + rootdir_gc_slabinfo (void *hook, char **contents, ssize_t *contents_len) + { +@@ -674,7 +665,6 @@ static const struct procfs_dir_entry rootdir_entries[] = { + }, + .ops = { + .make_node = rootdir_mounts_make_node, +- .exists = rootdir_mounts_exists, + } + }, + { +-- +2.1.0 + diff --git a/debian/patches/procfs-0005-procfs-generalize-the-translator-linkage-code.patch b/debian/patches/procfs-0005-procfs-generalize-the-translator-linkage-code.patch new file mode 100644 index 00000000..7233bf64 --- /dev/null +++ b/debian/patches/procfs-0005-procfs-generalize-the-translator-linkage-code.patch @@ -0,0 +1,141 @@ +From 5bc2ea2e6377e0f5f0d341ce0631da70669b9ceb Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Fri, 19 Sep 2014 10:01:57 +0200 +Subject: [PATCH 5/7] procfs: generalize the translator linkage code + +Generalize the translator linkage code previously introduced for the +`mounts' node. + +* procfs/rootdir.c (struct procfs_translated_node_ops): New +specialized node operations structure for translated nodes. +(rootdir_mounts_make_node): Generalize and rename to +rootdir_make_translated_node. Also, pass the entry_hook to +procfs_make_node so that... +(rootdir_mounts_get_translator): ... can be generalized to +rootdir_translated_node_get_translator and read the argz vector from +the hooked structure. +(ROOTDIR_DEFINE_TRANSLATED_NODE): New convenience macro to define +translated nodes. +(rootdir_entries): Use the new code for the `mounts' node. +--- + procfs/rootdir.c | 62 ++++++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 42 insertions(+), 20 deletions(-) + +diff --git a/procfs/rootdir.c b/procfs/rootdir.c +index 81e36f7..a04fb3e 100644 +--- a/procfs/rootdir.c ++++ b/procfs/rootdir.c +@@ -409,17 +409,29 @@ rootdir_gc_fakeself (void *hook, char **contents, ssize_t *contents_len) + } + + static struct node *rootdir_mounts_node; +-static pthread_spinlock_t rootdir_mounts_node_lock = ++ ++/* Translator linkage. */ ++static pthread_spinlock_t rootdir_translated_node_lock = + PTHREAD_SPINLOCK_INITIALIZER; + ++struct procfs_translated_node_ops ++{ ++ struct procfs_node_ops node_ops; ++ ++ struct node **npp; ++ char *argz; ++ size_t argz_len; ++}; ++ + static struct node * +-rootdir_mounts_make_node (void *dir_hook, const void *entry_hook) ++rootdir_make_translated_node (void *dir_hook, const void *entry_hook) + { ++ const struct procfs_translated_node_ops *ops = entry_hook; + struct node *np, *prev; + +- pthread_spin_lock (&rootdir_mounts_node_lock); +- np = rootdir_mounts_node; +- pthread_spin_unlock (&rootdir_mounts_node_lock); ++ pthread_spin_lock (&rootdir_translated_node_lock); ++ np = *ops->npp; ++ pthread_spin_unlock (&rootdir_translated_node_lock); + + if (np != NULL) + { +@@ -427,18 +439,18 @@ rootdir_mounts_make_node (void *dir_hook, const void *entry_hook) + return np; + } + +- np = procfs_make_node (entry_hook, dir_hook); ++ np = procfs_make_node (entry_hook, entry_hook); + if (np == NULL) + return NULL; + + procfs_node_chtype (np, S_IFREG | S_IPTRANS); + procfs_node_chmod (np, 0444); + +- pthread_spin_lock (&rootdir_mounts_node_lock); +- prev = rootdir_mounts_node; +- if (rootdir_mounts_node == NULL) +- rootdir_mounts_node = np; +- pthread_spin_unlock (&rootdir_mounts_node_lock); ++ pthread_spin_lock (&rootdir_translated_node_lock); ++ prev = *ops->npp; ++ if (*ops->npp == NULL) ++ *ops->npp = np; ++ pthread_spin_unlock (&rootdir_translated_node_lock); + + if (prev != NULL) + { +@@ -450,19 +462,30 @@ rootdir_mounts_make_node (void *dir_hook, const void *entry_hook) + } + + static error_t +-rootdir_mounts_get_translator (void *hook, char **argz, size_t *argz_len) ++rootdir_translated_node_get_translator (void *hook, char **argz, ++ size_t *argz_len) + { +- static const char const mtab_argz[] = _HURD_MTAB "\0/"; ++ const struct procfs_translated_node_ops *ops = hook; + +- *argz = malloc (sizeof mtab_argz); ++ *argz = malloc (ops->argz_len); + if (! *argz) + return ENOMEM; + +- memcpy (*argz, mtab_argz, sizeof mtab_argz); +- *argz_len = sizeof mtab_argz; ++ memcpy (*argz, ops->argz, ops->argz_len); ++ *argz_len = ops->argz_len; + return 0; + } + ++#define ROOTDIR_DEFINE_TRANSLATED_NODE(NPP, ARGZ) \ ++ &(struct procfs_translated_node_ops) { \ ++ .node_ops = { \ ++ .get_translator = rootdir_translated_node_get_translator, \ ++ }, \ ++ .npp = NPP, \ ++ .argz = (ARGZ), \ ++ .argz_len = sizeof (ARGZ), \ ++ } ++ + static error_t + rootdir_gc_slabinfo (void *hook, char **contents, ssize_t *contents_len) + { +@@ -660,11 +683,10 @@ static const struct procfs_dir_entry rootdir_entries[] = { + }, + { + .name = "mounts", +- .hook = & (struct procfs_node_ops) { +- .get_translator = rootdir_mounts_get_translator, +- }, ++ .hook = ROOTDIR_DEFINE_TRANSLATED_NODE (&rootdir_mounts_node, ++ _HURD_MTAB "\0/"), + .ops = { +- .make_node = rootdir_mounts_make_node, ++ .make_node = rootdir_make_translated_node, + } + }, + { +-- +2.1.0 + diff --git a/debian/patches/procfs-0006-procfs-reorganize-rootdir.c.patch b/debian/patches/procfs-0006-procfs-reorganize-rootdir.c.patch new file mode 100644 index 00000000..34ffc9bc --- /dev/null +++ b/debian/patches/procfs-0006-procfs-reorganize-rootdir.c.patch @@ -0,0 +1,187 @@ +From 57cc10fd45bec12e61a783e5ccced10be956483a Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Fri, 19 Sep 2014 10:10:24 +0200 +Subject: [PATCH 6/7] procfs: reorganize rootdir.c + +* procfs/rootdir.c: Move the translator linkage code to the +appropriate location. +--- + procfs/rootdir.c | 153 ++++++++++++++++++++++++++++--------------------------- + 1 file changed, 77 insertions(+), 76 deletions(-) + +diff --git a/procfs/rootdir.c b/procfs/rootdir.c +index a04fb3e..d68645e 100644 +--- a/procfs/rootdir.c ++++ b/procfs/rootdir.c +@@ -409,83 +409,7 @@ rootdir_gc_fakeself (void *hook, char **contents, ssize_t *contents_len) + } + + static struct node *rootdir_mounts_node; +- +-/* Translator linkage. */ +-static pthread_spinlock_t rootdir_translated_node_lock = +- PTHREAD_SPINLOCK_INITIALIZER; +- +-struct procfs_translated_node_ops +-{ +- struct procfs_node_ops node_ops; +- +- struct node **npp; +- char *argz; +- size_t argz_len; +-}; +- +-static struct node * +-rootdir_make_translated_node (void *dir_hook, const void *entry_hook) +-{ +- const struct procfs_translated_node_ops *ops = entry_hook; +- struct node *np, *prev; + +- pthread_spin_lock (&rootdir_translated_node_lock); +- np = *ops->npp; +- pthread_spin_unlock (&rootdir_translated_node_lock); +- +- if (np != NULL) +- { +- netfs_nref (np); +- return np; +- } +- +- np = procfs_make_node (entry_hook, entry_hook); +- if (np == NULL) +- return NULL; +- +- procfs_node_chtype (np, S_IFREG | S_IPTRANS); +- procfs_node_chmod (np, 0444); +- +- pthread_spin_lock (&rootdir_translated_node_lock); +- prev = *ops->npp; +- if (*ops->npp == NULL) +- *ops->npp = np; +- pthread_spin_unlock (&rootdir_translated_node_lock); +- +- if (prev != NULL) +- { +- procfs_cleanup (np); +- np = prev; +- } +- +- return np; +-} +- +-static error_t +-rootdir_translated_node_get_translator (void *hook, char **argz, +- size_t *argz_len) +-{ +- const struct procfs_translated_node_ops *ops = hook; +- +- *argz = malloc (ops->argz_len); +- if (! *argz) +- return ENOMEM; +- +- memcpy (*argz, ops->argz, ops->argz_len); +- *argz_len = ops->argz_len; +- return 0; +-} +- +-#define ROOTDIR_DEFINE_TRANSLATED_NODE(NPP, ARGZ) \ +- &(struct procfs_translated_node_ops) { \ +- .node_ops = { \ +- .get_translator = rootdir_translated_node_get_translator, \ +- }, \ +- .npp = NPP, \ +- .argz = (ARGZ), \ +- .argz_len = sizeof (ARGZ), \ +- } +- + static error_t + rootdir_gc_slabinfo (void *hook, char **contents, ssize_t *contents_len) + { +@@ -619,7 +543,84 @@ rootdir_symlink_make_node (void *dir_hook, const void *entry_hook) + procfs_node_chtype (np, S_IFLNK); + return np; + } ++ ++/* Translator linkage. */ ++ ++static pthread_spinlock_t rootdir_translated_node_lock = ++ PTHREAD_SPINLOCK_INITIALIZER; ++ ++struct procfs_translated_node_ops ++{ ++ struct procfs_node_ops node_ops; ++ ++ struct node **npp; ++ char *argz; ++ size_t argz_len; ++}; ++ ++static struct node * ++rootdir_make_translated_node (void *dir_hook, const void *entry_hook) ++{ ++ const struct procfs_translated_node_ops *ops = entry_hook; ++ struct node *np, *prev; ++ ++ pthread_spin_lock (&rootdir_translated_node_lock); ++ np = *ops->npp; ++ pthread_spin_unlock (&rootdir_translated_node_lock); ++ ++ if (np != NULL) ++ { ++ netfs_nref (np); ++ return np; ++ } ++ ++ np = procfs_make_node (entry_hook, entry_hook); ++ if (np == NULL) ++ return NULL; ++ ++ procfs_node_chtype (np, S_IFREG | S_IPTRANS); ++ procfs_node_chmod (np, 0444); ++ ++ pthread_spin_lock (&rootdir_translated_node_lock); ++ prev = *ops->npp; ++ if (*ops->npp == NULL) ++ *ops->npp = np; ++ pthread_spin_unlock (&rootdir_translated_node_lock); ++ ++ if (prev != NULL) ++ { ++ procfs_cleanup (np); ++ np = prev; ++ } ++ ++ return np; ++} ++ ++static error_t ++rootdir_translated_node_get_translator (void *hook, char **argz, ++ size_t *argz_len) ++{ ++ const struct procfs_translated_node_ops *ops = hook; + ++ *argz = malloc (ops->argz_len); ++ if (! *argz) ++ return ENOMEM; ++ ++ memcpy (*argz, ops->argz, ops->argz_len); ++ *argz_len = ops->argz_len; ++ return 0; ++} ++ ++#define ROOTDIR_DEFINE_TRANSLATED_NODE(NPP, ARGZ) \ ++ &(struct procfs_translated_node_ops) { \ ++ .node_ops = { \ ++ .get_translator = rootdir_translated_node_get_translator, \ ++ }, \ ++ .npp = NPP, \ ++ .argz = (ARGZ), \ ++ .argz_len = sizeof (ARGZ), \ ++ } ++ + static const struct procfs_dir_entry rootdir_entries[] = { + { + .name = "self", +-- +2.1.0 + diff --git a/debian/patches/procfs-0007-procfs-provide-magic-retry-response-for-proc-self.patch b/debian/patches/procfs-0007-procfs-provide-magic-retry-response-for-proc-self.patch new file mode 100644 index 00000000..74b0bc97 --- /dev/null +++ b/debian/patches/procfs-0007-procfs-provide-magic-retry-response-for-proc-self.patch @@ -0,0 +1,177 @@ +From bb245976b92068ca5239b5b860aa4dbfd70b44a5 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Sun, 21 Sep 2014 12:03:47 +0200 +Subject: [PATCH 7/7] procfs: provide magic retry response for /proc/self + +* hurd/hurd_types.h: Document the magic retry string `proc/self'. +* hurd/paths.h (_HURD_MAGIC): New macro. +* procfs/main.c: Remove all code related to faking /proc/self. +* procfs/main.h: Likewise. +* procfs/rootdir.c: Likewise. Instead, return the magic retry +response `proc/self' for the `self' node. +--- + hurd/hurd_types.h | 3 +++ + hurd/paths.h | 1 + + procfs/main.c | 24 ------------------------ + procfs/main.h | 1 - + procfs/rootdir.c | 23 ++++------------------- + 5 files changed, 8 insertions(+), 44 deletions(-) + +diff --git a/hurd/hurd_types.h b/hurd/hurd_types.h +index 4341177..f22816d 100644 +--- a/hurd/hurd_types.h ++++ b/hurd/hurd_types.h +@@ -114,6 +114,9 @@ enum retry_type + as for FS_RETRY_NORMAL. + + "/..." means retry "...", but starting from the users root directory. ++ ++ "proc/self/..." means replace `proc/self' with the PID of the current ++ process and then retry as for FS_RETRY_NORMAL. + */ + }; + typedef enum retry_type retry_type; +diff --git a/hurd/paths.h b/hurd/paths.h +index 92875b2..32bc2b4 100644 +--- a/hurd/paths.h ++++ b/hurd/paths.h +@@ -53,6 +53,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + #define _HURD_IFSOCK _HURD "ifsock" /* S_IFSOCK */ + + /* Symbolic names for all non-essential translators. */ ++#define _HURD_MAGIC _HURD "magic" + #define _HURD_MTAB _HURD "mtab" + + #endif /* hurd/paths.h */ +diff --git a/procfs/main.c b/procfs/main.c +index 54e9682..1afc923 100644 +--- a/procfs/main.c ++++ b/procfs/main.c +@@ -34,14 +34,12 @@ + /* Command-line options */ + int opt_clk_tck; + mode_t opt_stat_mode; +-pid_t opt_fake_self; + pid_t opt_kernel_pid; + uid_t opt_anon_owner; + + /* Default values */ + #define OPT_CLK_TCK sysconf(_SC_CLK_TCK) + #define OPT_STAT_MODE 0400 +-#define OPT_FAKE_SELF -1 + #define OPT_KERNEL_PID 2 + #define OPT_ANON_OWNER 0 + +@@ -74,19 +72,6 @@ argp_parser (int key, char *arg, struct argp_state *state) + opt_stat_mode = v; + break; + +- case 'S': +- if (arg) +- { +- v = strtol (arg, &endp, 0); +- if (*endp || ! *arg) +- argp_error (state, "--fake-self: PID must be an integer"); +- else +- opt_fake_self = v; +- } +- else +- opt_fake_self = 1; +- break; +- + case 'k': + v = strtol (arg, &endp, 0); + if (*endp || ! *arg || (signed) opt_kernel_pid < 0) +@@ -98,7 +83,6 @@ argp_parser (int key, char *arg, struct argp_state *state) + case 'c': + opt_clk_tck = 100; + opt_stat_mode = 0444; +- opt_fake_self = 1; + break; + + case 'a': +@@ -146,10 +130,6 @@ struct argp_option common_options[] = { + "You can use this option to override its mode to be more permissive " + "for compatibility purposes. " + "(default: 0400)" }, +- { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL, +- "Provide a fake \"self\" symlink to the given PID, for compatibility " +- "purposes. If PID is omitted, \"self\" will point to init. " +- "(default: no self link)" }, + { "kernel-process", 'k', "PID", 0, + "Process identifier for the kernel, used to retreive its command " + "line, as well as the global up and idle times. " +@@ -243,9 +223,6 @@ netfs_append_args (char **argz, size_t *argz_len) + FOPT (opt_stat_mode, OPT_STAT_MODE, + "--stat-mode=%o", opt_stat_mode); + +- FOPT (opt_fake_self, OPT_FAKE_SELF, +- "--fake-self=%d", opt_fake_self); +- + FOPT (opt_anon_owner, OPT_ANON_OWNER, + "--anonymous-owner=%d", opt_anon_owner); + +@@ -287,7 +264,6 @@ int main (int argc, char **argv) + + opt_clk_tck = OPT_CLK_TCK; + opt_stat_mode = OPT_STAT_MODE; +- opt_fake_self = OPT_FAKE_SELF; + opt_kernel_pid = OPT_KERNEL_PID; + opt_anon_owner = OPT_ANON_OWNER; + err = argp_parse (&argp, argc, argv, 0, 0, 0); +diff --git a/procfs/main.h b/procfs/main.h +index 4e28b7e..051db95 100644 +--- a/procfs/main.h ++++ b/procfs/main.h +@@ -20,6 +20,5 @@ + /* Startup options */ + extern int opt_clk_tck; + extern mode_t opt_stat_mode; +-extern pid_t opt_fake_self; + extern pid_t opt_kernel_pid; + extern uid_t opt_anon_owner; +diff --git a/procfs/rootdir.c b/procfs/rootdir.c +index d68645e..d63397e 100644 +--- a/procfs/rootdir.c ++++ b/procfs/rootdir.c +@@ -395,19 +395,7 @@ out: + return err; + } + +-static int +-rootdir_fakeself_exists (void *dir_hook, const void *entry_hook) +-{ +- return opt_fake_self >= 0; +-} +- +-static error_t +-rootdir_gc_fakeself (void *hook, char **contents, ssize_t *contents_len) +-{ +- *contents_len = asprintf (contents, "%d", opt_fake_self); +- return 0; +-} +- ++static struct node *rootdir_self_node; + static struct node *rootdir_mounts_node; + + static error_t +@@ -624,13 +612,10 @@ rootdir_translated_node_get_translator (void *hook, char **argz, + static const struct procfs_dir_entry rootdir_entries[] = { + { + .name = "self", +- .hook = & (struct procfs_node_ops) { +- .get_contents = rootdir_gc_fakeself, +- .cleanup_contents = procfs_cleanup_contents_with_free, +- }, ++ .hook = ROOTDIR_DEFINE_TRANSLATED_NODE (&rootdir_self_node, ++ _HURD_MAGIC "\0proc/self"), + .ops = { +- .make_node = rootdir_symlink_make_node, +- .exists = rootdir_fakeself_exists, ++ .make_node = rootdir_make_translated_node, + } + }, + { +-- +2.1.0 + diff --git a/debian/patches/procfs-filesystems.patch b/debian/patches/procfs-filesystems.patch deleted file mode 100644 index cfa28db3..00000000 --- a/debian/patches/procfs-filesystems.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 4b30ee4249c752d935e1863365bef457a5389169 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Thu, 18 Sep 2014 19:38:04 +0200 -Subject: [PATCH 2/2] procfs: implement /proc/filesystems - -* procfs/rootdir.c (rootdir_gc_filesystems): New function. -(rootdir_entries): Use the new function to implement /proc/filesystems. ---- - procfs/rootdir.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 60 insertions(+), 1 deletion(-) - -diff --git a/procfs/rootdir.c b/procfs/rootdir.c -index 0b13119..e500c3a 100644 ---- a/procfs/rootdir.c -+++ b/procfs/rootdir.c -@@ -1,5 +1,5 @@ - /* Hurd /proc filesystem, permanent files of the root directory. -- Copyright (C) 2010,13 Free Software Foundation, Inc. -+ Copyright (C) 2010,13,14 Free Software Foundation, Inc. - - This file is part of the GNU Hurd. - -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include "procfs.h" - #include "procfs_dir.h" - #include "main.h" -@@ -535,6 +536,57 @@ rootdir_gc_slabinfo (void *hook, char **contents, ssize_t *contents_len) - cache_info, cache_info_count * sizeof *cache_info); - return err; - } -+ -+static error_t -+rootdir_gc_filesystems (void *hook, char **contents, ssize_t *contents_len) -+{ -+ error_t err = 0; -+ size_t i; -+ int glob_ret; -+ glob_t matches; -+ FILE *m; -+ -+ m = open_memstream (contents, contents_len); -+ if (m == NULL) -+ return errno; -+ -+ glob_ret = glob (_HURD "*fs", 0, NULL, &matches); -+ switch (glob_ret) -+ { -+ case 0: -+ for (i = 0; i < matches.gl_pathc; i++) -+ { -+ /* Get ith entry, shave off the prefix. */ -+ char *name = &matches.gl_pathv[i][sizeof _HURD - 1]; -+ -+ /* Linux naming convention is a bit inconsistent. */ -+ if (strncmp (name, "ext", 3) == 0 -+ || strcmp (name, "procfs") == 0) -+ /* Drop the fs suffix. */ -+ name[strlen (name) - 2] = 0; -+ -+ fprintf (m, "\t%s\n", name); -+ } -+ -+ globfree (&matches); -+ break; -+ -+ case GLOB_NOMATCH: -+ /* Poor fellow. */ -+ break; -+ -+ case GLOB_NOSPACE: -+ err = ENOMEM; -+ break; -+ -+ default: -+ /* This should not happen. */ -+ err = EGRATUITOUS; -+ } -+ -+ fclose (m); -+ return err; -+} - - /* Glue logic and entries table */ - -@@ -635,6 +687,13 @@ static const struct procfs_dir_entry rootdir_entries[] = { - .cleanup_contents = procfs_cleanup_contents_with_free, - }, - }, -+ { -+ .name = "filesystems", -+ .hook = & (struct procfs_node_ops) { -+ .get_contents = rootdir_gc_filesystems, -+ .cleanup_contents = procfs_cleanup_contents_with_free, -+ }, -+ }, - #ifdef PROFILE - /* In order to get a usable gmon.out file, we must apparently use exit(). */ - { --- -2.1.0 - diff --git a/debian/patches/procfs-maps.patch b/debian/patches/procfs-maps.patch deleted file mode 100644 index 7e973e56..00000000 --- a/debian/patches/procfs-maps.patch +++ /dev/null @@ -1,143 +0,0 @@ -From f89a89b0ecefdc9327f799f9a0394e06cd1997c0 Mon Sep 17 00:00:00 2001 -From: Justus Winter <4winter@informatik.uni-hamburg.de> -Date: Thu, 18 Sep 2014 18:38:04 +0200 -Subject: [PATCH 1/2] procfs: implement /proc/N/maps - -Fixes https://savannah.gnu.org/bugs/?32770 . - -* procfs/process.c (process_file_gc_maps): New function. -(entries): Use the new function to implement /proc/N/maps. ---- - procfs/process.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 103 insertions(+), 1 deletion(-) - -diff --git a/procfs/process.c b/procfs/process.c -index 4854148..a9b1a59 100644 ---- a/procfs/process.c -+++ b/procfs/process.c -@@ -1,5 +1,5 @@ - /* Hurd /proc filesystem, implementation of process directories. -- Copyright (C) 2010 Free Software Foundation, Inc. -+ Copyright (C) 2010,14 Free Software Foundation, Inc. - - This file is part of the GNU Hurd. - -@@ -109,6 +109,100 @@ process_file_gc_environ (struct proc_stat *ps, char **contents) - } - - static ssize_t -+process_file_gc_maps (struct proc_stat *ps, char **contents) -+{ -+ error_t err; -+ FILE *s; -+ size_t contents_len; -+ vm_offset_t addr = 0; -+ vm_size_t size; -+ vm_prot_t prot, max_prot; -+ mach_port_t obj; -+ vm_offset_t offs; -+ vm_inherit_t inh; -+ int shared; -+ -+ /* Unfortunately we cannot resolve memory objects to their backing -+ file (yet), so we use the port name as identifier. To avoid the -+ same name from being used again and again, we defer the -+ deallocation until the end of the function. We use a simple -+ linked list for this purpose. */ -+ struct mem_obj -+ { -+ mach_port_t port; -+ struct mem_obj *next; -+ }; -+ struct mem_obj *objects = NULL; -+ -+ s = open_memstream (contents, &contents_len); -+ if (s == NULL) -+ { -+ *contents = NULL; -+ return 0; -+ } -+ -+ while (1) -+ { -+ err = -+ vm_region (ps->task, &addr, &size, &prot, &max_prot, &inh, -+ &shared, &obj, &offs); -+ if (err) -+ break; -+ -+ fprintf (s, "%0*x-%0*x %c%c%c%c %0*x %s %d ", -+ /* Address range. */ -+ 2*sizeof s, addr, -+ 2*sizeof s, addr + size, -+ /* Permissions. */ -+ prot & VM_PROT_READ? 'r': '-', -+ prot & VM_PROT_WRITE? 'w': '-', -+ prot & VM_PROT_EXECUTE? 'x': '-', -+ shared? 's': 'p', -+ /* Offset. */ -+ 2*sizeof s, offs, -+ /* Device. */ -+ "00:00", -+ /* Inode. */ -+ 0); -+ -+ /* Pathname. */ -+ if (MACH_PORT_VALID (obj)) -+ { -+ struct mem_obj *o = malloc (sizeof *o); -+ if (o) -+ { -+ o->port = obj; -+ o->next = objects; -+ objects = o; -+ } -+ else -+ mach_port_deallocate (mach_task_self (), obj); -+ -+ fprintf (s, "[mem_obj=%d]\n", obj); -+ } -+ else -+ fprintf (s, "\n"); -+ -+ addr += size; -+ } -+ -+ while (objects) -+ { -+ struct mem_obj *o = objects; -+ mach_port_deallocate (mach_task_self (), o->port); -+ objects = o->next; -+ free (o); -+ } -+ -+ /* This is a bit awkward, fortunately vm_region should not fail. */ -+ if (err != KERN_NO_SPACE) -+ fprintf (s, "%s\n", strerror (err)); -+ -+ fclose (s); -+ return contents_len; -+} -+ -+static ssize_t - process_file_gc_stat (struct proc_stat *ps, char **contents) - { - struct procinfo *pi = proc_stat_proc_info (ps); -@@ -348,6 +442,14 @@ static struct procfs_dir_entry entries[] = { - }, - }, - { -+ .name = "maps", -+ .hook = & (struct process_file_desc) { -+ .get_contents = process_file_gc_maps, -+ .needs = PSTAT_TASK, -+ .mode = 0400, -+ }, -+ }, -+ { - .name = "stat", - .hook = & (struct process_file_desc) { - .get_contents = process_file_gc_stat, --- -2.1.0 - diff --git a/debian/patches/series b/debian/patches/series index cfb74254..415454f2 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -60,5 +60,11 @@ mach-defpager-protected-payload.patch #0002-libports-lock-less-reference-counting-for-port_info-.patch 0001-libdiskfs-remove-code-counting-cache-misses.patch trans-crash-add-verbose.patch -procfs-maps.patch -procfs-filesystems.patch + +procfs-0001-procfs-implement-proc-N-maps.patch +procfs-0002-procfs-implement-proc-filesystems.patch +procfs-0003-procfs-implement-proc-N-mounts.patch +procfs-0004-procfs-do-not-test-whether-hurd-mtab-exists.patch +procfs-0005-procfs-generalize-the-translator-linkage-code.patch +procfs-0006-procfs-reorganize-rootdir.c.patch +procfs-0007-procfs-provide-magic-retry-response-for-proc-self.patch -- cgit v1.2.3