diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-09-24 18:24:04 +0200 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-09-24 18:24:04 +0200 |
commit | 0b7b919d1acce29637b5ae544ae6a73fafcde6df (patch) | |
tree | a8ed6010fc334b60c5dc9cc8344f1f240b18421e | |
parent | 82fe83952f061ff0c8cacfaa1eab63592ad9f435 (diff) |
add patch series
10 files changed, 1968 insertions, 0 deletions
diff --git a/debian/patches/introspection0001-hurd-add-an-Hurd-server-introspection-protocol.patch b/debian/patches/introspection0001-hurd-add-an-Hurd-server-introspection-protocol.patch new file mode 100644 index 00000000..6ffa437e --- /dev/null +++ b/debian/patches/introspection0001-hurd-add-an-Hurd-server-introspection-protocol.patch @@ -0,0 +1,147 @@ +From 1d2622b5bb6a49f0165bfdc10278451a9228c18e Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 21 May 2014 16:40:12 +0200 +Subject: [PATCH hurd 1/9] hurd: add an Hurd server introspection protocol + +Most Hurd servers use libports to manage receive rights and the +associated objects. These procedures can be used to query the state +associated with receive rights managed by libports. + +The procedures are not specific to libports. Any Hurd server can +implement this protocol. To do so, a server installs a send right in +the array of well-known ports, under the key +HURD_PORT_REGISTER_INTROSPECTION. + +* hurd/hurd_port.defs: New file. +* hurd/hurd_types.h (HURD_PORT_REGISTER_INTROSPECTION): New macro. +(HURD_PORT_REGISTER_MAX): Likewise. +* hurd/subsystems: Add hurd_port subsystem. +--- + hurd/hurd_port.defs | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + hurd/hurd_types.h | 7 +++++ + hurd/subsystems | 1 + + 3 files changed, 86 insertions(+) + create mode 100644 hurd/hurd_port.defs + +diff --git a/hurd/hurd_port.defs b/hurd/hurd_port.defs +new file mode 100644 +index 0000000..d1f46b3 +--- /dev/null ++++ b/hurd/hurd_port.defs +@@ -0,0 +1,78 @@ ++/* Hurd server introspection. ++ ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ ++ ++subsystem hurd_port 39000; ++ ++/* Hurd server introspection. ++ ++ Most Hurd servers use libports to manage receive rights and the ++ associated objects. These procedures can be used to query the ++ state associated with receive rights managed by libports. ++ ++ The procedures are not specific to libports. Any Hurd server can ++ implement this protocol. To do so, a server installs a send right ++ in the array of well-known ports, under the key ++ HURD_PORT_REGISTER_INTROSPECTION. ++ ++ A client in possession of the servers task port can retrieve a copy ++ of this send right using mach_ports_lookup. */ ++ ++#include <hurd/hurd_types.defs> ++ ++#ifdef HURD_PORT_IMPORTS ++HURD_PORT_IMPORTS ++#endif ++ ++INTR_INTERFACE ++ ++/* Return the number of hard and weak references of the object ++ directly associated with the receive right NAME. ++ ++ Return EINVAL if NAME does not denote a receive right managed by ++ the port-to-object mapper, or if the concept of reference counting ++ simply does not apply. */ ++routine hurd_port_get_refcounts ( ++ introspection: mach_port_t; ++ name: mach_port_name_t; ++ waittime timeout: natural_t; ++ RPT ++ out hard: natural_t; ++ out weak: natural_t); ++ ++/* Return a compact, human-readable description of the object related ++ with the receive right NAME. ++ ++ This description is meant for debugging purposes and should include ++ relevant internal state. If possible, it should include ++ information that is meaningful in other contexts (like a file name, ++ or the inode number). ++ ++ Return EINVAL if NAME does not denote a receive right managed by ++ the port-to-object mapper. */ ++routine hurd_port_debug_info ( ++ introspection: mach_port_t; ++ name: mach_port_name_t; ++ waittime timeout: natural_t; ++ RPT ++ out debug_info: string_t); ++ ++routine hurd_port_trace_class_rpcs ( ++ introspection: mach_port_t; ++ name: mach_port_name_t; ++ trace_port: mach_port_send_t); +diff --git a/hurd/hurd_types.h b/hurd/hurd_types.h +index 4341177..76a8201 100644 +--- a/hurd/hurd_types.h ++++ b/hurd/hurd_types.h +@@ -23,6 +23,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include <time.h> /* For struct timespec. */ + #include <mach/std_types.h> /* For mach_port_t et al. */ + #include <mach/message.h> /* For mach_msg_id_t et al. */ ++#include <mach/mach_param.h> /* For TASK_PORT_REGISTER_MAX. */ + #include <sys/types.h> /* For pid_t and uid_t. */ + + /* A string identifying this release of the GNU Hurd. Our +@@ -372,4 +373,10 @@ enum + INIT_INT_MAX, + }; + ++/* Define the well-known ports available via mach_ports_lookup. */ ++#define HURD_PORT_REGISTER_INTROSPECTION 0 ++ ++/* This is a fixed limit. */ ++#define HURD_PORT_REGISTER_MAX TASK_PORT_REGISTER_MAX ++ + #endif +diff --git a/hurd/subsystems b/hurd/subsystems +index c05895c..59893b2 100644 +--- a/hurd/subsystems ++++ b/hurd/subsystems +@@ -36,6 +36,7 @@ tape 35000 Special control operations for magtapes + login 36000 Database of logged-in users + pfinet 37000 Internet configuration calls + password 38000 Password checker ++hurd_port 39000 Port debugging and introspection + <ioctl space> 100000- First subsystem of ioctl class 'f' (lowest class) + tioctl 156000 Ioctl class 't' (terminals) + tioctl 156200 (continued) +-- +2.1.4 + diff --git a/debian/patches/introspection0002-libintrospection-a-library-for-Hurd-server-introspec.patch b/debian/patches/introspection0002-libintrospection-a-library-for-Hurd-server-introspec.patch new file mode 100644 index 00000000..55d691f5 --- /dev/null +++ b/debian/patches/introspection0002-libintrospection-a-library-for-Hurd-server-introspec.patch @@ -0,0 +1,401 @@ +From 9917c46bf101ab34c26a098936cdd0b3acd3f45d Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Fri, 23 May 2014 17:01:48 +0200 +Subject: [PATCH hurd 2/9] libintrospection: a library for Hurd server + introspection + +* Makefile (lib-subdirs): Add libintrospection. +* libintrospection/Makefile: New file. +* libintrospection/introspection.c: Likewise. +* libintrospection/introspection.h: Likewise. +* libintrospection/trace.c: Likewise. +--- + Makefile | 2 + + libintrospection/Makefile | 27 ++++++ + libintrospection/introspection.c | 86 +++++++++++++++++++ + libintrospection/introspection.h | 50 +++++++++++ + libintrospection/trace.c | 175 +++++++++++++++++++++++++++++++++++++++ + 5 files changed, 340 insertions(+) + create mode 100644 libintrospection/Makefile + create mode 100644 libintrospection/introspection.c + create mode 100644 libintrospection/introspection.h + create mode 100644 libintrospection/trace.c + +diff --git a/Makefile b/Makefile +index 3178740..76eec21 100644 +--- a/Makefile ++++ b/Makefile +@@ -50,6 +50,8 @@ endif + # Other directories + other-subdirs = hurd doc config release include + ++lib-subdirs += libintrospection ++ + # All the subdirectories together + subdirs = $(lib-subdirs) $(prog-subdirs) $(other-subdirs) + +diff --git a/libintrospection/Makefile b/libintrospection/Makefile +new file mode 100644 +index 0000000..75adef2 +--- /dev/null ++++ b/libintrospection/Makefile +@@ -0,0 +1,27 @@ ++# Copyright (C) 2014 Free Software Foundation, Inc. ++# ++# This file is part of the GNU Hurd. ++# ++# The GNU Hurd is free software; you can redistribute it and/or ++# modify it under the terms of the GNU General Public License as ++# published by the Free Software Foundation; either version 2, or (at ++# your option) any later version. ++# ++# The GNU Hurd is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. ++ ++dir := libintrospection ++makemode := library ++ ++libname := libintrospection ++SRCS = introspection.c trace.c hurd_portUser.c ++installhdrs = introspection.h ++ ++OBJS = $(SRCS:.c=.o) ++ ++include ../Makeconf +diff --git a/libintrospection/introspection.c b/libintrospection/introspection.c +new file mode 100644 +index 0000000..65c0727 +--- /dev/null ++++ b/libintrospection/introspection.c +@@ -0,0 +1,86 @@ ++/* Hurd server introspection. ++ ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ ++ Written by Justus Winter <4winter@informatik.uni-hamburg.de> ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ ++ ++#include <mach.h> ++ ++#include "introspection.h" ++#include "hurd_port_U.h" ++ ++error_t ++introspection_set_port (mach_port_t task, ++ mach_port_t introspection_port) ++{ ++ error_t err; ++ mach_port_t *ports; ++ size_t ports_len; ++ ++ err = mach_ports_lookup (task, &ports, &ports_len); ++ if (err) ++ return err; ++ ++ if (MACH_PORT_VALID (ports[HURD_PORT_REGISTER_INTROSPECTION])) ++ mach_port_deallocate (mach_task_self (), ++ ports[HURD_PORT_REGISTER_INTROSPECTION]); ++ ++ ports[HURD_PORT_REGISTER_INTROSPECTION] = introspection_port; ++ ++ err = mach_ports_register (task, ports, ports_len); ++ if (err) ++ { ++ size_t i; ++ for (i = 0; i < ports_len; i++) ++ if (MACH_PORT_VALID (ports[i])) ++ mach_port_deallocate (mach_task_self (), ports[i]); ++ ++ return err; ++ } ++ ++ return 0; ++} ++ ++error_t ++introspection_get_port (mach_port_t task, mach_port_t *introspection_port) ++{ ++ error_t err; ++ mach_port_t *ports; ++ size_t ports_len; ++ ++ err = mach_ports_lookup (task, &ports, &ports_len); ++ if (! err) ++ { ++ size_t i; ++ if (MACH_PORT_VALID (*introspection_port)) ++ mach_port_deallocate (mach_task_self (), *introspection_port); ++ ++ for (i = 0; i < ports_len; i++) ++ if (i == HURD_PORT_REGISTER_INTROSPECTION) ++ *introspection_port = ports[i]; ++ else ++ { ++ if (MACH_PORT_VALID (ports[i])) ++ mach_port_deallocate (mach_task_self (), ports[i]); ++ } ++ } ++ else ++ *introspection_port = MACH_PORT_DEAD; ++ ++ return err; ++} +diff --git a/libintrospection/introspection.h b/libintrospection/introspection.h +new file mode 100644 +index 0000000..ae9fcfa +--- /dev/null ++++ b/libintrospection/introspection.h +@@ -0,0 +1,50 @@ ++/* Hurd server introspection. ++ ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ ++ Written by Justus Winter <4winter@informatik.uni-hamburg.de> ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ ++ ++#ifndef _HURD_INTROSPECTION_H_ ++#define _HURD_INTROSPECTION_H_ ++ ++#include <errno.h> ++#include <mach.h> ++ ++error_t ++introspection_set_port (mach_port_t task, ++ mach_port_t introspection_port); ++ ++error_t ++introspection_get_port (mach_port_t task, ++ mach_port_t *introspection_port); ++ ++error_t ++introspection_trace_message (mach_port_t trace_port, ++ const mach_msg_header_t *msgp, ++ mach_port_t id); ++ ++error_t ++introspection_trace_request (mach_port_t trace_port, ++ const mach_msg_header_t *msgp, ++ mach_port_t *id); ++ ++error_t ++introspection_extract_message (mach_msg_header_t *msgp, ++ mach_port_t *id); ++ ++#endif /* _HURD_INTROSPECTION_H_ */ +diff --git a/libintrospection/trace.c b/libintrospection/trace.c +new file mode 100644 +index 0000000..ac2fdb0 +--- /dev/null ++++ b/libintrospection/trace.c +@@ -0,0 +1,175 @@ ++/* Hurd server introspection. ++ ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ ++ Written by Justus Winter <4winter@informatik.uni-hamburg.de> ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ ++ ++#include <error.h> ++#include <hurd/ports.h> ++#include <mach/mig_errors.h> ++#include <pthread.h> ++#include <stdlib.h> ++#include <string.h> ++ ++#include "introspection.h" ++ ++static const mach_msg_type_t ports_type = { ++ /* msgt_name = */ MACH_MSG_TYPE_PORT_NAME, ++ /* msgt_size = */ sizeof (mach_port_t) << 3, ++ /* msgt_number = */ 4, ++ /* msgt_inline = */ TRUE, ++ /* msgt_longform = */ FALSE, ++ /* msgt_deallocate = */ FALSE, ++ /* msgt_unused = */ 0 ++}; ++ ++struct trace_footer ++{ ++ mach_msg_type_t ports_type; ++ mach_port_t id; ++ mach_port_t bits; ++ mach_port_t remote_port; ++ mach_port_t local_port; ++}; ++ ++error_t ++introspection_trace_message (mach_port_t trace_port, ++ const mach_msg_header_t *msgp, ++ mach_port_t id) ++{ ++ error_t err; ++ mach_msg_header_t *copyp; ++ void *msg_buf_ptr; ++ struct trace_footer *footer; ++ size_t size = msgp->msgh_size + sizeof *footer; ++ ++ copyp = malloc (size); ++ if (copyp == NULL) ++ return ENOMEM; ++ ++ memcpy (copyp, msgp, msgp->msgh_size); ++ footer = (void *) copyp + msgp->msgh_size; ++ ++ /* Process the message data, clear msgt_deallocate and turn rights ++ into mere port names. */ ++ msg_buf_ptr = (void *) copyp + sizeof *copyp; ++ while (msg_buf_ptr < (void *) copyp + msgp->msgh_size) ++ { ++ mach_msg_type_long_t *type_long = msg_buf_ptr; ++ mach_msg_type_t *type = &type_long->msgtl_header; ++ mach_msg_type_number_t nelt; /* Number of data items. */ ++ mach_msg_type_size_t eltsize; /* Bytes per item. */ ++ ++ type->msgt_deallocate = 0; ++ ++ if (! type->msgt_longform) ++ { ++ nelt = type->msgt_number; ++ eltsize = type->msgt_size / 8; ++ if (MACH_MSG_TYPE_PORT_ANY (type->msgt_name)) ++ type->msgt_name = MACH_MSG_TYPE_PORT_NAME; ++ msg_buf_ptr += sizeof *type; ++ } ++ else ++ { ++ nelt = type_long->msgtl_number; ++ eltsize = type_long->msgtl_size / 8; ++ if (MACH_MSG_TYPE_PORT_ANY (type_long->msgtl_name)) ++ type_long->msgtl_name = MACH_MSG_TYPE_PORT_NAME; ++ msg_buf_ptr += sizeof *type_long; ++ } ++ ++ if (! type->msgt_inline) ++ /* This datum is out-of-line, meaning the message actually ++ contains a pointer to a vm_allocate'd region of data. */ ++ msg_buf_ptr += sizeof (void *); ++ else ++ msg_buf_ptr += ((nelt * eltsize + sizeof(natural_t) - 1) ++ & ~(sizeof(natural_t) - 1)); ++ } ++ ++ copyp->msgh_bits = ++ MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0) ++ | (msgp->msgh_bits & MACH_MSGH_BITS_COMPLEX); ++ copyp->msgh_remote_port = trace_port; ++ copyp->msgh_local_port = MACH_PORT_NULL; ++ ++ *footer = (struct trace_footer) ++ { ++ ports_type, ++ id, ++ (mach_port_t) msgp->msgh_bits, ++ msgp->msgh_remote_port, ++ MACH_MSGH_BITS_LOCAL (msgp->msgh_bits) ++ == MACH_MSG_TYPE_PROTECTED_PAYLOAD ++ ? ports_payload_get_name (msgp->msgh_protected_payload) ++ : msgp->msgh_local_port, ++ }; ++ ++ err = mach_msg (copyp, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, size, ++ 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); ++ ++ free (copyp); ++ return err; ++} ++ ++static mach_port_t ++make_id (void) ++{ ++ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; ++ static mach_port_t id; ++ mach_port_t result; ++ ++ pthread_mutex_lock (&lock); ++ ++ do ++ id += 1; ++ while (! MACH_PORT_VALID (id)); ++ ++ result = id; ++ pthread_mutex_unlock (&lock); ++ ++ return result; ++} ++ ++error_t ++introspection_trace_request (mach_port_t trace_port, ++ const mach_msg_header_t *msgp, ++ mach_port_t *id) ++{ ++ *id = make_id (); ++ return introspection_trace_message (trace_port, msgp, *id); ++} ++ ++error_t ++introspection_extract_message (mach_msg_header_t *msgp, ++ mach_port_t *id) ++{ ++ size_t size = msgp->msgh_size - sizeof (struct trace_footer); ++ struct trace_footer *footer = (void *) msgp + size; ++ ++ if (memcmp (&footer->ports_type, &ports_type, sizeof ports_type) != 0) ++ return MIG_BAD_ARGUMENTS; ++ ++ msgp->msgh_bits = (mach_msg_bits_t) footer->bits; ++ msgp->msgh_remote_port = footer->remote_port; ++ msgp->msgh_local_port = footer->local_port; ++ msgp->msgh_size = size; ++ *id = footer->id; ++ return 0; ++} +-- +2.1.4 + diff --git a/debian/patches/introspection0003-libports-implement-the-Hurd-server-introspection-pro.patch b/debian/patches/introspection0003-libports-implement-the-Hurd-server-introspection-pro.patch new file mode 100644 index 00000000..1f5393d0 --- /dev/null +++ b/debian/patches/introspection0003-libports-implement-the-Hurd-server-introspection-pro.patch @@ -0,0 +1,481 @@ +From 798eae80f9de731d0dc3ff5bb8172cef99cad207 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 21 May 2014 16:47:14 +0200 +Subject: [PATCH hurd 3/9] libports: implement the Hurd server introspection + protocol + +Add a compact and self-contained introspection server to libports. +Add functions to to label port buckets and classes. Make it possible +to provide a function that given an object of a class, returns a +human-readable representation for it. + +* libports/introspection.c: New file. +* libports/create-bucket.c (ports_label_bucket): New function. +* libports/create-class.c (ports_set_debug_info): Likewise. +* libports/manage-multithread.c (internal_demuxer): Trace messages if +desired. +* libports/manage-one-thread.c (internal_demuxer): Likewise. +* libports/ports.h (struct port_bucket): Add label. +(struct port_class): Add debug_info and label. +(ports_label_bucket): New declaration. +(ports_set_debug_info): Likewise. +* libports/Makefile (SRCS): Add introspection.c. +(OBJS): Add hurd_portServer.o. +--- + ext2fs/Makefile | 3 +- + fatfs/Makefile | 3 +- + isofs/Makefile | 3 +- + libports/Makefile | 6 +- + libports/create-bucket.c | 7 ++ + libports/create-class.c | 16 ++++ + libports/introspection.c | 189 ++++++++++++++++++++++++++++++++++++++++++ + libports/manage-multithread.c | 10 +++ + libports/manage-one-thread.c | 11 +++ + libports/ports.h | 14 ++++ + tmpfs/Makefile | 3 +- + 11 files changed, 258 insertions(+), 7 deletions(-) + create mode 100644 libports/introspection.c + +diff --git a/ext2fs/Makefile b/ext2fs/Makefile +index 8d2e68c..9d72fda 100644 +--- a/ext2fs/Makefile ++++ b/ext2fs/Makefile +@@ -23,7 +23,8 @@ target = ext2fs + SRCS = balloc.c dir.c ext2fs.c getblk.c hyper.c ialloc.c \ + inode.c pager.c pokel.c truncate.c storeinfo.c msg.c xinl.c + OBJS = $(SRCS:.c=.o) +-HURDLIBS = diskfs pager iohelp fshelp store ports ihash shouldbeinlibc ++HURDLIBS = diskfs pager iohelp fshelp store ports ihash introspection \ ++ shouldbeinlibc + OTHERLIBS = -lpthread $(and $(HAVE_LIBBZ2),-lbz2) $(and $(HAVE_LIBZ),-lz) + + include ../Makeconf +diff --git a/fatfs/Makefile b/fatfs/Makefile +index 6224b64..e4f01ec 100644 +--- a/fatfs/Makefile ++++ b/fatfs/Makefile +@@ -22,7 +22,8 @@ target = fatfs + SRCS = inode.c main.c dir.c pager.c fat.c virt-inode.c node-create.c + + OBJS = $(SRCS:.c=.o) +-HURDLIBS = diskfs iohelp fshelp store pager ports ihash shouldbeinlibc ++HURDLIBS = diskfs iohelp fshelp store pager ports ihash introspection \ ++ shouldbeinlibc + OTHERLIBS = -lpthread $(and $(HAVE_LIBBZ2),-lbz2) $(and $(HAVE_LIBZ),-lz) + + include ../Makeconf +diff --git a/isofs/Makefile b/isofs/Makefile +index 6475c52..9e399bf 100644 +--- a/isofs/Makefile ++++ b/isofs/Makefile +@@ -21,7 +21,8 @@ target = iso9660fs + SRCS = inode.c main.c lookup.c pager.c rr.c + + OBJS = $(SRCS:.c=.o) +-HURDLIBS = diskfs iohelp fshelp store pager ports ihash shouldbeinlibc ++HURDLIBS = diskfs iohelp fshelp store pager ports ihash introspection \ ++ shouldbeinlibc + OTHERLIBS = -lpthread $(and $(HAVE_LIBBZ2),-lbz2) $(and $(HAVE_LIBZ),-lz) + + include ../Makeconf +diff --git a/libports/Makefile b/libports/Makefile +index af881f8..ec98bad 100644 +--- a/libports/Makefile ++++ b/libports/Makefile +@@ -36,13 +36,13 @@ SRCS = create-bucket.c create-class.c \ + interrupt-operation.c interrupt-on-notify.c interrupt-notified-rpcs.c \ + dead-name.c create-port.c import-port.c default-uninhibitable-rpcs.c \ + claim-right.c transfer-right.c create-port-noinstall.c create-internal.c \ +- interrupted.c extern-inline.c port-deref-deferred.c ++ interrupted.c extern-inline.c port-deref-deferred.c introspection.c + + installhdrs = ports.h port-deref-deferred.h + +-HURDLIBS= ihash ++HURDLIBS= ihash introspection + LDLIBS += -lpthread +-OBJS = $(SRCS:.c=.o) notifyServer.o interruptServer.o ++OBJS = $(SRCS:.c=.o) notifyServer.o interruptServer.o hurd_portServer.o + + MIGCOMSFLAGS = -prefix ports_ + MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h +diff --git a/libports/create-bucket.c b/libports/create-bucket.c +index 82c00a4..34559f5 100644 +--- a/libports/create-bucket.c ++++ b/libports/create-bucket.c +@@ -49,5 +49,12 @@ ports_create_bucket () + hurd_ihash_init (&ret->htable, offsetof (struct port_info, hentry)); + ret->rpcs = ret->flags = ret->count = 0; + _ports_threadpool_init (&ret->threadpool); ++ ret->label = "unlabeled bucket"; + return ret; + } ++ ++/* Label BUCKET with LABEL. */ ++void ports_label_bucket (struct port_bucket *bucket, const char *label) ++{ ++ bucket->label = label; ++} +diff --git a/libports/create-class.c b/libports/create-class.c +index 782f52b..8abf643 100644 +--- a/libports/create-class.c ++++ b/libports/create-class.c +@@ -41,6 +41,22 @@ ports_create_class (void (*clean_routine)(void *), + cl->rpcs = 0; + cl->count = 0; + cl->uninhibitable_rpcs = ports_default_uninhibitable_rpcs; ++ cl->debug_info = NULL; ++ cl->label = "unlabeled class"; ++ cl->trace_port = MACH_PORT_NULL; + + return cl; + } ++ ++/* Label CLASS with LABEL. Use DEBUG_INFO to format human-readable ++ information about a given object belonging to CLASS into an buffer, ++ or the default formatting function if DEBUG_INFO is NULL. */ ++void ++ports_label_class (struct port_class *class, ++ const char *label, ++ error_t (*debug_info) (const void *, char *, size_t)) ++{ ++ class->label = label; ++ if (debug_info) ++ class->debug_info = debug_info; ++} +diff --git a/libports/introspection.c b/libports/introspection.c +new file mode 100644 +index 0000000..912c768 +--- /dev/null ++++ b/libports/introspection.c +@@ -0,0 +1,189 @@ ++/* Hurd server introspection. ++ ++ Copyright (C) 2014 Free Software Foundation, Inc. ++ ++ This file is part of the GNU Hurd. ++ ++ The GNU Hurd is free software; you can redistribute it and/or ++ modify it under the terms of the GNU General Public License as ++ published by the Free Software Foundation; either version 2, or (at ++ your option) any later version. ++ ++ The GNU Hurd is distributed in the hope that it will be useful, but ++ WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ ++ ++#include <error.h> ++#include <hurd/introspection.h> ++#include <pthread.h> ++#include <stdio.h> ++#include <string.h> ++ ++#include "ports.h" ++#include "hurd_port_U.h" ++ ++/* We service introspection requests on this port. */ ++static mach_port_t introspection_port; ++ ++/* We use a separate thread to service the introspection requests. It ++ is a straight forward Mach server for the hurd_port protocol. */ ++static void * ++service_introspection_requests (void *arg) ++{ ++ error_t err; ++ ++ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, ++ &introspection_port); ++ if (err) ++ { ++ error (0, err, "mach_port_allocate"); ++ return NULL; ++ } ++ ++ err = mach_port_insert_right (mach_task_self (), ++ introspection_port, introspection_port, ++ MACH_MSG_TYPE_MAKE_SEND); ++ if (err) ++ { ++ error (0, err, "mach_port_insert_right"); ++ return NULL; ++ } ++ ++ err = introspection_set_port (mach_task_self (), introspection_port); ++ if (err) ++ { ++ error (0, err, "introspection_set_port"); ++ return NULL; ++ } ++ ++ /* XXX mig should emit this declaration. */ ++ boolean_t ports_hurd_port_server (mach_msg_header_t *InHeadP, ++ mach_msg_header_t *OutHeadP); ++ ++ while (1) ++ mach_msg_server (ports_hurd_port_server, 0, introspection_port); ++ ++ /* Not reached. */ ++ return NULL; ++} ++ ++/* Start the introspection server before main is called. */ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ error_t err; ++ ++ pthread_t thread; ++ pthread_attr_t attr; ++#define STACK_SIZE (64 * 1024) ++ pthread_attr_init (&attr); ++ pthread_attr_setstacksize (&attr, STACK_SIZE); ++#undef STACK_SIZE ++ ++ err = pthread_create (&thread, &attr, ++ service_introspection_requests, NULL); ++ if (err) ++ error (1, err, "pthread_create"); ++ pthread_detach (thread); ++} ++ ++/* Return the number of hard and weak references of the object ++ directly associated with the receive right NAME. ++ ++ Return EINVAL if NAME does not denote a receive right managed by ++ the port-to-object mapper, or if the concept of reference counting ++ simply does not apply. */ ++error_t ++ports_S_hurd_port_get_refcounts (mach_port_t port, ++ mach_port_t name, ++ natural_t *hard, ++ natural_t *weak) ++{ ++ struct references result; ++ struct port_info *pi; ++ ++ if (port != introspection_port) ++ return EOPNOTSUPP; ++ ++ pi = ports_lookup_port (0, name, 0); ++ if (pi == NULL) ++ return EINVAL; ++ ++ refcounts_references (&pi->refcounts, &result); ++ ++ *hard = result.hard - 1; ++ *weak = result.weak; ++ ports_port_deref (pi); ++ return 0; ++} ++ ++static error_t ++default_debug_info (const void *port, char *buffer, size_t size) ++{ ++ const struct port_info *pi = port; ++ snprintf (buffer, size, ++ "bucket: %s, class: %s", ++ pi->bucket->label, pi->class->label); ++ return 0; ++} ++ ++/* Return a compact, human-readable description of the object related ++ with the receive right NAME. ++ ++ This description is meant for debugging purposes and should include ++ relevant internal state. If possible, it should include ++ information that is meaningful in other contexts (like a file name, ++ or the inode number). ++ ++ Return EINVAL if NAME does not denote a receive right managed by ++ the port-to-object mapper. */ ++error_t ++ports_S_hurd_port_debug_info (mach_port_t port, ++ mach_port_t name, ++ char *info) ++{ ++ error_t err; ++ struct port_info *pi; ++ ++ if (port != introspection_port) ++ return EOPNOTSUPP; ++ ++ pi = ports_lookup_port (0, name, 0); ++ if (pi == NULL) ++ return EINVAL; ++ ++ if (pi->class->debug_info) ++ err = pi->class->debug_info (pi, info, 1024 /* XXX */); ++ else ++ err = default_debug_info (pi, info, 1024 /* XXX */); ++ info[1023 /* XXX */] = 0; ++ ++ ports_port_deref (pi); ++ return err; ++} ++ ++error_t ++ports_S_hurd_port_trace_class_rpcs (mach_port_t port, ++ mach_port_t name, ++ mach_port_t trace_port) ++{ ++ struct port_info *pi; ++ ++ if (port != introspection_port) ++ return EOPNOTSUPP; ++ ++ pi = ports_lookup_port (0, name, 0); ++ if (pi == NULL) ++ return EINVAL; ++ ++ if (MACH_PORT_VALID (pi->class->trace_port)) ++ mach_port_deallocate (mach_task_self (), pi->class->trace_port); ++ ++ pi->class->trace_port = trace_port; ++ ports_port_deref (pi); ++ return 0; ++} +diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c +index 60743d9..8707d98 100644 +--- a/libports/manage-multithread.c ++++ b/libports/manage-multithread.c +@@ -21,6 +21,7 @@ + #include "ports.h" + #include <assert.h> + #include <error.h> ++#include <hurd/introspection.h> + #include <stdio.h> + #include <mach/message.h> + #include <mach/thread_info.h> +@@ -189,6 +190,11 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, + + if (pi) + { ++ mach_port_t trace_port = pi->class->trace_port; ++ mach_port_t trace_id; ++ if (__builtin_expect (MACH_PORT_VALID (trace_port), 0)) ++ introspection_trace_request (trace_port, inp, &trace_id); ++ + error_t err = ports_begin_rpc (pi, inp->msgh_id, &link); + if (err) + { +@@ -207,6 +213,10 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, + ports_end_rpc (pi, &link); + } + ports_port_deref (pi); ++ ++ if (__builtin_expect (MACH_PORT_VALID (trace_port), 0) ++ && outp->RetCode != MIG_NO_REPLY) ++ introspection_trace_message (trace_port, outp, trace_id); + } + else + { +diff --git a/libports/manage-one-thread.c b/libports/manage-one-thread.c +index b920338..55aa378 100644 +--- a/libports/manage-one-thread.c ++++ b/libports/manage-one-thread.c +@@ -18,6 +18,8 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++#include <hurd/introspection.h> ++ + #include "ports.h" + + void +@@ -80,6 +82,11 @@ ports_manage_port_operations_one_thread (struct port_bucket *bucket, + + if (pi) + { ++ mach_port_t trace_port = pi->class->trace_port; ++ mach_port_t trace_id; ++ if (__builtin_expect (MACH_PORT_VALID (trace_port), 0)) ++ introspection_trace_request (trace_port, inp, &trace_id); ++ + err = ports_begin_rpc (pi, inp->msgh_id, &link); + if (err) + { +@@ -96,6 +103,10 @@ ports_manage_port_operations_one_thread (struct port_bucket *bucket, + ports_end_rpc (pi, &link); + } + ports_port_deref (pi); ++ ++ if (__builtin_expect (MACH_PORT_VALID (trace_port), 0) ++ && outp->RetCode != MIG_NO_REPLY) ++ introspection_trace_message (trace_port, outp, trace_id); + } + else + { +diff --git a/libports/ports.h b/libports/ports.h +index 9299bc4..a31b894 100644 +--- a/libports/ports.h ++++ b/libports/ports.h +@@ -76,6 +76,7 @@ struct port_bucket + int flags; + int count; + struct ports_threadpool threadpool; ++ const char *label; + }; + /* FLAGS above are the following: */ + #define PORT_BUCKET_INHIBITED PORTS_INHIBITED +@@ -91,7 +92,10 @@ struct port_class + int count; + void (*clean_routine) (void *); + void (*dropweak_routine) (void *); ++ error_t (*debug_info) (const void *, char *, size_t); + struct ports_msg_id_range *uninhibitable_rpcs; ++ const char *label; ++ mach_port_t trace_port; + }; + /* FLAGS are the following: */ + #define PORT_CLASS_INHIBITED PORTS_INHIBITED +@@ -160,6 +164,9 @@ extern struct ports_msg_id_range *ports_default_uninhibitable_rpcs; + /* Create and return a new bucket. */ + struct port_bucket *ports_create_bucket (void); + ++/* Label BUCKET with LABEL. */ ++void ports_label_bucket (struct port_bucket *bucket, const char *label); ++ + /* Create and return a new port class. If nonzero, CLEAN_ROUTINE will + be called for each allocated port object in this class when it is + being destroyed. If nonzero, DROPWEAK_ROUTINE will be called +@@ -169,6 +176,12 @@ struct port_bucket *ports_create_bucket (void); + struct port_class *ports_create_class (void (*clean_routine)(void *), + void (*dropweak_routine)(void *)); + ++/* Label CLASS with LABEL. Use DEBUG_INFO to format human-readable ++ information about a given object belonging to CLASS into an buffer, ++ or the default formatting function if DEBUG_INFO is NULL. */ ++void ports_label_class (struct port_class *class, const char *label, ++ error_t (*debug_info) (const void *, char *, size_t)); ++ + /* Create and return in RESULT a new port in CLASS and BUCKET; SIZE bytes + will be allocated to hold the port structure and whatever private data the + user desires. */ +@@ -482,5 +495,6 @@ extern int _ports_flags; + void _ports_complete_deallocate (struct port_info *); + error_t _ports_create_port_internal (struct port_class *, struct port_bucket *, + size_t, void *, int); ++error_t _ports_trace_message (mach_port_t, const mach_msg_header_t *); + + #endif +diff --git a/tmpfs/Makefile b/tmpfs/Makefile +index fdcae34..fc27909 100644 +--- a/tmpfs/Makefile ++++ b/tmpfs/Makefile +@@ -23,7 +23,8 @@ target = tmpfs + SRCS = tmpfs.c node.c dir.c pager-stubs.c + OBJS = $(SRCS:.c=.o) default_pagerUser.o + # XXX The shared libdiskfs requires libstore even though we don't use it here. +-HURDLIBS = diskfs pager iohelp fshelp store ports ihash shouldbeinlibc ++HURDLIBS = diskfs pager iohelp fshelp store ports ihash introspection \ ++ shouldbeinlibc + OTHERLIBS = -lpthread + + include ../Makeconf +-- +2.1.4 + diff --git a/debian/patches/introspection0004-utils-implement-portinfo-query-process.patch b/debian/patches/introspection0004-utils-implement-portinfo-query-process.patch new file mode 100644 index 00000000..dfd095e9 --- /dev/null +++ b/debian/patches/introspection0004-utils-implement-portinfo-query-process.patch @@ -0,0 +1,168 @@ +From 6c2d3e9e3f4b30b3cea7df49db75272554a88c29 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 21 May 2014 17:38:46 +0200 +Subject: [PATCH hurd 4/9] utils: implement portinfo --query-process + +Implement portinfo --query-process (hopefully) as envisaged by a +comment in portinfo.c. We use the new Hurd server introspection +protocol to obtain information about the objects related to ports: + +% utils/portinfo --receive --query-process 5586 77 + 77: receive [bucket: diskfs_port_bucket, class: diskfs_protid_class, + node{inode: 48194, hard: 1, weak: 1}, + path: hello/hurd/developers_:)] + +* libshouldbeinlibc/Makefile (OBJS): Add hurd_portUser.o. +* libshouldbeinlibc/portinfo.c (show_portinfo_query): New function. +(print_port_info): Use show_portinfo_query if desired. +* libshouldbeinlibc/portinfo.h (PORTINFO_QUERY): New macro. +* utils/portinfo.c (argp_option): Drop #if 0. +(parse_opt): Handle --query-process. +--- + libshouldbeinlibc/Makefile | 2 +- + libshouldbeinlibc/portinfo.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ + libshouldbeinlibc/portinfo.h | 1 + + utils/portinfo.c | 3 +- + 4 files changed, 72 insertions(+), 3 deletions(-) + +diff --git a/libshouldbeinlibc/Makefile b/libshouldbeinlibc/Makefile +index 633d60e..a41a879 100644 +--- a/libshouldbeinlibc/Makefile ++++ b/libshouldbeinlibc/Makefile +@@ -36,6 +36,6 @@ installhdrs = idvec.h timefmt.h maptime.h \ + + installhdrsubdir = . + +-OBJS = $(SRCS:.c=.o) ++OBJS = $(SRCS:.c=.o) hurd_portUser.o + + include ../Makeconf +diff --git a/libshouldbeinlibc/portinfo.c b/libshouldbeinlibc/portinfo.c +index e6305c6..f99b789 100644 +--- a/libshouldbeinlibc/portinfo.c ++++ b/libshouldbeinlibc/portinfo.c +@@ -17,10 +17,77 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++#include <assert.h> ++#include <error.h> ++#include <string.h> + #include <sys/types.h> + #include <sys/mman.h> + + #include "portinfo.h" ++#include "hurd_port_U.h" ++ ++static void ++show_portinfo_query (mach_port_t task, mach_port_t name, ++ unsigned show, FILE *stream) ++{ ++ error_t err; ++ static mach_port_t introspection_port; ++ static mach_port_t for_task; ++ ++ if (task != for_task) ++ { ++ mach_port_t *ports; ++ size_t ports_len; ++ ++ err = mach_ports_lookup (task, &ports, &ports_len); ++ if (! err) ++ { ++ size_t i; ++ if (MACH_PORT_VALID (introspection_port)) ++ mach_port_deallocate (mach_task_self (), introspection_port); ++ ++ for (i = 0; i < ports_len; i++) ++ if (i == HURD_PORT_REGISTER_INTROSPECTION) ++ introspection_port = ports[i]; ++ else ++ { ++ if (MACH_PORT_VALID (ports[i])) ++ mach_port_deallocate (mach_task_self (), ports[i]); ++ } ++ } ++ else ++ introspection_port = MACH_PORT_DEAD; ++ ++ for_task = task; ++ } ++ ++ if (! MACH_PORT_VALID (introspection_port)) ++ return; ++ ++ string_t info; /* XXX */ ++ err = hurd_port_debug_info (introspection_port, name, 100, info); ++ if (err) ++ { ++ if (err != EINVAL) ++ error (0, err, "hurd_port_debug_info"); ++ return; ++ } ++ ++ if (strlen (info) > 0) ++ fprintf (stream, " [%s", info); ++ ++ if (show & PORTINFO_DETAILS) ++ { ++ unsigned int hard, weak; ++ err = hurd_port_get_refcounts (introspection_port, name, 100, ++ &hard, &weak); ++ if (! err) ++ fprintf (stream, ", hard: %u, weak: %u", hard, weak); ++ } ++ ++ fprintf (stream, "]"); ++} ++ + + /* Prints info about NAME in TASK to STREAM, in a way described by the flags + in SHOW. If TYPE is non-zero, it should be what mach_port_type returns +@@ -83,6 +150,8 @@ print_port_info (mach_port_t name, mach_port_type_t type, task_t task, + status.mps_nsrequest ? ", ns-req" : ""); + } + } ++ if (show & PORTINFO_QUERY) ++ show_portinfo_query (task, name, show, stream); + } + if (type & MACH_PORT_TYPE_SEND) + { +diff --git a/libshouldbeinlibc/portinfo.h b/libshouldbeinlibc/portinfo.h +index 143c289..bd96eb8 100644 +--- a/libshouldbeinlibc/portinfo.h ++++ b/libshouldbeinlibc/portinfo.h +@@ -31,6 +31,7 @@ + #define PORTINFO_DETAILS 0x1 + #define PORTINFO_MEMBERS 0x4 + #define PORTINFO_HEX_NAMES 0x8 ++#define PORTINFO_QUERY 0x10 + + /* Prints info about NAME in TASK to STREAM, in a way described by the flags + in SHOW. If TYPE is non-zero, it should be what mach_port_type returns +diff --git a/utils/portinfo.c b/utils/portinfo.c +index 4c40352..27998db 100644 +--- a/utils/portinfo.c ++++ b/utils/portinfo.c +@@ -44,10 +44,8 @@ static const struct argp_option options[] = { + {"verbose", 'v', 0, 0, "Give more detailed information"}, + {"members", 'm', 0, 0, "Show members of port-sets"}, + {"hex-names", 'x', 0, 0, "Show port names in hexadecimal"}, +-#if 0 /* XXX implement this */ + {"query-process", 'q', 0, 0, "Query the process itself for the identity of" + " the ports in question -- requires the process be in a sane state"}, +-#endif + {"hold", '*', 0, OPTION_HIDDEN}, + + {0,0,0,0, "Selecting which names to show:", 2}, +@@ -249,6 +247,7 @@ main (int argc, char **argv) + case 'v': show |= PORTINFO_DETAILS; break; + case 'm': show |= PORTINFO_MEMBERS; break; + case 'x': show |= PORTINFO_HEX_NAMES; break; ++ case 'q': show |= PORTINFO_QUERY; break; + + case 'r': only |= MACH_PORT_TYPE_RECEIVE; break; + case 's': only |= MACH_PORT_TYPE_SEND; break; +-- +2.1.4 + diff --git a/debian/patches/introspection0005-libdiskfs-annotate-objects-managed-by-libports.patch b/debian/patches/introspection0005-libdiskfs-annotate-objects-managed-by-libports.patch new file mode 100644 index 00000000..4c8c543e --- /dev/null +++ b/debian/patches/introspection0005-libdiskfs-annotate-objects-managed-by-libports.patch @@ -0,0 +1,107 @@ +From d3f069f39fae7a622e257e919ecfa8dd9c5a78d5 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 21 May 2014 18:17:33 +0200 +Subject: [PATCH hurd 5/9] libdiskfs: annotate objects managed by libports + +Label all port classes and diskfs_port_bucket. Provide +diskfs_format_debug_info which prints a human-readable description of +a protid object, which notably includes the path and the inode number. + +* libdiskfs/diskfs.h (diskfs_format_debug_info): New declaration. +* libdiskfs/init-init.c (diskfs_format_debug_info): New function. +(diskfs_init_diskfs): Add annotations to classes and bucket. +--- + libdiskfs/diskfs.h | 8 ++++++++ + libdiskfs/init-init.c | 41 ++++++++++++++++++++++++++++++++++++----- + 2 files changed, 44 insertions(+), 5 deletions(-) + +diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h +index 11fb0ad..c2f97ad 100644 +--- a/libdiskfs/diskfs.h ++++ b/libdiskfs/diskfs.h +@@ -591,6 +591,14 @@ error_t (*diskfs_read_symlink_hook)(struct node *np, char *target); + default function always returns EOPNOTSUPP. */ + error_t diskfs_get_source (struct protid *cred, + char *source, size_t source_len); ++ ++/* The user may define this function. The function must provide a ++ human-readable description of PROTID in BUFFER of size SIZE. The ++ default implementation generates a reasonable amount of ++ information. */ ++error_t diskfs_format_debug_info (const void *protid, ++ char *buffer, size_t size); ++ + + /* Libdiskfs contains a node cache. + +diff --git a/libdiskfs/init-init.c b/libdiskfs/init-init.c +index 357960b..07714f0 100644 +--- a/libdiskfs/init-init.c ++++ b/libdiskfs/init-init.c +@@ -24,6 +24,7 @@ + #include <hurd/fsys.h> + #include <stdio.h> + #include <maptime.h> ++#include <inttypes.h> + + /* For safe inlining of diskfs_node_disknode and + diskfs_disknode_node. */ +@@ -52,6 +53,29 @@ struct port_class *diskfs_shutdown_notification_class; + + struct port_bucket *diskfs_port_bucket; + ++/* Provide a human-readable description of the given protid object. */ ++error_t ++diskfs_format_debug_info (const void *port, char *buffer, size_t size) ++{ ++ const struct protid *protid = port; ++ const struct port_info *pi = port; ++ struct references references; ++ ++ refcounts_references (&protid->po->np->refcounts, &references); ++ ++ snprintf (buffer, size, ++ "bucket: %s, class: %s" ++ ", node{inode: %"PRIu64", hard: %u, weak: %u}, path: %s", ++ pi->bucket->label, ++ pi->class->label, ++ protid->po->np->cache_id, ++ references.hard, ++ references.weak, ++ protid->po->path); ++ ++ return 0; ++} ++ + /* Call this after arguments have been parsed to initialize the + library. */ + error_t +@@ -87,13 +111,20 @@ diskfs_init_diskfs (void) + + diskfs_auth_server_port = getauth (); + +- diskfs_protid_class = ports_create_class (diskfs_protid_rele, 0); +- diskfs_control_class = ports_create_class (_diskfs_control_clean, 0); +- diskfs_initboot_class = ports_create_class (0, 0); +- diskfs_execboot_class = ports_create_class (0, 0); +- diskfs_shutdown_notification_class = ports_create_class (0, 0); ++#define MAKE_CLASS(NAME, FN, ARG, DBG) \ ++ NAME = ports_create_class ((FN), (ARG)); \ ++ ports_label_class (NAME, #NAME, (DBG)) ++ ++ MAKE_CLASS (diskfs_protid_class, diskfs_protid_rele, NULL, ++ diskfs_format_debug_info); ++ MAKE_CLASS (diskfs_control_class, _diskfs_control_clean, NULL, NULL); ++ MAKE_CLASS (diskfs_initboot_class, NULL, NULL, NULL); ++ MAKE_CLASS (diskfs_execboot_class, NULL, NULL, NULL); ++ MAKE_CLASS (diskfs_shutdown_notification_class, NULL, NULL, NULL); ++#undef MAKE_CLASS + + diskfs_port_bucket = ports_create_bucket (); ++ ports_label_bucket (diskfs_port_bucket, "diskfs_port_bucket"); + + _hurd_port_init (&_diskfs_exec_portcell, MACH_PORT_NULL); + +-- +2.1.4 + diff --git a/debian/patches/introspection0006-libpager-annotate-objects-managed-by-libports.patch b/debian/patches/introspection0006-libpager-annotate-objects-managed-by-libports.patch new file mode 100644 index 00000000..844bba57 --- /dev/null +++ b/debian/patches/introspection0006-libpager-annotate-objects-managed-by-libports.patch @@ -0,0 +1,61 @@ +From 2423b4906a7bcee05ce776364979d5ca9090fd99 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 21 May 2014 18:33:14 +0200 +Subject: [PATCH hurd 6/9] libpager: annotate objects managed by libports + +Label _pager_class and provide a function which prints a +human-readable description of a pager object. + +* libpager/pager-create.c (format_debug_info): New function. +(create_class): Label _pager_class. +--- + libpager/pager-create.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/libpager/pager-create.c b/libpager/pager-create.c +index b583f02..422e8f4 100644 +--- a/libpager/pager-create.c ++++ b/libpager/pager-create.c +@@ -15,6 +15,8 @@ + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + ++#include <stdio.h> ++ + #include "priv.h" + + /* Create and return a new pager with user info UPI. */ +@@ -50,6 +52,23 @@ pager_create (struct user_pager_info *upi, + return p; + } + ++/* Provide a human-readable description of the given pager object. */ ++static error_t ++format_debug_info (const void *port, char *buffer, size_t size) ++{ ++ const struct pager *pager = port; ++ const struct port_info *pi = port; ++ ++ snprintf (buffer, size, ++ "bucket: %s, class: %s, may_cache: %d", ++ pi->bucket->label, ++ pi->class->label, ++ /* XXX I have no idea what might be interesting to print ++ here, but it is straight forward to add stuff. */ ++ pager->may_cache); ++ ++ return 0; ++} + + /* This causes the function to be run at startup by compiler magic. */ + static void create_class (void) __attribute__ ((constructor)); +@@ -58,5 +77,6 @@ static void + create_class () + { + _pager_class = ports_create_class (_pager_clean, _pager_real_dropweak); ++ ports_label_class (_pager_class, "_pager_class", format_debug_info); + (void) &create_class; /* Avoid warning */ + } +-- +2.1.4 + diff --git a/debian/patches/introspection0007-ext2fs-annotate-objects-managed-by-libports.patch b/debian/patches/introspection0007-ext2fs-annotate-objects-managed-by-libports.patch new file mode 100644 index 00000000..09117381 --- /dev/null +++ b/debian/patches/introspection0007-ext2fs-annotate-objects-managed-by-libports.patch @@ -0,0 +1,99 @@ +From 9c8ddc2ff667a9d7482676eadfa321d4efb97297 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Wed, 21 May 2014 18:39:38 +0200 +Subject: [PATCH hurd 7/9] ext2fs: annotate objects managed by libports + +Install a specialized version of libpagers format_debug_info which +prints more detailed information, like the nodes inode number for file +pager objects. Also label both pager buckets. + +* ext2fs/pager-create.c (format_debug_info): New function. +(create_disk_pager): Install our own format_debug_info function. +Label both pager buckets. +--- + ext2fs/pager.c | 38 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/ext2fs/pager.c b/ext2fs/pager.c +index 3e080f8..b737ba7 100644 +--- a/ext2fs/pager.c ++++ b/ext2fs/pager.c +@@ -19,10 +19,12 @@ + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include <unistd.h> ++#include <stdio.h> + #include <string.h> + #include <errno.h> + #include <error.h> + #include <hurd/store.h> ++#include <inttypes.h> + #include "ext2fs.h" + + /* XXX */ +@@ -1196,6 +1198,38 @@ disk_cache_block_is_ref (block_t block) + return ref; + } + ++/* Provide a human-readable description of the given pager object. */ ++static error_t ++format_debug_info (const void *port, char *buffer, size_t size) ++{ ++ const struct pager *pager = port; ++ const struct port_info *pi = port; ++ ++ if (pager->upi->type == FILE_DATA) ++ { ++ struct references references; ++ refcounts_references (&pager->upi->node->refcounts, &references); ++ snprintf (buffer, size, ++ "bucket: %s, class: %s, " ++ "node{inode: %"PRIu64", hard: %u, weak: %u}", ++ pi->bucket->label, ++ pi->class->label, ++ pager->upi->node->cache_id, ++ references.hard, ++ references.weak); ++ } ++ else ++ snprintf (buffer, size, ++ "bucket: %s, class: %s, may_cache: %d", ++ pi->bucket->label, ++ pi->class->label, ++ /* XXX I have no idea what might be interesting to print ++ here, but it is straight forward to add stuff. */ ++ pager->may_cache); ++ ++ return 0; ++} ++ + /* Create the disk pager, and the file pager. */ + void + create_disk_pager (void) +@@ -1204,12 +1238,15 @@ create_disk_pager (void) + pthread_attr_t attr; + error_t err; + ++ ports_label_class (_pager_class, "_pager_class", format_debug_info); ++ + /* The disk pager. */ + struct user_pager_info *upi = malloc (sizeof (struct user_pager_info)); + if (!upi) + ext2_panic ("can't create disk pager: %s", strerror (errno)); + upi->type = DISK; + disk_pager_bucket = ports_create_bucket (); ++ ports_label_bucket (disk_pager_bucket, "disk_pager_bucket"); + get_hypermetadata (); + disk_cache_blocks = DISK_CACHE_BLOCKS; + disk_cache_size = disk_cache_blocks << log2_block_size; +@@ -1219,6 +1256,7 @@ create_disk_pager (void) + + /* The file pager. */ + file_pager_bucket = ports_create_bucket (); ++ ports_label_bucket (file_pager_bucket, "file_pager_bucket"); + + /* Start libpagers worker threads. */ + err = pager_start_workers (file_pager_bucket, &file_pager_requests); +-- +2.1.4 + diff --git a/debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch b/debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch new file mode 100644 index 00000000..0a8b0260 --- /dev/null +++ b/debian/patches/introspection0008-utils-rpctrace-support-attaching-to-servers.patch @@ -0,0 +1,373 @@ +From 5a4a5c0807ce9b90b36e21032d5ff268b4a71f6f Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Fri, 23 May 2014 08:42:45 +0200 +Subject: [PATCH hurd 8/9] utils/rpctrace: support attaching to servers + +* utils/rpctrace.c (options): Add `--pid' and `--reference-port'. +(print_contents): Prevent the translation of rights if `req' is NULL. +We will use this to print messages in `trace_server'. +(parse_task): New function. +(trace_server): Mach server function that displays relayed messages. +(trace_class_rpcs): New function that attaches to a server and starts +tracing. +(parse_opt): Handle `--pid' and `--reference-port'. +(main): Handle new arguments, call trace_class_rpcs if desired. +--- + utils/Makefile | 5 +- + utils/rpctrace.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 2 files changed, 248 insertions(+), 3 deletions(-) + +diff --git a/utils/Makefile b/utils/Makefile +index 955789b..352494a 100644 +--- a/utils/Makefile ++++ b/utils/Makefile +@@ -34,7 +34,7 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \ + nullauth.c match-options.c msgids.c rpcscan.c + + OBJS = $(filter-out %.sh,$(SRCS:.c=.o)) +-HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc ++HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc introspection + LDLIBS += -lpthread + login-LDLIBS = -lutil -lcrypt + addauth-LDLIBS = -lcrypt +@@ -67,7 +67,8 @@ ps w ids settrans syncfs showtrans fsysopts storeinfo login vmstat portinfo \ + + $(filter-out $(special-targets), $(targets)): %: %.o + +-rpctrace: ../libports/libports.a ++rpctrace: ../libports/libports.a \ ++ ../libintrospection/libintrospection.a hurd_portUser.o + rpctrace rpcscan: msgids.o \ + ../libihash/libihash.a + msgids-CPPFLAGS = -DDATADIR=\"${datadir}\" +diff --git a/utils/rpctrace.c b/utils/rpctrace.c +index d53b510..64c171a 100644 +--- a/utils/rpctrace.c ++++ b/utils/rpctrace.c +@@ -23,6 +23,7 @@ + #include <hurd.h> + #include <hurd/ports.h> + #include <hurd/ihash.h> ++#include <hurd/introspection.h> + #include <mach/message.h> + #include <assert.h> + #include <fcntl.h> +@@ -40,14 +41,22 @@ + #include <envz.h> + + #include "msgids.h" ++#include "hurd_port_U.h" + + const char *argp_program_version = STANDARD_HURD_VERSION (rpctrace); + + static unsigned strsize = 80; ++static int trace_class; + + static const struct argp_option options[] = + { + {"output", 'o', "FILE", 0, "Send trace output to FILE instead of stderr."}, ++ {"pid", 'p', "PID", 0, "Attach to PID and trace all requests to objects " ++ "of the same class as the given reference port. This will only work " ++ "for Hurd servers implementing the introspection protocol."}, ++ {"port", 'P', "PORT", 0, "Trace all requests PORT. " ++ "PORT must denote a receive right in PID."}, ++ {"class", 'c', NULL, 0, "Trace all requests to the same class as PORT."}, + {0, 's', "SIZE", 0, "Specify the maximum string size to print (the default is 80)."}, + {0, 'E', "var[=value]", 0, + "Set/change (var=value) or remove (var) an environment variable among the " +@@ -852,7 +861,7 @@ print_contents (mach_msg_header_t *inp, + what task that port name is meaningful in. If it's meaningful in + a traced task, then it refers to our intercepting port rather than + the original port anyway. */ +- if (MACH_MSG_TYPE_PORT_ANY_RIGHT (name)) ++ if (MACH_MSG_TYPE_PORT_ANY_RIGHT (name) && req != NULL) + { + /* These are port rights. Translate them into wrappers. */ + mach_port_t *const portnames = data; +@@ -1669,10 +1678,218 @@ traced_spawn (char **argv, char **envp) + + return pid; + } ++ ++/* Return the task corresponding to the user argument ARG, exiting with an ++ appriate error message if we can't. */ ++static task_t ++parse_task (char *arg) ++{ ++ error_t err; ++ task_t task; ++ char *arg_end; ++ pid_t pid = strtoul (arg, &arg_end, 10); ++ static process_t proc = MACH_PORT_NULL; ++ ++ if (*arg == '\0' || *arg_end != '\0') ++ error (10, 0, "%s: Invalid process id", arg); ++ ++ if (proc == MACH_PORT_NULL) ++ proc = getproc (); ++ ++ err = proc_pid2task (proc, pid, &task); ++ if (err) ++ error (11, err, "%s", arg); ++ else if (task == MACH_PORT_NULL) ++ error (11, 0, "%s: Process %d is dead and has no task", arg, (int) pid); ++ ++ return task; ++} ++ ++static mach_port_t trace_notification_port; ++static mach_port_t reference_port; ++ ++boolean_t ++trace_server (mach_msg_header_t *inp, ++ mach_msg_header_t *outp) ++{ ++ error_t err; ++ static struct hurd_ihash ongoing_requests = ++ HURD_IHASH_INITIALIZER (HURD_IHASH_NO_LOCP); ++ struct msgid_info *info; ++ mach_port_t trace_id; ++ int is_reply; ++ ++ if (inp->msgh_local_port == trace_notification_port ++ && inp->msgh_id == MACH_NOTIFY_NO_SENDERS) ++ { ++ error (0, 0, "The tracee vanished."); ++ exit (EXIT_SUCCESS); ++ } ++ ++ err = introspection_extract_message (inp, &trace_id); ++ if (err) ++ { ++ error (0, err, "introspection_extract_message"); ++ goto out; ++ } ++ info = msgid_info (inp->msgh_id); ++ ++ /* XXX This hardcodes an assumption about reply message ids. */ ++ is_reply = (inp->msgh_id / 100) % 2 == 1; ++ if (is_reply) ++ { ++ /* This looks like a traced reply or a pseudo-reply. A ++ pseudo-reply is a message containing the result of a simple ++ procedure that is only sent to us. */ ++ mig_reply_header_t *reply = (mig_reply_header_t *) inp; ++ ++ mach_port_t request_port; ++ request_port = hurd_ihash_find (&ongoing_requests, trace_id); ++ if (! MACH_PORT_VALID (request_port)) ++ { ++ fprintf (stderr, "unsolicited reply packet with id: %d\n", ++ trace_id); ++ goto out; ++ } ++ hurd_ihash_remove (&ongoing_requests, trace_id); ++ ++ if (! (trace_class || request_port == reference_port)) ++ goto out; ++ ++ if (last_reply_port != trace_id) ++ { ++ print_ellipsis (); ++ fprintf (ostream, "%u...", (unsigned int) trace_id); ++ } ++ last_reply_port = MACH_PORT_NULL; ++ ++ fprintf (ostream, " = "); ++ ++ if (reply->RetCode == 0) ++ fprintf (ostream, "0"); ++ else ++ { ++ const char *str = strerror (reply->RetCode); ++ if (str == 0) ++ fprintf (ostream, "%#x", reply->RetCode); ++ else ++ fprintf (ostream, "%#x (%s)", reply->RetCode, str); ++ } ++ ++ if (inp->msgh_size > sizeof *reply) ++ { ++ fprintf (ostream, " "); ++ print_contents (inp, (void *) inp + sizeof *reply, NULL); ++ } ++ fprintf (ostream, "\n"); ++ } ++ else ++ { ++ /* Remember the request port. */ ++ hurd_ihash_add (&ongoing_requests, trace_id, inp->msgh_local_port); ++ ++ if (! (trace_class || inp->msgh_local_port == reference_port)) ++ goto out; ++ ++ /* This looks like a traced request. */ ++ print_ellipsis (); ++ last_reply_port = trace_id; ++ ++ if (info) ++ fprintf (ostream, "% 4d->%s (", inp->msgh_local_port, info->name); ++ else ++ fprintf (ostream, "% 4d->%d (", inp->msgh_local_port, inp->msgh_id); ++ ++ print_contents (inp, (void *) inp + sizeof *inp, NULL); ++ fprintf (ostream, ")"); ++ } ++ ++ out: ++ /* vm_deallocate any out-of-band memory. */ ++ mach_msg_destroy (inp); ++ ++ /* Prevent mach_msg_server from sending messages. */ ++ ((mig_reply_header_t *) outp)->RetCode = MIG_NO_REPLY; ++ return TRUE; ++} ++ ++int ++trace_class_rpcs (mach_port_t task, ++ mach_port_t name) ++{ ++ error_t err; ++ mach_port_t trace_port; ++ mach_port_t introspection_port; ++ mach_port_t previous; ++ mach_port_t port_set; ++ ++ err = introspection_get_port (task, &introspection_port); ++ if (err) ++ error (13, err, "Failed to get introspection port"); ++ ++ if (! MACH_PORT_VALID (introspection_port)) ++ error (13, 0, "The server does not implement the introspection protocol"); ++ ++ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, ++ &trace_port); ++ if (err) ++ error (13, err, "mach_port_allocate"); ++ ++ err = hurd_port_trace_class_rpcs (introspection_port, name, ++ trace_port, MACH_MSG_TYPE_MAKE_SEND); ++ if (err) ++ { ++ if (err == EINVAL) ++ error (13, 0, ++ "%d does not denote a receive right managed by libports", name); ++ else ++ error (13, err, "hurd_port_trace_class_rpcs"); ++ } ++ ++ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE, ++ &trace_notification_port); ++ if (err) ++ error (13, err, "mach_port_allocate"); ++ ++ err = mach_port_request_notification (mach_task_self (), ++ trace_port, ++ MACH_NOTIFY_NO_SENDERS, ++ 0, ++ trace_notification_port, ++ MACH_MSG_TYPE_MAKE_SEND_ONCE, ++ &previous); ++ if (err) ++ error (13, err, "mach_port_request_notification"); ++ assert (! MACH_PORT_VALID (previous)); ++ ++ ++ err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_PORT_SET, ++ &port_set); ++ if (err) ++ error (13, err, "mach_port_allocate"); ++ ++ err = mach_port_move_member (mach_task_self (), trace_port, port_set); ++ if (err) ++ error (13, err, "mach_port_move_member"); + ++ err = mach_port_move_member (mach_task_self (), trace_notification_port, ++ port_set); ++ if (err) ++ error (13, err, "mach_port_move_member"); ++ ++ error (0, 0, "entering service loop"); ++ while (1) ++ mach_msg_server (trace_server, 0, port_set); ++ ++ /* Not reached. */ ++ return 0; ++} ++ + int + main (int argc, char **argv, char **envp) + { ++ mach_port_t target_task = MACH_PORT_NULL; ++ bool nostdinc = FALSE; + const char *outfile = 0; + char **cmd_argv = 0; + pthread_t thread; +@@ -1684,12 +1901,27 @@ main (int argc, char **argv, char **envp) + /* Parse our options... */ + error_t parse_opt (int key, char *arg, struct argp_state *state) + { ++ char *arg_end; + switch (key) + { + case 'o': + outfile = arg; + break; + ++ case 'p': ++ target_task = parse_task (arg); ++ break; ++ ++ case 'P': ++ reference_port = strtoul (arg, &arg_end, 10); ++ if (*arg == '\0' || *arg_end != '\0') ++ argp_error (state, "Invalid port name: %s", arg); ++ break; ++ ++ case 'c': ++ trace_class = 1; ++ break; ++ + case 's': + strsize = atoi (arg); + break; +@@ -1723,10 +1955,16 @@ main (int argc, char **argv, char **envp) + break; + + case ARGP_KEY_NO_ARGS: ++ if (MACH_PORT_VALID (target_task)) ++ break; ++ + argp_usage (state); + return EINVAL; + + case ARGP_KEY_ARG: ++ if (MACH_PORT_VALID (target_task)) ++ argp_error (state, "Superfluous argument: %s", arg); ++ + cmd_argv = &state->argv[state->next - 1]; + state->next = state->argc; + break; +@@ -1746,6 +1984,9 @@ main (int argc, char **argv, char **envp) + /* Parse our arguments. */ + argp_parse (&argp, argc, argv, ARGP_IN_ORDER, 0, 0); + ++ if (MACH_PORT_VALID (target_task) != MACH_PORT_VALID (reference_port)) ++ error (10, 0, "Please specify either both -p and -P, or neither."); ++ + err = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_DEAD_NAME, + &unknown_task); + assert_perror (err); +@@ -1760,6 +2001,9 @@ main (int argc, char **argv, char **envp) + ostream = stderr; + setlinebuf (ostream); + ++ if (MACH_PORT_VALID (target_task)) ++ return trace_class_rpcs (target_task, reference_port); ++ + traced_bucket = ports_create_bucket (); + traced_class = ports_create_class (&traced_clean, NULL); + other_class = ports_create_class (0, 0); +-- +2.1.4 + diff --git a/debian/patches/introspection0009-fixup_libports.patch b/debian/patches/introspection0009-fixup_libports.patch new file mode 100644 index 00000000..afdd0456 --- /dev/null +++ b/debian/patches/introspection0009-fixup_libports.patch @@ -0,0 +1,122 @@ +From c899d36cf0358036428e0f545da0ea1bff812022 Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Thu, 24 Sep 2015 18:23:28 +0200 +Subject: [PATCH hurd 9/9] fixup_libports + +--- + libports/introspection.c | 35 ++++++++++++++++++++--------------- + libports/manage-multithread.c | 6 ++++-- + libports/manage-one-thread.c | 6 ++++-- + libports/ports.h | 1 + + 4 files changed, 29 insertions(+), 19 deletions(-) + +diff --git a/libports/introspection.c b/libports/introspection.c +index 912c768..07f8624 100644 +--- a/libports/introspection.c ++++ b/libports/introspection.c +@@ -71,24 +71,29 @@ service_introspection_requests (void *arg) + return NULL; + } + +-/* Start the introspection server before main is called. */ +-static void __attribute__ ((constructor)) +-init (void) ++/* Start the introspection server if it is not already running. */ ++void ++_ports_start_introspection_server (void) + { ++ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; ++ static int initialized = 0; + error_t err; +- + pthread_t thread; +- pthread_attr_t attr; +-#define STACK_SIZE (64 * 1024) +- pthread_attr_init (&attr); +- pthread_attr_setstacksize (&attr, STACK_SIZE); +-#undef STACK_SIZE +- +- err = pthread_create (&thread, &attr, +- service_introspection_requests, NULL); +- if (err) +- error (1, err, "pthread_create"); +- pthread_detach (thread); ++ ++ pthread_mutex_lock (&lock); ++ if (! initialized) ++ { ++ err = pthread_create (&thread, NULL, ++ service_introspection_requests, NULL); ++ if (err) ++ error (0, err, "Error starting introspection server"); ++ else ++ { ++ pthread_detach (thread); ++ initialized = 1; ++ } ++ } ++ pthread_mutex_unlock (&lock); + } + + /* Return the number of hard and weak references of the object +diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c +index 8707d98..d2e7dbe 100644 +--- a/libports/manage-multithread.c ++++ b/libports/manage-multithread.c +@@ -214,8 +214,7 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, + } + ports_port_deref (pi); + +- if (__builtin_expect (MACH_PORT_VALID (trace_port), 0) +- && outp->RetCode != MIG_NO_REPLY) ++ if (__builtin_expect (MACH_PORT_VALID (trace_port), 0)) + introspection_trace_message (trace_port, outp, trace_id); + } + else +@@ -291,5 +290,8 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, + master thread from going away. */ + global_timeout = 0; + ++ /* Make sure the introspection server is running. */ ++ _ports_start_introspection_server (); ++ + thread_function ((void *) 1); + } +diff --git a/libports/manage-one-thread.c b/libports/manage-one-thread.c +index 55aa378..86d575e 100644 +--- a/libports/manage-one-thread.c ++++ b/libports/manage-one-thread.c +@@ -104,8 +104,7 @@ ports_manage_port_operations_one_thread (struct port_bucket *bucket, + } + ports_port_deref (pi); + +- if (__builtin_expect (MACH_PORT_VALID (trace_port), 0) +- && outp->RetCode != MIG_NO_REPLY) ++ if (__builtin_expect (MACH_PORT_VALID (trace_port), 0)) + introspection_trace_message (trace_port, outp, trace_id); + } + else +@@ -125,6 +124,9 @@ ports_manage_port_operations_one_thread (struct port_bucket *bucket, + zero. */ + timeout = 0; + ++ /* Make sure the introspection server is running. */ ++ _ports_start_introspection_server (); ++ + _ports_thread_online (&bucket->threadpool, &thread); + do + err = mach_msg_server_timeout (internal_demuxer, 0, bucket->portset, +diff --git a/libports/ports.h b/libports/ports.h +index a31b894..e61b38c 100644 +--- a/libports/ports.h ++++ b/libports/ports.h +@@ -496,5 +496,6 @@ void _ports_complete_deallocate (struct port_info *); + error_t _ports_create_port_internal (struct port_class *, struct port_bucket *, + size_t, void *, int); + error_t _ports_trace_message (mach_port_t, const mach_msg_header_t *); ++void _ports_start_introspection_server (void); + + #endif +-- +2.1.4 + diff --git a/debian/patches/series b/debian/patches/series index 08c3dc14..9150b813 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -63,3 +63,12 @@ exec_filename0001-Add-a-new-exec_exec_file_name-RPC.patch exec_filename0002-Add-a-file_exec_file_name-RPC.patch exec_filename0003-Use-the-new-_hurd_exec_file_name-function.patch exec_filename0004-This-patch-is-an-amendment-of-exec_filename_exec.pat.patch +introspection0001-hurd-add-an-Hurd-server-introspection-protocol.patch +introspection0002-libintrospection-a-library-for-Hurd-server-introspec.patch +introspection0003-libports-implement-the-Hurd-server-introspection-pro.patch +introspection0004-utils-implement-portinfo-query-process.patch +introspection0005-libdiskfs-annotate-objects-managed-by-libports.patch +introspection0006-libpager-annotate-objects-managed-by-libports.patch +introspection0007-ext2fs-annotate-objects-managed-by-libports.patch +introspection0008-utils-rpctrace-support-attaching-to-servers.patch +introspection0009-fixup_libports.patch |