All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] /dev/time for Linux, inspired by Plan 9
@ 2009-03-11 15:10 Christopher Brannon
  2009-03-11 21:49 ` Jochen Voß
                   ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: Christopher Brannon @ 2009-03-11 15:10 UTC (permalink / raw)
  To: linux-kernel

Under Plan 9 from Bell Labs, one queries or sets the system clock by
reading or writing text strings to a special file named /dev/time.
I implemented such a facility for Linux.  A read of /dev/time produces
four decimal numbers: epoch seconds, nanoseconds since start of epoch,
nanoseconds since boot, and nanoseconds per second.  Writing a decimal number
to /dev/time sets the system clock to the given number of epoch seconds.
Anyone who is permitted to write to /dev/time may set the clock.
Granting this privilege becomes as easy as modifying groups and file
permissions.

Signed-off-by: Christopher Brannon <cmbrannon@cox.net>
---
 Documentation/time-device.txt |   51 +++++++++++++++++
 arch/um/Kconfig.char          |   11 ++++
 drivers/char/Kconfig          |   11 ++++
 drivers/char/Makefile         |    2 +
 drivers/char/devtime.c        |  124 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 199 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/time-device.txt
 create mode 100644 drivers/char/devtime.c

diff --git a/Documentation/time-device.txt b/Documentation/time-device.txt
new file mode 100644
index 0000000..c3145a0
--- /dev/null
+++ b/Documentation/time-device.txt
@@ -0,0 +1,51 @@
+/dev/time for Linux
+===================
+
+Christopher M. Brannon <cmbrannon@cox.net>
+
+Inspiration
+-----------
+This document describes an implementation for the Linux kernel of a facility
+that is provided by the Plan 9 operating system from Bell Laboratories [1].
+
+Functionality
+-------------
+/dev/time provides a file-based interface to the system clock.
+Using this interface, one can query or set the system clock by reading or
+writing text strings.  A read of /dev/time yields four decimal integers:
+seconds since start of epoch, nanoseconds since start of epoch,
+nanoseconds since boot, and nanoseconds per second.
+The fourth value is redundant; it is kept in order to be faithful to the
+original interface.
+Writing a decimal number n to /dev/time sets the system clock to the
+date and time which is n seconds greater than January 1, 1970, 00:00:00 GMT.
+
+Examples
+--------
+cat /dev/time
+# Produces: 1236121128 123612012877063000 495497 300,
+# at time of writing on a test machine.
+echo 287604960 > /dev/time
+# sets the clock to the approximate time of my birth.
+
+Use Case
+--------
+Traditionally, super-user privileges were required in order to set the
+system clock under Linux.
+Since the advent of capabilities, any process having the CAP_SYS_TIME
+capability may perform this operation.
+The /dev/time device ties privileges to file permissions.  If a user
+can write to /dev/time, then he can set the system clock.
+
+Difference from Plan 9
+-----------------------
+This implementation differs from Plan 9 in one respect.  the Plan 9
+Programmer's Manual exactly specifies the format of data read from the
+device, including the widths of the four numeric fields [1].  This Linux
+implementation does not pad values with whitespace, so the four fields
+are of variable width.
+
+References
+----------
+[1] Plan 9 Programmers Manual, section 3.
+http://plan9.bell-labs.com/magic/man2html/3/cons
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index 70dabd1..7d0da78 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -236,4 +236,15 @@ config MMAPPER
 	  This driver allows a host file to be used as emulated IO memory inside
 	  UML.
 
+config DEVTIME
+	tristate "/dev/time virtual device support."
+	depends on EXPERIMENTAL
+	help
+	  This device provides a file-based interface to the system clock.
+	  The interface is based on the /dev/time device used in the
+	  Plan 9 operating system from Bell Labs.
+	  See <file:Documentation/time-device.txt> for a full description.
+	  To compile this driver as a module, choose M here: the
+	  module will be called devtime.
+
 endmenu
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 735bbe2..5bad918 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -97,6 +97,17 @@ config DEVKMEM
 	  kind of kernel debugging operations.
 	  When in doubt, say "N".
 
+config DEVTIME
+	tristate "/dev/time virtual device support."
+	depends on EXPERIMENTAL
+	help
+	  This device provides a file-based interface to the system clock.
+	  The interface is based on the /dev/time device used in the
+	  Plan 9 operating system from Bell Labs.
+	  See <file:Documentation/time-device.txt> for a full description.
+	  To compile this driver as a module, choose M here: the
+	  module will be called devtime.
+
 config SERIAL_NONSTANDARD
 	bool "Non-standard serial port support"
 	depends on HAS_IOMEM
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 9caf5b5..aba7403 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH)		+= ps3flash.o
 obj-$(CONFIG_JS_RTC)		+= js-rtc.o
 js-rtc-y = rtc.o
 
+obj-$(CONFIG_DEVTIME)		+= devtime.o
+
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c
 
diff --git a/drivers/char/devtime.c b/drivers/char/devtime.c
new file mode 100644
index 0000000..0349ea8
--- /dev/null
+++ b/drivers/char/devtime.c
@@ -0,0 +1,124 @@
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/ktime.h>
+#include <linux/time.h>
+#include <linux/uaccess.h>
+
+MODULE_AUTHOR("Christopher Brannon <cmbrannon79@gmail.com>");
+MODULE_LICENSE("GPL");
+
+#define NS_PER_SEC 1000000000
+#define TIME_BUFSIZE 256
+
+static ssize_t time_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t time_write(struct file *, const char __user *, size_t,
+			  loff_t *);
+
+static const struct file_operations time_fops = {
+	.owner = THIS_MODULE,
+	.read = time_read,
+	.write = time_write,
+};
+
+static struct miscdevice timedev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "time",
+	.fops = &time_fops
+};
+
+static int time2text(char *buffer, size_t bufsize)
+{
+	int count = 0;
+	struct timespec abs_time;
+	struct timespec boot_time;
+	s64 abs_nanos;	/* nanoseconds since epoch */
+	s64 boot_nanos;	/* nanoseconds since boot */
+
+	getnstimeofday(&abs_time);
+
+	/*
+	 * The next two lines calculate uptime and store it in boot_time.
+	 * Taken from fs/proc/uptime.c.
+	 */
+	do_posix_clock_monotonic_gettime(&boot_time);
+	monotonic_to_bootbased(&boot_time);
+
+	/* Convert both time structs to nanoseconds. */
+	boot_nanos = timespec_to_ns(&boot_time);
+	abs_nanos = timespec_to_ns(&abs_time);
+
+	count =
+	    scnprintf(buffer, bufsize, "%ld %lld %lld %d\n", abs_time.tv_sec,
+		      abs_nanos, boot_nanos, NS_PER_SEC);
+
+	return count;
+}
+
+static int text2time(char *buffer)
+{
+	struct timespec ts;
+	int result = strict_strtol(buffer, 10, &ts.tv_sec);
+	if ((result == 0) && (ts.tv_sec > 0)) {
+		ts.tv_nsec = 0;
+		do_settimeofday(&ts);
+	} else
+		result = -EINVAL;	/* only positive longs are valid. */
+	return result;
+}
+
+static ssize_t
+time_read(struct file *f, char __user * buffer, size_t count, loff_t *offset)
+{
+	int result = 0;
+	if (*offset != 0)
+		result = 0;
+	else {
+		char tmpbuf[TIME_BUFSIZE];
+		int timetextlen = time2text(tmpbuf, TIME_BUFSIZE);
+		unsigned long readcount = min(count, (size_t) timetextlen);
+		if (timetextlen <= 0)
+			return -EAGAIN;
+		if (!copy_to_user(buffer, tmpbuf, readcount)) {
+			*offset += readcount;
+			result = readcount;
+		} else
+			result = -EFAULT;
+	}
+	return result;
+}
+
+static ssize_t
+time_write(struct file *f, const char __user * buffer, size_t count,
+	   loff_t *offset)
+{
+	unsigned int result = 0;
+	char tmpbuf[TIME_BUFSIZE];
+
+	if (*offset != 0)
+		return -EINVAL;
+	if (count > ((size_t) TIME_BUFSIZE - 1))
+		return -EINVAL;	/* Likely trying to feed bogus data anyway. */
+	result = copy_from_user(tmpbuf, buffer, count);
+	if (result)
+		return -EFAULT;
+	tmpbuf[count] = '\0';
+	if (text2time(tmpbuf))
+		return -EINVAL;
+	return count;
+}
+
+static int __init time_init(void)
+{
+	return misc_register(&timedev);
+}
+
+static void __exit time_exit(void)
+{
+	misc_deregister(&timedev);
+}
+
+module_init(time_init);
+module_exit(time_exit);
-- 
1.6.2


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-11 15:10 [PATCH] /dev/time for Linux, inspired by Plan 9 Christopher Brannon
@ 2009-03-11 21:49 ` Jochen Voß
  2009-03-11 22:07 ` Bill Nottingham
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 21+ messages in thread
From: Jochen Voß @ 2009-03-11 21:49 UTC (permalink / raw)
  To: Christopher Brannon; +Cc: linux-kernel

Hi Christopher,

2009/3/11 Christopher Brannon <cmbrannon@cox.net>:
> +/dev/time provides a file-based interface to the system clock.
> +Using this interface, one can query or set the system clock by reading or
> +writing text strings.  A read of /dev/time yields four decimal integers:
> +seconds since start of epoch, nanoseconds since start of epoch,
> +nanoseconds since boot, and nanoseconds per second.
> [...]
> +Examples
> +--------
> +cat /dev/time
> +# Produces: 1236121128 123612012877063000 495497 300,
> +# at time of writing on a test machine.

The last two numbers in the example seem suspicous to me.  300
nanoseconds per second?

I hope this helps,
Jochen
-- 
http://seehuhn.de/

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-11 15:10 [PATCH] /dev/time for Linux, inspired by Plan 9 Christopher Brannon
  2009-03-11 21:49 ` Jochen Voß
