diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-09-16 00:17:32 +0000 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2013-09-16 00:17:32 +0000 |
commit | ebb437fb4b27fa565b9aebb05cda1e9db4ec17ff (patch) | |
tree | 15598d7d3bfc6ba837e6a5ab3c419f9ac17a2438 | |
parent | 9ad092a877c6256a425be4f54cbb66382d6762bf (diff) |
New upstream snapshot
-rw-r--r-- | devnode/devnode.c | 10 | ||||
-rw-r--r-- | procfs/ChangeLog | 6 | ||||
-rw-r--r-- | procfs/main.c | 165 | ||||
-rw-r--r-- | procfs/process.c | 24 | ||||
-rw-r--r-- | procfs/rootdir.c | 49 | ||||
-rw-r--r-- | ufs/pager.c | 11 |
6 files changed, 223 insertions, 42 deletions
diff --git a/devnode/devnode.c b/devnode/devnode.c index 50011aa4..218b3081 100644 --- a/devnode/devnode.c +++ b/devnode/devnode.c @@ -164,6 +164,16 @@ ds_device_open (mach_port_t master_port, mach_port_t reply_port, || device_name == NULL) return D_NO_SUCH_DEVICE; + if (master_file != NULL) + { + if (master_device != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), master_device); + + master_device = file_name_lookup (master_file, 0, 0); + if (master_device == MACH_PORT_NULL) + error (1, errno, "file_name_lookup"); + } + err = device_open (master_device, mode, device_name, device); *devicetype = MACH_MSG_TYPE_MOVE_SEND; return err; diff --git a/procfs/ChangeLog b/procfs/ChangeLog new file mode 100644 index 00000000..0cd74d02 --- /dev/null +++ b/procfs/ChangeLog @@ -0,0 +1,6 @@ +edb4593c38d421b5d538b221a991b50c36fdba15 is the last commit imported from CVS. +All commits after that one have valid author and committer information. + +Use this to examine the change log for earlier changes: + + $ git show edb4593c38d421b5d538b221a991b50c36fdba15:ChangeLog diff --git a/procfs/main.c b/procfs/main.c index 90b3e92c..54e96823 100644 --- a/procfs/main.c +++ b/procfs/main.c @@ -22,6 +22,7 @@ #include <unistd.h> #include <error.h> #include <argp.h> +#include <argz.h> #include <hurd/netfs.h> #include <ps.h> #include "procfs.h" @@ -37,6 +38,13 @@ pid_t opt_fake_self; pid_t opt_kernel_pid; uid_t opt_anon_owner; +/* Default values */ +#define OPT_CLK_TCK sysconf(_SC_CLK_TCK) +#define OPT_STAT_MODE 0400 +#define OPT_FAKE_SELF -1 +#define OPT_KERNEL_PID 2 +#define OPT_ANON_OWNER 0 + #define NODEV_KEY -1 /* <= 0, so no short option. */ #define NOEXEC_KEY -2 /* Likewise. */ #define NOSUID_KEY -3 /* Likewise. */ @@ -120,50 +128,90 @@ argp_parser (int key, char *arg, struct argp_state *state) case NOSUID_KEY: /* Ignored for compatibility with Linux' procfs. */ ;; + + default: + return ARGP_ERR_UNKNOWN; } return 0; } +struct argp_option common_options[] = { + { "clk-tck", 'h', "HZ", 0, + "Unit used for the values expressed in system clock ticks " + "(default: sysconf(_SC_CLK_TCK))" }, + { "stat-mode", 's', "MODE", 0, + "The [pid]/stat file publishes information which on Hurd is only " + "available to the process owner. " + "You can use this option to override its mode to be more permissive " + "for compatibility purposes. " + "(default: 0400)" }, + { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL, + "Provide a fake \"self\" symlink to the given PID, for compatibility " + "purposes. If PID is omitted, \"self\" will point to init. " + "(default: no self link)" }, + { "kernel-process", 'k', "PID", 0, + "Process identifier for the kernel, used to retreive its command " + "line, as well as the global up and idle times. " + "(default: 2)" }, + { "compatible", 'c', NULL, 0, + "Try to be compatible with the Linux procps utilities. " + "Currently equivalent to -h 100 -s 0444 -S 1." }, + { "anonymous-owner", 'a', "USER", 0, + "Make USER the owner of files related to processes without one. " + "Be aware that USER will be granted access to the environment and " + "other sensitive information about the processes in question. " + "(default: use uid 0)" }, + { "nodev", NODEV_KEY, NULL, 0, + "Ignored for compatibility with Linux' procfs." }, + { "noexec", NOEXEC_KEY, NULL, 0, + "Ignored for compatibility with Linux' procfs." }, + { "nosuid", NOSUID_KEY, NULL, 0, + "Ignored for compatibility with Linux' procfs." }, + {} +}; + struct argp argp = { - .options = (struct argp_option []) { - { "clk-tck", 'h', "HZ", 0, - "Unit used for the values expressed in system clock ticks " - "(default: sysconf(_SC_CLK_TCK))" }, - { "stat-mode", 's', "MODE", 0, - "The [pid]/stat file publishes information which on Hurd is only " - "available to the process owner. " - "You can use this option to override its mode to be more permissive " - "for compatibility purposes. " - "(default: 0400)" }, - { "fake-self", 'S', "PID", OPTION_ARG_OPTIONAL, - "Provide a fake \"self\" symlink to the given PID, for compatibility " - "purposes. If PID is omitted, \"self\" will point to init. " - "(default: no self link)" }, - { "kernel-process", 'k', "PID", 0, - "Process identifier for the kernel, used to retreive its command " - "line, as well as the global up and idle times. " - "(default: 2)" }, - { "compatible", 'c', NULL, 0, - "Try to be compatible with the Linux procps utilities. " - "Currently equivalent to -h 100 -s 0444 -S 1." }, - { "anonymous-owner", 'a', "USER", 0, - "Make USER the owner of files related to processes without one. " - "Be aware that USER will be granted access to the environment and " - "other sensitive information about the processes in question. " - "(default: use uid 0)" }, - { "nodev", NODEV_KEY, NULL, 0, - "Ignored for compatibility with Linux' procfs." }, - { "noexec", NOEXEC_KEY, NULL, 0, - "Ignored for compatibility with Linux' procfs." }, - { "nosuid", NOSUID_KEY, NULL, 0, - "Ignored for compatibility with Linux' procfs." }, + .options = common_options, + .parser = argp_parser, + .doc = "A virtual filesystem emulating the Linux procfs.", + .children = (struct argp_child []) { + { &netfs_std_startup_argp, }, {} }, +}; + +static error_t +runtime_argp_parser (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case 'u': + /* do nothing */ + break; + + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +struct argp runtime_argp = { + .options = (struct argp_option []) { + { "update", 'u', NULL, 0, "remount; for procfs this does nothing" }, + {}, + }, + .parser = runtime_argp_parser, +}; + +struct argp netfs_runtime_argp_ = { + .options = common_options, .parser = argp_parser, .doc = "A virtual filesystem emulating the Linux procfs.", .children = (struct argp_child []) { - { &netfs_std_startup_argp, }, + { &runtime_argp, }, + { &netfs_std_runtime_argp, }, {} }, }; @@ -171,6 +219,47 @@ struct argp argp = { /* Used by netfs_set_options to handle runtime option parsing. */ struct argp *netfs_runtime_argp = &argp; +/* Return an argz string describing the current options. Fill *ARGZ + with a pointer to newly malloced storage holding the list and *LEN + to the length of that storage. */ +error_t +netfs_append_args (char **argz, size_t *argz_len) +{ + char buf[80]; + error_t err = 0; + +#define FOPT(opt, default, fmt, args...) \ + do { \ + if (! err && opt != default) \ + { \ + snprintf (buf, sizeof buf, fmt, ## args); \ + err = argz_add (argz, argz_len, buf); \ + } \ + } while (0) + + FOPT (opt_clk_tck, OPT_CLK_TCK, + "--clk-tck=%d", opt_clk_tck); + + FOPT (opt_stat_mode, OPT_STAT_MODE, + "--stat-mode=%o", opt_stat_mode); + + FOPT (opt_fake_self, OPT_FAKE_SELF, + "--fake-self=%d", opt_fake_self); + + FOPT (opt_anon_owner, OPT_ANON_OWNER, + "--anonymous-owner=%d", opt_anon_owner); + + FOPT (opt_kernel_pid, OPT_KERNEL_PID, + "--kernel-process=%d", opt_kernel_pid); + +#undef FOPT + + if (! err) + err = netfs_append_std_options (argz, argz_len); + + return err; +} + error_t root_make_node (struct ps_context *pc, struct node **np) { @@ -196,11 +285,11 @@ int main (int argc, char **argv) mach_port_t bootstrap; error_t err; - opt_clk_tck = sysconf(_SC_CLK_TCK); - opt_stat_mode = 0400; - opt_fake_self = -1; - opt_kernel_pid = 2; - opt_anon_owner = 0; + opt_clk_tck = OPT_CLK_TCK; + opt_stat_mode = OPT_STAT_MODE; + opt_fake_self = OPT_FAKE_SELF; + opt_kernel_pid = OPT_KERNEL_PID; + opt_anon_owner = OPT_ANON_OWNER; err = argp_parse (&argp, argc, argv, 0, 0, 0); if (err) error (1, err, "Could not parse command line"); diff --git a/procfs/process.c b/procfs/process.c index c5ef7d8a..269a18bb 100644 --- a/procfs/process.c +++ b/procfs/process.c @@ -116,6 +116,26 @@ process_file_gc_stat (struct proc_stat *ps, char **contents) thread_basic_info_t thbi = proc_stat_thread_basic_info (ps); const char *fn = args_filename (proc_stat_args (ps)); + vm_address_t start_code = 1; /* 0 would make killall5.c consider it + a kernel process, thus use 1 as + default. */ + vm_address_t end_code = 1; + process_t p; + error_t err = proc_pid2proc (ps->context->server, ps->pid, &p); + if (! err) + { + boolean_t essential = 0; + proc_is_important (p, &essential); + if (essential) + start_code = end_code = 0; /* To make killall5.c consider it a + kernel process that is to be + left alone. */ + else + proc_get_code (p, &start_code, &end_code); + + mach_port_deallocate (mach_task_self (), p); + } + /* See proc(5) for more information about the contents of each field for the Linux procfs. */ return asprintf (contents, @@ -152,7 +172,9 @@ process_file_gc_stat (struct proc_stat *ps, char **contents) timeval_jiffies (thbi->creation_time), /* FIXME: ... since boot */ (long unsigned) tbi->virtual_size, (long unsigned) tbi->resident_size / PAGE_SIZE, 0L, - 0L, 0L, 0L, 0L, 0L, + start_code, + end_code, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, (long unsigned) proc_stat_thread_rpc (ps), /* close enough */ 0L, 0L, diff --git a/procfs/rootdir.c b/procfs/rootdir.c index f234dd03..34bf91ce 100644 --- a/procfs/rootdir.c +++ b/procfs/rootdir.c @@ -1,5 +1,5 @@ /* Hurd /proc filesystem, permanent files of the root directory. - Copyright (C) 2010 Free Software Foundation, Inc. + Copyright (C) 2010,13 Free Software Foundation, Inc. This file is part of the GNU Hurd. @@ -404,6 +404,31 @@ rootdir_gc_fakeself (void *hook, char **contents, ssize_t *contents_len) return 0; } +/* The mtab translator to use by default for the "mounts" node. */ +#define MTAB_TRANSLATOR "/hurd/mtab" + +static error_t +rootdir_mounts_get_translator (void *hook, char **argz, size_t *argz_len) +{ + static const char const mtab_argz[] = MTAB_TRANSLATOR "\0/"; + + *argz = malloc (sizeof mtab_argz); + if (! *argz) + return ENOMEM; + + memcpy (*argz, mtab_argz, sizeof mtab_argz); + *argz_len = sizeof mtab_argz; + return 0; +} + +static int +rootdir_mounts_exists (void *dir_hook, const void *entry_hook) +{ + static int translator_exists = -1; + if (translator_exists == -1) + translator_exists = access (MTAB_TRANSLATOR, F_OK|X_OK) == 0; + return translator_exists; +} /* Glue logic and entries table */ @@ -426,6 +451,18 @@ rootdir_symlink_make_node (void *dir_hook, const void *entry_hook) return np; } +static struct node * +rootdir_translator_make_node (void *dir_hook, const void *entry_hook) +{ + struct node *np = procfs_make_node (entry_hook, dir_hook); + if (np) + { + procfs_node_chtype (np, S_IFREG | S_IPTRANS); + procfs_node_chmod (np, 0444); + } + return np; +} + static const struct procfs_dir_entry rootdir_entries[] = { { .name = "self", @@ -487,6 +524,16 @@ static const struct procfs_dir_entry rootdir_entries[] = { .cleanup_contents = procfs_cleanup_contents_with_free, }, }, + { + .name = "mounts", + .hook = & (struct procfs_node_ops) { + .get_translator = rootdir_mounts_get_translator, + }, + .ops = { + .make_node = rootdir_translator_make_node, + .exists = rootdir_mounts_exists, + } + }, #ifdef PROFILE /* In order to get a usable gmon.out file, we must apparently use exit(). */ { diff --git a/ufs/pager.c b/ufs/pager.c index 1e3d140c..5d3e44ab 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -450,6 +450,13 @@ pager_unlock_page (struct user_pager_info *pager, return err; } +void +pager_notify_evict (struct user_pager_info *pager, + vm_offset_t page) +{ + assert (!"unrequested notification on eviction"); +} + /* Implement the pager_report_extent callback from the pager library. See <hurd/pager.h> for the interface description. */ inline error_t @@ -502,7 +509,7 @@ create_disk_pager (void) upi->type = DISK; upi->np = 0; pager_bucket = ports_create_bucket (); - diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, store->size, + diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, 0, store->size, &disk_image); upi->p = diskfs_disk_pager; } @@ -595,7 +602,7 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) upi->unlocked_pagein_length = 0; diskfs_nref_light (np); upi->p = pager_create (upi, pager_bucket, - MAY_CACHE, MEMORY_OBJECT_COPY_DELAY); + MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0); if (upi->p == 0) { diskfs_nrele_light (np); |