diff options
Diffstat (limited to 'debian/patches/0023-libports-implement-the-Hurd-server-introspection-pro.patch')
-rw-r--r-- | debian/patches/0023-libports-implement-the-Hurd-server-introspection-pro.patch | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/debian/patches/0023-libports-implement-the-Hurd-server-introspection-pro.patch b/debian/patches/0023-libports-implement-the-Hurd-server-introspection-pro.patch new file mode 100644 index 00000000..243f5a96 --- /dev/null +++ b/debian/patches/0023-libports-implement-the-Hurd-server-introspection-pro.patch @@ -0,0 +1,328 @@ +From d494a068b98f79a7c454802a52eddbff3350acbc 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 23/27] 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/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. +--- + libports/Makefile | 4 +- + libports/create-bucket.c | 7 ++ + libports/create-class.c | 15 ++++ + libports/introspection.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++ + libports/ports.h | 12 ++++ + 5 files changed, 218 insertions(+), 2 deletions(-) + create mode 100644 libports/introspection.c + +diff --git a/libports/Makefile b/libports/Makefile +index 30da1c1..6c7f5df 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 ++ interrupted.c introspection.c + + installhdrs = ports.h + + HURDLIBS= ihash + 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 2c5f1b6..51168cb 100644 +--- a/libports/create-bucket.c ++++ b/libports/create-bucket.c +@@ -48,5 +48,12 @@ ports_create_bucket () + + hurd_ihash_init (&ret->htable, offsetof (struct port_info, hentry)); + ret->rpcs = ret->flags = ret->count = 0; ++ 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..fbce9d9 100644 +--- a/libports/create-class.c ++++ b/libports/create-class.c +@@ -41,6 +41,21 @@ 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"; + + return cl; + } ++ ++/* Label BUCKET 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_set_debug_info (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..dcebd6b +--- /dev/null ++++ b/libports/introspection.c +@@ -0,0 +1,182 @@ ++/* 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 <mach/mach_param.h> ++#include <pthread.h> ++#include <stdio.h> ++#include <string.h> ++ ++#include "ports.h" ++#include "hurd_port_S.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; ++ mach_port_t *ports; ++ size_t ports_len; ++ ++ 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 = mach_ports_lookup (mach_task_self (), ++ &ports, &ports_len); ++ if (err) ++ { ++ error (0, err, "mach_ports_lookup"); ++ return NULL; ++ } ++ ++ ports[HURD_PORT_REGISTER_INTROSPECTION] = introspection_port; ++ ++ err = mach_ports_register (mach_task_self (), ++ ports, ++ HURD_PORT_REGISTER_MAX); ++ if (err) ++ { ++ error (0, err, "mach_ports_register"); ++ 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] = 0; ++ ++ ports_port_deref (pi); ++ return err; ++} +diff --git a/libports/ports.h b/libports/ports.h +index 3439443..18eb5cb 100644 +--- a/libports/ports.h ++++ b/libports/ports.h +@@ -65,6 +65,7 @@ struct port_bucket + int rpcs; + int flags; + int count; ++ const char *label; + }; + /* FLAGS above are the following: */ + #define PORT_BUCKET_INHIBITED PORTS_INHIBITED +@@ -80,7 +81,9 @@ 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; + }; + /* FLAGS are the following: */ + #define PORT_CLASS_INHIBITED PORTS_INHIBITED +@@ -149,6 +152,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 +@@ -158,6 +164,12 @@ struct port_bucket *ports_create_bucket (void); + struct port_class *ports_create_class (void (*clean_routine)(void *), + void (*dropweak_routine)(void *)); + ++/* Label BUCKET 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_set_debug_info (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. */ +-- +2.0.0.rc2 + |