@ 2009-03-11 22:07 ` Bill Nottingham
  2009-03-12  8:00   ` David Newall
  2009-03-12  9:30 ` Giacomo A. Catenazzi
  2009-03-14 16:13 ` Pavel Machek
  3 siblings, 1 reply; 21+ messages in thread
From: Bill Nottingham @ 2009-03-11 22:07 UTC (permalink / raw)
  To: Christopher Brannon; +Cc: linux-kernel

Christopher Brannon (cmbrannon@cox.net) said: 
> Under Plan 9 from Bell Labs, one queries or sets the system clock by
> reading or writing text strings to a special file named /dev/time.
> I implemented such a facility for Linux.  A read of /dev/time produces
> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> nanoseconds since boot, and nanoseconds per second.  Writing a decimal number
> to /dev/time sets the system clock to the given number of epoch seconds.
> Anyone who is permitted to write to /dev/time may set the clock.
> Granting this privilege becomes as easy as modifying groups and file
> permissions.

Given the general array of current interfaces in the kernel, isn't
read/write of textual parameters better suited to sysfs or procfs
than a character device?

Bill

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-11 22:07 ` Bill Nottingham
@ 2009-03-12  8:00   ` David Newall
  2009-03-12 18:15     ` J.R. Mauro
  0 siblings, 1 reply; 21+ messages in thread
From: David Newall @ 2009-03-12  8:00 UTC (permalink / raw)
  To: linux-kernel

Bill Nottingham wrote:
> Given the general array of current interfaces in the kernel, isn't
> read/write of textual parameters better suited to sysfs or procfs
> than a character device?

Procfs and Sysfs are used to control devices.  Dev is used to access
them.  Dev is the right place to fetch and set the time; having a text
interface is beside the point.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-11 15:10 [PATCH] /dev/time for Linux, inspired by Plan 9 Christopher Brannon
  2009-03-11 21:49 ` Jochen Voß
  2009-03-11 22:07 ` Bill Nottingham
@ 2009-03-12  9:30 ` Giacomo A. Catenazzi
  2009-03-14 16:13 ` Pavel Machek
  3 siblings, 0 replies; 21+ messages in thread
From: Giacomo A. Catenazzi @ 2009-03-12  9:30 UTC (permalink / raw)
  To: Christopher Brannon; +Cc: linux-kernel

Christopher Brannon wrote:

> diff --git a/Documentation/time-device.txt b/Documentation/time-device.txt
> new file mode 100644
> index 0000000..c3145a0
> --- /dev/null
> +++ b/Documentation/time-device.txt
> @@ -0,0 +1,51 @@
> +/dev/time for Linux
> +===================

I would like to see this documentation also as time(4) manpage.
So maybe you can already format it in man/mdoc format.

ciao
	cate

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-12  8:00   ` David Newall
@ 2009-03-12 18:15     ` J.R. Mauro
  0 siblings, 0 replies; 21+ messages in thread
From: J.R. Mauro @ 2009-03-12 18:15 UTC (permalink / raw)
  To: David Newall; +Cc: linux-kernel

On Thu, Mar 12, 2009 at 4:00 AM, David Newall <davidn@davidnewall.com> wrote:
> Bill Nottingham wrote:
>> Given the general array of current interfaces in the kernel, isn't
>> read/write of textual parameters better suited to sysfs or procfs
>> than a character device?
>
> Procfs and Sysfs are used to control devices.  Dev is used to access
> them.  Dev is the right place to fetch and set the time; having a text
> interface is beside the point.

I also think we're aiming for compatibility with Plan 9 here, which
keeps this file in /dev

> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-11 15:10 [PATCH] /dev/time for Linux, inspired by Plan 9 Christopher Brannon
                   ` (2 preceding siblings ...)
  2009-03-12  9:30 ` Giacomo A. Catenazzi
@ 2009-03-14 16:13 ` Pavel Machek
  2009-03-17 15:15   ` J.R. Mauro
  3 siblings, 1 reply; 21+ messages in thread
From: Pavel Machek @ 2009-03-14 16:13 UTC (permalink / raw)
  To: Christopher Brannon; +Cc: linux-kernel

On Wed 2009-03-11 10:10:23, Christopher Brannon wrote:
> Under Plan 9 from Bell Labs, one queries or sets the system clock by
> reading or writing text strings to a special file named /dev/time.
> I implemented such a facility for Linux.  A read of /dev/time produces
> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> nanoseconds since boot, and nanoseconds per second.  Writing a
> decimal number

nanoseconds per second?! Just use 123.456 notation.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-14 16:13 ` Pavel Machek
@ 2009-03-17 15:15   ` J.R. Mauro
  2009-03-21 22:05     ` Pavel Machek
  0 siblings, 1 reply; 21+ messages in thread
From: J.R. Mauro @ 2009-03-17 15:15 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Christopher Brannon, linux-kernel

On Sat, Mar 14, 2009 at 12:13 PM, Pavel Machek <pavel@ucw.cz> wrote:
> On Wed 2009-03-11 10:10:23, Christopher Brannon wrote:
>> Under Plan 9 from Bell Labs, one queries or sets the system clock by
>> reading or writing text strings to a special file named /dev/time.
>> I implemented such a facility for Linux.  A read of /dev/time produces
>> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
>> nanoseconds since boot, and nanoseconds per second.  Writing a
>> decimal number
>
> nanoseconds per second?! Just use 123.456 notation.

