diff options
Diffstat (limited to 'debian/patches/introspection0003-libports-implement-the-Hurd-server-introspection-pro.patch')
-rw-r--r-- | debian/patches/introspection0003-libports-implement-the-Hurd-server-introspection-pro.patch | 481 |
1 files changed, 481 insertions, 0 deletions
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..43d8f846 --- /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 03/10] 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 + |