summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2013-09-16 00:17:32 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2013-09-16 00:17:32 +0000
commitebb437fb4b27fa565b9aebb05cda1e9db4ec17ff (patch)
tree15598d7d3bfc6ba837e6a5ab3c419f9ac17a2438
parent9ad092a877c6256a425be4f54cbb66382d6762bf (diff)
New upstream snapshot
-rw-r--r--devnode/devnode.c10
-rw-r--r--procfs/ChangeLog6
-rw-r--r--procfs/main.c165
-rw-r--r--procfs/process.c24
-rw-r--r--procfs/rootdir.c49
-rw-r--r--ufs/pager.c11
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);