The point is to be close to Plan 9's interface, in which column 3 is
"something since boot" and column 4 is "somethings per second" to keep
programs portable.

>
> --
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-17 15:15   ` J.R. Mauro
@ 2009-03-21 22:05     ` Pavel Machek
  0 siblings, 0 replies; 21+ messages in thread
From: Pavel Machek @ 2009-03-21 22:05 UTC (permalink / raw)
  To: J.R. Mauro; +Cc: Christopher Brannon, linux-kernel

On Tue 2009-03-17 11:15:09, J.R. Mauro wrote:
> On Sat, Mar 14, 2009 at 12:13 PM, Pavel Machek <pavel@ucw.cz> wrote:
> > On Wed 2009-03-11 10:10:23, Christopher Brannon wrote:
> >> Under Plan 9 from Bell Labs, one queries or sets the system clock by
> >> reading or writing text strings to a special file named /dev/time.
> >> I implemented such a facility for Linux.  A read of /dev/time produces
> >> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> >> nanoseconds since boot, and nanoseconds per second.  Writing a
> >> decimal number
> >
> > nanoseconds per second?! Just use 123.456 notation.
> 
> The point is to be close to Plan 9's interface, in which column 3 is
> "something since boot" and column 4 is "somethings per second" to keep
> programs portable.

I don't think compatibility with Plan9 is worthy goal... especially
when Plan9's interface is unneccessarily ugly.
								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-12 18:12     ` J.R. Mauro
@ 2009-03-14 23:27       ` Chris Brannon
  0 siblings, 0 replies; 21+ messages in thread
From: Chris Brannon @ 2009-03-14 23:27 UTC (permalink / raw)
  To: linux-kernel

J.R. Mauro wrote:
> On Sat, Mar 07, 2009 at 10:23:05AM -0600, Chris Brannon wrote:
> > John Stultz wrote:
> > > Ehh. Why would we want to export raw kernel internal values like
> > > jiffies and HZ?
> > > 
> > > I think the CLOCK_MONOTONIC clockid would probably be a better value to
> > > export.
> > 
> > I'll look at CLOCK_MONOTONIC clockid.  I'm more than glad to export
> > something > more appropriate, including nothing at all (dummy values,
> > perhaps).
> 
> Chris, are the current values exactly what one would get if reading /dev/time
> onPlan 9?
> If possible, it would be nice to aim for 100% compatibility as there are
> folks trying to get complete Plan 9 binary compatibility working in Linux.

On Plan 9, the last two values are architecture-dependent.
I rewrote my patch to export nanoseconds since boot and nanoseconds per
second, but either choice should be ok from the standpoint of compatibility.

I am going to rework this patch to eliminate the inconsistencies
with the Plan 9 interface.

Thanks to Jochen Vos for pointing out the error in the documentation.
I forgot to change my example to reflect the change to the code.

-- Chris

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-07 16:23   ` Chris Brannon
@ 2009-03-12 18:12     ` J.R. Mauro
  2009-03-14 23:27       ` Chris Brannon
  0 siblings, 1 reply; 21+ messages in thread
From: J.R. Mauro @ 2009-03-12 18:12 UTC (permalink / raw)
  To: Chris Brannon; +Cc: john stultz, linux-kernel

On Sat, Mar 07, 2009 at 10:23:05AM -0600, Chris Brannon wrote:
> John Stultz wrote:
> > On Tue, Mar 3, 2009 at 7:06 PM, Christopher Brannon <cmbrannon@cox.net> wrote:
> > > I implemented such a facility for Linux.  A read of /dev/time produces
> > > four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> > > jiffies since boot, and jiffies per second.
> > 
> > Ehh. Why would we want to export raw kernel internal values like
> > jiffies and HZ?
> > 
> > I think the CLOCK_MONOTONIC clockid would probably be a better value to export.
> 
> I'll look at CLOCK_MONOTONIC clockid.  I'm more than glad to export something
> more appropriate, including nothing at all (dummy values, perhaps).

Chris, are the current values exactly what one would get if reading /dev/time on
Plan 9? If possible, it would be nice to aim for 100% compatibility as there are
folks trying to get complete Plan 9 binary compatibility working in Linux.

> 
> -- Chris
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
				J.R. Mauro

()  ascii ribbon campaign - against html e-mail 
/\  www.asciiribbon.org   - against Microsoft attachments

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-04  3:06 Christopher Brannon
                   ` (2 preceding siblings ...)
  2009-03-10 11:22 ` Pavel Machek
@ 2009-03-11  7:28 ` Américo Wang
  3 siblings, 0 replies; 21+ messages in thread
From: Américo Wang @ 2009-03-11  7:28 UTC (permalink / raw)
  To: Christopher Brannon; +Cc: linux-kernel

On Tue, Mar 03, 2009 at 09:06:46PM -0600, Christopher Brannon wrote:

<snip>

>@@ -0,0 +1,112 @@
>+#include <linux/init.h>
>+#include <linux/module.h>
>+#include <linux/fs.h>
>+#include <linux/miscdevice.h>
>+#include <linux/time.h>
>+#include <linux/jiffies.h>
>+#include <linux/uaccess.h>
>+
>+MODULE_AUTHOR("Christopher Brannon <cmbrannon79@gmail.com>");
>+MODULE_LICENSE("GPL");
>+
>+const long long NS_PER_SEC = 1000000000;
>+const long long NS_PER_USEC = 1000;
>+const size_t time_bufsize = 256;

I notice that you use this "const" as an array size below, so
you are using VLA, yes, C99 supports it but this is in the kernel,
try to avoid this by using marco:

#define BUFSIZE 256

And yes, C's const sucks. :)


>+
>+static ssize_t time_read(struct file *, char __user *, size_t, loff_t *);
>+static ssize_t time_write(struct file *, const char __user *, size_t, loff_t *);
>+
>+static const struct file_operations time_fops = {
>+	.owner = THIS_MODULE,
>+	.read = time_read,
>+	.write = time_write,
>+};
>+
>+static struct miscdevice timedev = {
>+	.minor = MISC_DYNAMIC_MINOR,
>+	.name = "time",
>+	.fops = &time_fops
>+};
>+
>+static int time2text(char *buffer, size_t bufsize)
>+{
>+	int count = 0;
>+	struct timeval tv;
>+	long long nanos;
>+
>+/* jiffies isn't 0 at boot time; its value is INITIAL_JIFFIES. */
>+	u64 ticks = get_jiffies_64() - INITIAL_JIFFIES;
>+
>+	do_gettimeofday(&tv);
>+	nanos = tv.tv_sec * NS_PER_SEC + tv.tv_usec * NS_PER_USEC;
>+	count =
>+	    scnprintf(buffer, bufsize, "%ld %lld %llu %d\n", tv.tv_sec, nanos,
>+		      ticks, HZ);
>+	return count;
>+}
>+
>+static int text2time(char *buffer)
>+{
>+	struct timespec tv;
>+	int result = strict_strtol(buffer, 10, &tv.tv_sec);
>+	if ((result == 0) && (tv.tv_sec > 0)) {
>+		tv.tv_nsec = 0;
>+		do_settimeofday(&tv);
>+	} else
>+		result = -EINVAL;	/* only positive longs are valid. */
>+	return result;
>+}
>+
>+static ssize_t
>+time_read(struct file *f, char __user *buffer, size_t count, loff_t * offset)
>+{
>+	int result = 0;
>+	if (*offset != 0)
>+		result = 0;
>+	else {
>+		char tmpbuf[time_bufsize];
>+		int timetextlen = time2text(tmpbuf, time_bufsize);
>+		unsigned long readcount = min(count, (size_t) timetextlen);
>+		if (timetextlen <= 0)
>+			return -EAGAIN;
>+		if (!copy_to_user(buffer, tmpbuf, readcount)) {
>+			*offset += readcount;
>+			result = readcount;
>+		} else
>+			result = -EFAULT;
>+	}
>+	return result;
>+}
>+
>+static ssize_t
>+time_write(struct file *f, const char __user * buffer, size_t count,
>+	   loff_t *offset)
>+{
>+	unsigned int result = 0;
>+	char tmpbuf[time_bufsize];
>+
>+	if (*offset != 0)
>+		return -EINVAL;
>+	if (count > ((size_t) time_bufsize - 1))
>+		return -EINVAL;	/* Likely trying to feed bogus data anyway. */
>+	result = copy_from_user(tmpbuf, buffer, count);
>+	if (result)
>+		return -EFAULT;
>+	tmpbuf[count] = '\0';
>+	if (text2time(tmpbuf))
>+		return -EINVAL;
>+	return count;
>+}
>+
>+static int __init time_init(void)
>+{
>+	return misc_register(&timedev);
>+}
>+
>+static void __exit time_exit(void)
>+{
>+	misc_deregister(&timedev);
>+}
>+
>+module_init(time_init);
>+module_exit(time_exit);
>-- 
>1.6.1.3
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at  http://www.tux.org/lkml/

-- 
Do what you love, f**k the rest! F**k the regulations!
 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-04  3:06 Christopher Brannon
  2009-03-06 17:57 ` Greg KH
  2009-03-06 22:56 ` john stultz
@ 2009-03-10 11:22 ` Pavel Machek
  2009-03-11  7:28 ` Américo Wang
  3 siblings, 0 replies; 21+ messages in thread
From: Pavel Machek @ 2009-03-10 11:22 UTC (permalink / raw)
  To: Christopher Brannon; +Cc: linux-kernel

Hi!

> Under Plan 9 from Bell Labs, one queries or sets the system clock by
> reading or writing text strings to a special file named /dev/time.
> I implemented such a facility for Linux.  A read of /dev/time produces
> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> jiffies since boot, and jiffies per second.  Writing a decimal
> number to

Jiffies are strange... and I guess time should be exported as 123.456
(seconds . fractional part). That way we are not limited to
nanoseconds...

Same interface can be used for setting precise time...
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-07  5:54     ` Greg KH
  2009-03-07 16:08       ` Chris Brannon
@ 2009-03-08 16:03       ` J.R. Mauro
  1 sibling, 0 replies; 21+ messages in thread
From: J.R. Mauro @ 2009-03-08 16:03 UTC (permalink / raw)
  To: Greg KH; +Cc: Christopher Brannon, linux-kernel

On 3/7/09, Greg KH <greg@kroah.com> wrote:
> On Sat, Mar 07, 2009 at 12:43:43AM -0500, J.R. Mauro wrote:
>> On Fri, Mar 6, 2009 at 12:57 PM, Greg KH <greg@kroah.com> wrote:
>> > On Tue, Mar 03, 2009 at 09:06:46PM -0600, Christopher Brannon wrote:
>> >> Under Plan 9 from Bell Labs, one queries or sets the system clock by
>> >> reading or writing text strings to a special file named /dev/time.
>> >> I implemented such a facility for Linux.  A read of /dev/time produces
>> >> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
>> >> jiffies since boot, and jiffies per second.  Writing a decimal number
>> >> to
>> >> /dev/time sets the system clock to the given number of epoch seconds.
>> >> Anyone who is permitted to write to /dev/time may set the clock.
>> >> Granting this privilege becomes as easy as modifying groups and file
>> >> permissions.
>> >>
>> >> Signed-off-by: Christopher Brannon <cmbrannon@cox.net>
>> >
>> > I'm starting to see a few plan9 specific devices being proposed
>> > recently, with one making it into the staging tree recently (the p9auth
>> > interface).  Should we just start lumping them all together so to keep
>> > them in one place?  drivers/plan9/ ?
>>
>> That might be a good idea, assuming it doesn't start up a flamewar.
>
> I don't think if we keep it all in one place, it would.
>
>> The Glendix folks are working hard to get a lot of these device files
>> and filesystems implemented and it would be nice to see them have a
>> place to feel welcome.
>>
>> Would it be very involved to get a little sandbox for these things?
>
> drivers/plan9 looks like a nice place to me, any objections?
>

Sounds good to keep this all together, as more things come in. We
don't want to male a mess :-)
> thanks,
>
> greg k-h
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-06 22:56 ` john stultz
@ 2009-03-07 16:23   ` Chris Brannon
  2009-03-12 18:12     ` J.R. Mauro
  0 siblings, 1 reply; 21+ messages in thread
From: Chris Brannon @ 2009-03-07 16:23 UTC (permalink / raw)
  To: john stultz; +Cc: linux-kernel

John Stultz wrote:
> On Tue, Mar 3, 2009 at 7:06 PM, Christopher Brannon <cmbrannon@cox.net> wrote:
> > I implemented such a facility for Linux.  A read of /dev/time produces
> > four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> > jiffies since boot, and jiffies per second.
> 
> Ehh. Why would we want to export raw kernel internal values like
> jiffies and HZ?
> 
> I think the CLOCK_MONOTONIC clockid would probably be a better value to export.

I'll look at CLOCK_MONOTONIC clockid.  I'm more than glad to export something
more appropriate, including nothing at all (dummy values, perhaps).

-- Chris

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-07  5:54     ` Greg KH
@ 2009-03-07 16:08       ` Chris Brannon
  2009-03-08 16:03       ` J.R. Mauro
  1 sibling, 0 replies; 21+ messages in thread
From: Chris Brannon @ 2009-03-07 16:08 UTC (permalink / raw)
  To: Greg KH; +Cc: J.R. Mauro, linux-kernel

Greg KH wrote:
> On Sat, Mar 07, 2009 at 12:43:43AM -0500, J.R. Mauro wrote:
> > That might be a good idea, assuming it doesn't start up a flamewar.
> 
> I don't think if we keep it all in one place, it would.
> 
> > The Glendix folks are working hard to get a lot of these device files
> > and filesystems implemented and it would be nice to see them have a
> > place to feel welcome.
> > Would it be very involved to get a little sandbox for these things?
> 
> drivers/plan9 looks like a nice place to me, any objections?

Treating all of the Plan 9 devices as a group seems good,
especially if it applies to Kconfig.
During the config process, one could easily ignore the whole group.

-- Chris

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-07  5:43   ` J.R. Mauro
@ 2009-03-07  5:54     ` Greg KH
  2009-03-07 16:08       ` Chris Brannon
  2009-03-08 16:03       ` J.R. Mauro
  0 siblings, 2 replies; 21+ messages in thread
From: Greg KH @ 2009-03-07  5:54 UTC (permalink / raw)
  To: J.R. Mauro; +Cc: Christopher Brannon, linux-kernel

On Sat, Mar 07, 2009 at 12:43:43AM -0500, J.R. Mauro wrote:
> On Fri, Mar 6, 2009 at 12:57 PM, Greg KH <greg@kroah.com> wrote:
> > On Tue, Mar 03, 2009 at 09:06:46PM -0600, Christopher Brannon wrote:
> >> Under Plan 9 from Bell Labs, one queries or sets the system clock by
> >> reading or writing text strings to a special file named /dev/time.
> >> I implemented such a facility for Linux.  A read of /dev/time produces
> >> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> >> jiffies since boot, and jiffies per second.  Writing a decimal number to
> >> /dev/time sets the system clock to the given number of epoch seconds.
> >> Anyone who is permitted to write to /dev/time may set the clock.
> >> Granting this privilege becomes as easy as modifying groups and file
> >> permissions.
> >>
> >> Signed-off-by: Christopher Brannon <cmbrannon@cox.net>
> >
> > I'm starting to see a few plan9 specific devices being proposed
> > recently, with one making it into the staging tree recently (the p9auth
> > interface).  Should we just start lumping them all together so to keep
> > them in one place?  drivers/plan9/ ?
> 
> That might be a good idea, assuming it doesn't start up a flamewar.

I don't think if we keep it all in one place, it would.

> The Glendix folks are working hard to get a lot of these device files
> and filesystems implemented and it would be nice to see them have a
> place to feel welcome.
> 
> Would it be very involved to get a little sandbox for these things?

drivers/plan9 looks like a nice place to me, any objections?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-06 17:57 ` Greg KH
@ 2009-03-07  5:43   ` J.R. Mauro
  2009-03-07  5:54     ` Greg KH
  0 siblings, 1 reply; 21+ messages in thread
From: J.R. Mauro @ 2009-03-07  5:43 UTC (permalink / raw)
  To: Greg KH; +Cc: Christopher Brannon, linux-kernel

On Fri, Mar 6, 2009 at 12:57 PM, Greg KH <greg@kroah.com> wrote:
> On Tue, Mar 03, 2009 at 09:06:46PM -0600, Christopher Brannon wrote:
>> Under Plan 9 from Bell Labs, one queries or sets the system clock by
>> reading or writing text strings to a special file named /dev/time.
>> I implemented such a facility for Linux.  A read of /dev/time produces
>> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
>> jiffies since boot, and jiffies per second.  Writing a decimal number to
>> /dev/time sets the system clock to the given number of epoch seconds.
>> Anyone who is permitted to write to /dev/time may set the clock.
>> Granting this privilege becomes as easy as modifying groups and file
>> permissions.
>>
>> Signed-off-by: Christopher Brannon <cmbrannon@cox.net>
>
> I'm starting to see a few plan9 specific devices being proposed
> recently, with one making it into the staging tree recently (the p9auth
> interface).  Should we just start lumping them all together so to keep
> them in one place?  drivers/plan9/ ?

That might be a good idea, assuming it doesn't start up a flamewar.
The Glendix folks are working hard to get a lot of these device files
and filesystems implemented and it would be nice to see them have a
place to feel welcome.

Would it be very involved to get a little sandbox for these things?

>
>
>> ---
>>  Documentation/time-device.txt |   49 ++++++++++++++++++
>>  arch/um/Kconfig.char          |   11 ++++
>>  drivers/char/Kconfig          |   11 ++++
>>  drivers/char/Makefile         |    2 +
>>  drivers/char/devtime.c        |  112 +++++++++++++++++++++++++++++++++++++++++
>>  5 files changed, 185 insertions(+), 0 deletions(-)
>>  create mode 100644 Documentation/time-device.txt
>>  create mode 100644 drivers/char/devtime.c
>>
>> diff --git a/Documentation/time-device.txt b/Documentation/time-device.txt
>> new file mode 100644
>> index 0000000..6294732
>> --- /dev/null
>> +++ b/Documentation/time-device.txt
>> @@ -0,0 +1,49 @@
>> +/dev/time for Linux
>> +===================
>> +
>> +Christopher M. Brannon <cmbrannon@cox.net>
>> +
>> +Inspiration
>> +-----------
>> +This document describes an implementation for the Linux kernel of a facility
>> +that is provided by the Plan 9 operating system from Bell Laboratories [1].
>> +
>> +Functionality
>> +-------------
>> +/dev/time provides a file-based interface to the system clock.
>> +Using this interface, one can query or set the system clock by reading or
>> +writing text strings.  A read of /dev/time yields four decimal integers:
>> +seconds since start of epoch, nanoseconds since start of epoch,
>> +jiffies since boot, and jiffies per second.
>> +Writing a decimal number n to /dev/time sets the system clock to the
>> +date and time which is n seconds greater than January 1, 1970, 00:00:00 GMT.
>> +
>> +Examples
>> +--------
>> +cat /dev/time
>> +# Produces: 1236121128 123612012877063000 495497 300,
>> +# at time of writing on a test machine.
>> +echo 287604960 > /dev/time
>> +# sets the clock to the approximate time of my birth.
>> +
>> +Use Case
>> +--------
>> +Traditionally, super-user privileges were required in order to set the
>> +system clock under Linux.
>> +Since the advent of capabilities, any process having the CAP_SYS_TIME
>> +capability may perform this operation.
>> +The /dev/time device ties privileges to file permissions.  If a user
>> +can write to /dev/time, then he can set the system clock.
>> +
>> +Difference from Plan 9
>> +-----------------------
>> +This implementation differs from Plan 9 in one respect.  the Plan 9
>> +Programmer's Manual exactly specifies the format of data read from the
>> +device, including the widths of the four numeric fields [1].  This Linux
>> +implementation does not pad values with whitespace, so the four fields
>> +are of variable width.
>> +
>> +References
>> +----------
>> +[1] Plan 9 Programmers Manual, section 3.
>> +http://plan9.bell-labs.com/magic/man2html/3/cons
>> diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
>> index 70dabd1..7d0da78 100644
>> --- a/arch/um/Kconfig.char
>> +++ b/arch/um/Kconfig.char
>> @@ -236,4 +236,15 @@ config MMAPPER
>>         This driver allows a host file to be used as emulated IO memory inside
>>         UML.
>>
>> +config DEVTIME
>> +     tristate "/dev/time virtual device support."
>> +     depends on EXPERIMENTAL
>> +     help
>> +       This device provides a file-based interface to the system clock.
>> +       The interface is based on the /dev/time device used in the
>> +       Plan 9 operating system from Bell Labs.
>> +       See <file:Documentation/time-device.txt> for a full description.
>> +       To compile this driver as a module, choose M here: the
>> +       module will be called devtime.
>> +
>>  endmenu
>> diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
>> index 735bbe2..5bad918 100644
>> --- a/drivers/char/Kconfig
>> +++ b/drivers/char/Kconfig
>> @@ -97,6 +97,17 @@ config DEVKMEM
>>         kind of kernel debugging operations.
>>         When in doubt, say "N".
>>
>> +config DEVTIME
>> +     tristate "/dev/time virtual device support."
>> +     depends on EXPERIMENTAL
>> +     help
>> +       This device provides a file-based interface to the system clock.
>> +       The interface is based on the /dev/time device used in the
>> +       Plan 9 operating system from Bell Labs.
>> +       See <file:Documentation/time-device.txt> for a full description.
>> +       To compile this driver as a module, choose M here: the
>> +       module will be called devtime.
>> +
>>  config SERIAL_NONSTANDARD
>>       bool "Non-standard serial port support"
>>       depends on HAS_IOMEM
>> diff --git a/drivers/char/Makefile b/drivers/char/Makefile
>> index 9caf5b5..aba7403 100644
>> --- a/drivers/char/Makefile
>> +++ b/drivers/char/Makefile
>> @@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH)           += ps3flash.o
>>  obj-$(CONFIG_JS_RTC)         += js-rtc.o
>>  js-rtc-y = rtc.o
>>
>> +obj-$(CONFIG_DEVTIME)                += devtime.o
>> +
>>  # Files generated that shall be removed upon make clean
>>  clean-files := consolemap_deftbl.c defkeymap.c
>>
>> diff --git a/drivers/char/devtime.c b/drivers/char/devtime.c
>> new file mode 100644
>> index 0000000..5e4ca66
>> --- /dev/null
>> +++ b/drivers/char/devtime.c
>> @@ -0,0 +1,112 @@
>> +#include <linux/init.h>
>> +#include <linux/module.h>
>> +#include <linux/fs.h>
>> +#include <linux/miscdevice.h>
>> +#include <linux/time.h>
>> +#include <linux/jiffies.h>
>> +#include <linux/uaccess.h>
>> +
>> +MODULE_AUTHOR("Christopher Brannon <cmbrannon79@gmail.com>");
>> +MODULE_LICENSE("GPL");
>> +
>> +const long long NS_PER_SEC = 1000000000;
>> +const long long NS_PER_USEC = 1000;
>> +const size_t time_bufsize = 256;
>> +
>> +static ssize_t time_read(struct file *, char __user *, size_t, loff_t *);
>> +static ssize_t time_write(struct file *, const char __user *, size_t, loff_t *);
>> +
>> +static const struct file_operations time_fops = {
>> +     .owner = THIS_MODULE,
>> +     .read = time_read,
>> +     .write = time_write,
>> +};
>> +
>> +static struct miscdevice timedev = {
>> +     .minor = MISC_DYNAMIC_MINOR,
>> +     .name = "time",
>> +     .fops = &time_fops
>> +};
>> +
>> +static int time2text(char *buffer, size_t bufsize)
>> +{
>> +     int count = 0;
>> +     struct timeval tv;
>> +     long long nanos;
>> +
>> +/* jiffies isn't 0 at boot time; its value is INITIAL_JIFFIES. */
>> +     u64 ticks = get_jiffies_64() - INITIAL_JIFFIES;
>
> Are you sure this will handle the roll-over properly?
>
>> +     do_gettimeofday(&tv);
>> +     nanos = tv.tv_sec * NS_PER_SEC + tv.tv_usec * NS_PER_USEC;
>> +     count =
>> +         scnprintf(buffer, bufsize, "%ld %lld %llu %d\n", tv.tv_sec, nanos,
>> +                   ticks, HZ);
>> +     return count;
>> +}
>> +
>> +static int text2time(char *buffer)
>> +{
>> +     struct timespec tv;
>> +     int result = strict_strtol(buffer, 10, &tv.tv_sec);
>> +     if ((result == 0) && (tv.tv_sec > 0)) {
>> +             tv.tv_nsec = 0;
>> +             do_settimeofday(&tv);
>> +     } else
>> +             result = -EINVAL;       /* only positive longs are valid. */
>> +     return result;
>> +}
>> +
>> +static ssize_t
>> +time_read(struct file *f, char __user *buffer, size_t count, loff_t * offset)
>> +{
>> +     int result = 0;
>> +     if (*offset != 0)
>> +             result = 0;
>> +     else {
>> +             char tmpbuf[time_bufsize];
>
> Not good to put 256 bytes on the stack.  Dynamically allocate it?
>
>> +             int timetextlen = time2text(tmpbuf, time_bufsize);
>> +             unsigned long readcount = min(count, (size_t) timetextlen);
>
> As was recently pointed out to me, we have min_t() for when you need to
> cast like this.
>
>> +             if (timetextlen <= 0)
>> +                     return -EAGAIN;
>
> If it equals 0, shouldn't you return 0?  And how could it be negative?
>
> thanks,
>
> greg k-h
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-04  3:06 Christopher Brannon
  2009-03-06 17:57 ` Greg KH
@ 2009-03-06 22:56 ` john stultz
  2009-03-07 16:23   ` Chris Brannon
  2009-03-10 11:22 ` Pavel Machek
  2009-03-11  7:28 ` Américo Wang
  3 siblings, 1 reply; 21+ messages in thread
From: john stultz @ 2009-03-06 22:56 UTC (permalink / raw)
  To: Christopher Brannon; +Cc: linux-kernel

On Tue, Mar 3, 2009 at 7:06 PM, Christopher Brannon <cmbrannon@cox.net> wrote:
> Under Plan 9 from Bell Labs, one queries or sets the system clock by
> reading or writing text strings to a special file named /dev/time.
> I implemented such a facility for Linux.  A read of /dev/time produces
> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> jiffies since boot, and jiffies per second.

Ehh. Why would we want to export raw kernel internal values like
jiffies and HZ?

I think the CLOCK_MONOTONIC clockid would probably be a better value to export.

thanks
-john

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH] /dev/time for Linux, inspired by Plan 9
  2009-03-04  3:06 Christopher Brannon
@ 2009-03-06 17:57 ` Greg KH
  2009-03-07  5:43   ` J.R. Mauro
  2009-03-06 22:56 ` john stultz
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 21+ messages in thread
From: Greg KH @ 2009-03-06 17:57 UTC (permalink / raw)
  To: Christopher Brannon; +Cc: linux-kernel

On Tue, Mar 03, 2009 at 09:06:46PM -0600, Christopher Brannon wrote:
> Under Plan 9 from Bell Labs, one queries or sets the system clock by
> reading or writing text strings to a special file named /dev/time.
> I implemented such a facility for Linux.  A read of /dev/time produces
> four decimal numbers: epoch seconds, nanoseconds since start of epoch,
> jiffies since boot, and jiffies per second.  Writing a decimal number to
> /dev/time sets the system clock to the given number of epoch seconds.
> Anyone who is permitted to write to /dev/time may set the clock.
> Granting this privilege becomes as easy as modifying groups and file
> permissions.
> 
> Signed-off-by: Christopher Brannon <cmbrannon@cox.net>

I'm starting to see a few plan9 specific devices being proposed
recently, with one making it into the staging tree recently (the p9auth
interface).  Should we just start lumping them all together so to keep
them in one place?  drivers/plan9/ ?


> ---
>  Documentation/time-device.txt |   49 ++++++++++++++++++
>  arch/um/Kconfig.char          |   11 ++++
>  drivers/char/Kconfig          |   11 ++++
>  drivers/char/Makefile         |    2 +
>  drivers/char/devtime.c        |  112 +++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 185 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/time-device.txt
>  create mode 100644 drivers/char/devtime.c
> 
> diff --git a/Documentation/time-device.txt b/Documentation/time-device.txt
> new file mode 100644
> index 0000000..6294732
> --- /dev/null
> +++ b/Documentation/time-device.txt
> @@ -0,0 +1,49 @@
> +/dev/time for Linux
> +===================
> +
> +Christopher M. Brannon <cmbrannon@cox.net>
> +
> +Inspiration
> +-----------
> +This document describes an implementation for the Linux kernel of a facility
> +that is provided by the Plan 9 operating system from Bell Laboratories [1].
> +
> +Functionality
> +-------------
> +/dev/time provides a file-based interface to the system clock.
> +Using this interface, one can query or set the system clock by reading or
> +writing text strings.  A read of /dev/time yields four decimal integers:
> +seconds since start of epoch, nanoseconds since start of epoch,
> +jiffies since boot, and jiffies per second.
> +Writing a decimal number n to /dev/time sets the system clock to the
> +date and time which is n seconds greater than January 1, 1970, 00:00:00 GMT.
> +
> +Examples
> +--------
> +cat /dev/time
> +# Produces: 1236121128 123612012877063000 495497 300,
> +# at time of writing on a test machine.
> +echo 287604960 > /dev/time
> +# sets the clock to the approximate time of my birth.
> +
> +Use Case
> +--------
> +Traditionally, super-user privileges were required in order to set the
> +system clock under Linux.
> +Since the advent of capabilities, any process having the CAP_SYS_TIME
> +capability may perform this operation.
> +The /dev/time device ties privileges to file permissions.  If a user
> +can write to /dev/time, then he can set the system clock.
> +
> +Difference from Plan 9
> +-----------------------
> +This implementation differs from Plan 9 in one respect.  the Plan 9
> +Programmer's Manual exactly specifies the format of data read from the
> +device, including the widths of the four numeric fields [1].  This Linux
> +implementation does not pad values with whitespace, so the four fields
> +are of variable width.
> +
> +References
> +----------
> +[1] Plan 9 Programmers Manual, section 3.
> +http://plan9.bell-labs.com/magic/man2html/3/cons
> diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
> index 70dabd1..7d0da78 100644
> --- a/arch/um/Kconfig.char
> +++ b/arch/um/Kconfig.char
> @@ -236,4 +236,15 @@ config MMAPPER
>  	  This driver allows a host file to be used as emulated IO memory inside
>  	  UML.
>  
> +config DEVTIME
> +	tristate "/dev/time virtual device support."
> +	depends on EXPERIMENTAL
> +	help
> +	  This device provides a file-based interface to the system clock.
> +	  The interface is based on the /dev/time device used in the
> +	  Plan 9 operating system from Bell Labs.
> +	  See <file:Documentation/time-device.txt> for a full description.
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called devtime.
> +
>  endmenu
> diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
> index 735bbe2..5bad918 100644
> --- a/drivers/char/Kconfig
> +++ b/drivers/char/Kconfig
> @@ -97,6 +97,17 @@ config DEVKMEM
>  	  kind of kernel debugging operations.
>  	  When in doubt, say "N".
>  
> +config DEVTIME
> +	tristate "/dev/time virtual device support."
> +	depends on EXPERIMENTAL
> +	help
> +	  This device provides a file-based interface to the system clock.
> +	  The interface is based on the /dev/time device used in the
> +	  Plan 9 operating system from Bell Labs.
> +	  See <file:Documentation/time-device.txt> for a full description.
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called devtime.
> +
>  config SERIAL_NONSTANDARD
>  	bool "Non-standard serial port support"
>  	depends on HAS_IOMEM
> diff --git a/drivers/char/Makefile b/drivers/char/Makefile
> index 9caf5b5..aba7403 100644
> --- a/drivers/char/Makefile
> +++ b/drivers/char/Makefile
> @@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH)		+= ps3flash.o
>  obj-$(CONFIG_JS_RTC)		+= js-rtc.o
>  js-rtc-y = rtc.o
>  
> +obj-$(CONFIG_DEVTIME)		+= devtime.o
> +
>  # Files generated that shall be removed upon make clean
>  clean-files := consolemap_deftbl.c defkeymap.c
>  
> diff --git a/drivers/char/devtime.c b/drivers/char/devtime.c
> new file mode 100644
> index 0000000..5e4ca66
> --- /dev/null
> +++ b/drivers/char/devtime.c
> @@ -0,0 +1,112 @@
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/fs.h>
> +#include <linux/miscdevice.h>
> +#include <linux/time.h>
> +#include <linux/jiffies.h>
> +#include <linux/uaccess.h>
> +
> +MODULE_AUTHOR("Christopher Brannon <cmbrannon79@gmail.com>");
> +MODULE_LICENSE("GPL");
> +
> +const long long NS_PER_SEC = 1000000000;
> +const long long NS_PER_USEC = 1000;
> +const size_t time_bufsize = 256;
> +
> +static ssize_t time_read(struct file *, char __user *, size_t, loff_t *);
> +static ssize_t time_write(struct file *, const char __user *, size_t, loff_t *);
> +
> +static const struct file_operations time_fops = {
> +	.owner = THIS_MODULE,
> +	.read = time_read,
> +	.write = time_write,
> +};
> +
> +static struct miscdevice timedev = {
> +	.minor = MISC_DYNAMIC_MINOR,
> +	.name = "time",
> +	.fops = &time_fops
> +};
> +
> +static int time2text(char *buffer, size_t bufsize)
> +{
> +	int count = 0;
> +	struct timeval tv;
> +	long long nanos;
> +
> +/* jiffies isn't 0 at boot time; its value is INITIAL_JIFFIES. */
> +	u64 ticks = get_jiffies_64() - INITIAL_JIFFIES;

Are you sure this will handle the roll-over properly?

> +	do_gettimeofday(&tv);
> +	nanos = tv.tv_sec * NS_PER_SEC + tv.tv_usec * NS_PER_USEC;
> +	count =
> +	    scnprintf(buffer, bufsize, "%ld %lld %llu %d\n", tv.tv_sec, nanos,
> +		      ticks, HZ);
> +	return count;
> +}
> +
> +static int text2time(char *buffer)
> +{
> +	struct timespec tv;
> +	int result = strict_strtol(buffer, 10, &tv.tv_sec);
> +	if ((result == 0) && (tv.tv_sec > 0)) {
> +		tv.tv_nsec = 0;
> +		do_settimeofday(&tv);
> +	} else
> +		result = -EINVAL;	/* only positive longs are valid. */
> +	return result;
> +}
> +
> +static ssize_t
> +time_read(struct file *f, char __user *buffer, size_t count, loff_t * offset)
> +{
> +	int result = 0;
> +	if (*offset != 0)
> +		result = 0;
> +	else {
> +		char tmpbuf[time_bufsize];

Not good to put 256 bytes on the stack.  Dynamically allocate it?

> +		int timetextlen = time2text(tmpbuf, time_bufsize);
> +		unsigned long readcount = min(count, (size_t) timetextlen);

As was recently pointed out to me, we have min_t() for when you need to
cast like this.

> +		if (timetextlen <= 0)
> +			return -EAGAIN;

If it equals 0, shouldn't you return 0?  And how could it be negative?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH] /dev/time for Linux, inspired by Plan 9
@ 2009-03-04  3:06 Christopher Brannon
  2009-03-06 17:57 ` Greg KH
                   ` (3 more replies)
  0 siblings, 4 replies; 21+ messages in thread
From: Christopher Brannon @ 2009-03-04  3:06 UTC (permalink / raw)
  To: linux-kernel

Under Plan 9 from Bell Labs, one queries or sets the system clock by
reading or writing text strings to a special file named /dev/time.
I implemented such a facility for Linux.  A read of /dev/time produces
four decimal numbers: epoch seconds, nanoseconds since start of epoch,
jiffies since boot, and jiffies per second.  Writing a decimal number to
/dev/time sets the system clock to the given number of epoch seconds.
Anyone who is permitted to write to /dev/time may set the clock.
Granting this privilege becomes as easy as modifying groups and file
permissions.

Signed-off-by: Christopher Brannon <cmbrannon@cox.net>
---
 Documentation/time-device.txt |   49 ++++++++++++++++++
 arch/um/Kconfig.char          |   11 ++++
 drivers/char/Kconfig          |   11 ++++
 drivers/char/Makefile         |    2 +
 drivers/char/devtime.c        |  112 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 185 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/time-device.txt
 create mode 100644 drivers/char/devtime.c

diff --git a/Documentation/time-device.txt b/Documentation/time-device.txt
new file mode 100644
index 0000000..6294732
--- /dev/null
+++ b/Documentation/time-device.txt
@@ -0,0 +1,49 @@
+/dev/time for Linux
+===================
+
+Christopher M. Brannon <cmbrannon@cox.net>
+
+Inspiration
+-----------
+This document describes an implementation for the Linux kernel of a facility
+that is provided by the Plan 9 operating system from Bell Laboratories [1].
+
+Functionality
+-------------
+/dev/time provides a file-based interface to the system clock.
+Using this interface, one can query or set the system clock by reading or
+writing text strings.  A read of /dev/time yields four decimal integers:
+seconds since start of epoch, nanoseconds since start of epoch,
+jiffies since boot, and jiffies per second.
+Writing a decimal number n to /dev/time sets the system clock to the
+date and time which is n seconds greater than January 1, 1970, 00:00:00 GMT.
+
+Examples
+--------
+cat /dev/time
+# Produces: 1236121128 123612012877063000 495497 300,
+# at time of writing on a test machine.
+echo 287604960 > /dev/time
+# sets the clock to the approximate time of my birth.
+
+Use Case
+--------
+Traditionally, super-user privileges were required in order to set the
+system clock under Linux.
+Since the advent of capabilities, any process having the CAP_SYS_TIME
+capability may perform this operation.
+The /dev/time device ties privileges to file permissions.  If a user
+can write to /dev/time, then he can set the system clock.
+
+Difference from Plan 9
+-----------------------
+This implementation differs from Plan 9 in one respect.  the Plan 9
+Programmer's Manual exactly specifies the format of data read from the
+device, including the widths of the four numeric fields [1].  This Linux
+implementation does not pad values with whitespace, so the four fields
+are of variable width.
+
+References
+----------
+[1] Plan 9 Programmers Manual, section 3.
+http://plan9.bell-labs.com/magic/man2html/3/cons
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index 70dabd1..7d0da78 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -236,4 +236,15 @@ config MMAPPER
 	  This driver allows a host file to be used as emulated IO memory inside
 	  UML.
 
+config DEVTIME
+	tristate "/dev/time virtual device support."
+	depends on EXPERIMENTAL
+	help
+	  This device provides a file-based interface to the system clock.
+	  The interface is based on the /dev/time device used in the
+	  Plan 9 operating system from Bell Labs.
+	  See <file:Documentation/time-device.txt> for a full description.
+	  To compile this driver as a module, choose M here: the
+	  module will be called devtime.
+
 endmenu
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 735bbe2..5bad918 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -97,6 +97,17 @@ config DEVKMEM
 	  kind of kernel debugging operations.
 	  When in doubt, say "N".
 
+config DEVTIME
+	tristate "/dev/time virtual device support."
+	depends on EXPERIMENTAL
+	help
+	  This device provides a file-based interface to the system clock.
+	  The interface is based on the /dev/time device used in the
+	  Plan 9 operating system from Bell Labs.
+	  See <file:Documentation/time-device.txt> for a full description.
+	  To compile this driver as a module, choose M here: the
+	  module will be called devtime.
+
 config SERIAL_NONSTANDARD
 	bool "Non-standard serial port support"
 	depends on HAS_IOMEM
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 9caf5b5..aba7403 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -111,6 +111,8 @@ obj-$(CONFIG_PS3_FLASH)		+= ps3flash.o
 obj-$(CONFIG_JS_RTC)		+= js-rtc.o
 js-rtc-y = rtc.o
 
+obj-$(CONFIG_DEVTIME)		+= devtime.o
+
 # Files generated that shall be removed upon make clean
 clean-files := consolemap_deftbl.c defkeymap.c
 
diff --git a/drivers/char/devtime.c b/drivers/char/devtime.c
new file mode 100644
index 0000000..5e4ca66
--- /dev/null
+++ b/drivers/char/devtime.c
@@ -0,0 +1,112 @@
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/time.h>
+#include <linux/jiffies.h>
+#include <linux/uaccess.h>
+
+MODULE_AUTHOR("Christopher Brannon <cmbrannon79@gmail.com>");
+MODULE_LICENSE("GPL");
+
+const long long NS_PER_SEC = 1000000000;
+const long long NS_PER_USEC = 1000;
+const size_t time_bufsize = 256;
+
+static ssize_t time_read(struct file *, char __user *, size_t, loff_t *);
+static ssize_t time_write(struct file *, const char __user *, size_t, loff_t *);
+
+static const struct file_operations time_fops = {
+	.owner = THIS_MODULE,
+	.read = time_read,
+	.write = time_write,
+};
+
+static struct miscdevice timedev = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = "time",
+	.fops = &time_fops
+};
+
+static int time2text(char *buffer, size_t bufsize)
+{
+	int count = 0;
+	struct timeval tv;
+	long long nanos;
+
+/* jiffies isn't 0 at boot time; its value is INITIAL_JIFFIES. */
+	u64 ticks = get_jiffies_64() - INITIAL_JIFFIES;
+
+	do_gettimeofday(&tv);
+	nanos = tv.tv_sec * NS_PER_SEC + tv.tv_usec * NS_PER_USEC;
+	count =
+	    scnprintf(buffer, bufsize, "%ld %lld %llu %d\n", tv.tv_sec, nanos,
+		      ticks, HZ);
+	return count;
+}
+
+static int text2time(char *buffer)
+{
+	struct timespec tv;
+	int result = strict_strtol(buffer, 10, &tv.tv_sec);
+	if ((result == 0) && (tv.tv_sec > 0)) {
+		tv.tv_nsec = 0;
+		do_settimeofday(&tv);
+	} else
+		result = -EINVAL;	/* only positive longs are valid. */
+	return result;
+}
+
+static ssize_t
+time_read(struct file *f, char __user *buffer, size_t count, loff_t * offset)
+{
+	int result = 0;
+	if (*offset != 0)
+		result = 0;
+	else {
+		char tmpbuf[time_bufsize];
+		int timetextlen = time2text(tmpbuf, time_bufsize);
+		unsigned long readcount = min(count, (size_t) timetextlen);
+		if (timetextlen <= 0)
+			return -EAGAIN;
+		if (!copy_to_user(buffer, tmpbuf, readcount)) {
+			*offset += readcount;
+			result = readcount;
+		} else
+			result = -EFAULT;
+	}
+	return result;
+}
+
+static ssize_t
+time_write(struct file *f, const char __user * buffer, size_t count,
+	   loff_t *offset)
+{
+	unsigned int result = 0;
+	char tmpbuf[time_bufsize];
+
+	if (*offset != 0)
+		return -EINVAL;
+	if (count > ((size_t) time_bufsize - 1))
+		return -EINVAL;	/* Likely trying to feed bogus data anyway. */
+	result = copy_from_user(tmpbuf, buffer, count);
+	if (result)
+		return -EFAULT;
+	tmpbuf[count] = '\0';
+	if (text2time(tmpbuf))
+		return -EINVAL;
+	return count;
+}
+
+static int __init time_init(void)
+{
+	return misc_register(&timedev);
+}
+
+static void __exit time_exit(void)
+{
+	misc_deregister(&timedev);
+}
+
+module_init(time_init);
+module_exit(time_exit);
-- 
1.6.1.3


^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2009-03-21 22:02 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-11 15:10 [PATCH] /dev/time for Linux, inspired by Plan 9 Christopher Brannon
2009-03-11 21:49 ` Jochen Voß
2009-03-11 22:07 ` Bill Nottingham
2009-03-12  8:00   ` David Newall
2009-03-12 18:15     ` J.R. Mauro
2009-03-12  9:30 ` Giacomo A. Catenazzi
2009-03-14 16:13 ` Pavel Machek
2009-03-17 15:15   ` J.R. Mauro
2009-03-21 22:05     ` Pavel Machek
  -- strict thread matches above, loose matches on Subject: below --
2009-03-04  3:06 Christopher Brannon
2009-03-06 17:57 ` Greg KH
2009-03-07  5:43   ` J.R. Mauro
2009-03-07  5:54     ` Greg KH
2009-03-07 16:08       ` Chris Brannon
2009-03-08 16:03       ` J.R. Mauro
2009-03-06 22:56 ` john stultz
2009-03-07 16:23   ` Chris Brannon
2009-03-12 18:12     ` J.R. Mauro
2009-03-14 23:27       ` Chris Brannon
2009-03-10 11:22 ` Pavel Machek
2009-03-11  7:28 ` Américo Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.