<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">From pjones@redhat.com Sat Jun 25 09:19:56 2005
Subject: /sys/block/hda/sample.sh
From: Peter Jones &lt;pjones@redhat.com&gt;
To: gregkh@suse.de
Date: Sat, 25 Jun 2005 11:57:46 -0400
Message-Id: &lt;1119715067.22239.1.camel@localhost.localdomain&gt;

Greg, here's a patch.  I'm thinking maybe the selinux context should be
a config option or a sysctl, but if distros care it's easy to patch it
to the right thing or just replace it at runtime.

From: Peter Jones &lt;pjones@redhat.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;


---
 drivers/base/class.c   |   34 ++++++++++++++++++++++++++++++++++
 drivers/block/genhd.c  |   25 +++++++++++++++++++++++++
 fs/partitions/check.c  |   27 +++++++++++++++++++++++++++
 include/linux/device.h |    1 +
 4 files changed, 87 insertions(+)

--- gregkh-2.6.orig/drivers/block/genhd.c	2005-08-17 23:44:17.000000000 -0700
+++ gregkh-2.6/drivers/block/genhd.c	2005-08-17 23:44:18.000000000 -0700
@@ -15,6 +15,7 @@
 #include &lt;linux/kmod.h&gt;
 #include &lt;linux/kobj_map.h&gt;
 #include &lt;linux/buffer_head.h&gt;
+#include &lt;linux/mount.h&gt;
 
 #define MAX_PROBE_HASH 255	/* random */
 
@@ -382,6 +383,25 @@ static ssize_t disk_stats_read(struct ge
 		jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
 		jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
 }
+static ssize_t disk_sample_read(struct gendisk * disk, char *page)
+{
+	char buf[BDEVNAME_SIZE];
+	const char * context = "system_u:object_r:fixed_disk_device_t";
+	struct vfsmount *mnt;
+	int n;
+
+	n = sprintf(page, "#!/bin/sh\nmknod ");
+
+	mnt = do_kern_mount("selinuxfs", 0, "selinuxfs", NULL);
+	if (!IS_ERR(mnt)) {
+		mntput(mnt);
+		n += sprintf(page+n, "-Z %s ", context);
+	}
+	n += sprintf(page+n, "/dev/%s b %d %d\n", disk_name(disk, 0, buf),
+		disk-&gt;major, disk-&gt;first_minor);
+
+	return n;
+}
 static struct disk_attribute disk_attr_dev = {
 	.attr = {.name = "dev", .mode = S_IRUGO },
 	.show	= disk_dev_read
@@ -402,6 +422,10 @@ static struct disk_attribute disk_attr_s
 	.attr = {.name = "stat", .mode = S_IRUGO },
 	.show	= disk_stats_read
 };
+static struct disk_attribute disk_attr_sample = {
+	.attr = {.name = "sample.sh", .mode = S_IRUSR | S_IXUSR | S_IRUGO },
+	.show	= disk_sample_read
+};
 
 static struct attribute * default_attrs[] = {
 	&amp;disk_attr_dev.attr,
@@ -409,6 +433,7 @@ static struct attribute * default_attrs[
 	&amp;disk_attr_removable.attr,
 	&amp;disk_attr_size.attr,
 	&amp;disk_attr_stat.attr,
+	&amp;disk_attr_sample.attr,
 	NULL,
 };
 
--- gregkh-2.6.orig/fs/partitions/check.c	2005-08-17 23:44:17.000000000 -0700
+++ gregkh-2.6/fs/partitions/check.c	2005-08-17 23:44:18.000000000 -0700
@@ -36,6 +36,8 @@
 #include "ultrix.h"
 #include "efi.h"
 
+#include &lt;linux/mount.h&gt;
+
 #ifdef CONFIG_BLK_DEV_MD
 extern void md_autodetect_dev(dev_t dev);
 #endif
@@ -229,6 +231,26 @@ static ssize_t part_stat_read(struct hd_
 		       p-&gt;reads, (unsigned long long)p-&gt;read_sectors,
 		       p-&gt;writes, (unsigned long long)p-&gt;write_sectors);
 }
+static ssize_t part_sample_read(struct hd_struct * p, char *page)
+{
+	struct gendisk *disk = container_of(p-&gt;kobj.parent,struct gendisk,kobj);
+	char buf[BDEVNAME_SIZE];
+	const char * context = "system_u:object_r:fixed_disk_device_t";
+	struct vfsmount *mnt;
+	int n;
+
+	n = sprintf(page, "#!/bin/sh\nmknod ");
+
+	mnt = do_kern_mount("selinuxfs", 0, "selinuxfs", NULL);
+	if (!IS_ERR(mnt)) {
+		mntput(mnt);
+		n += sprintf(page+n, "-Z %s ", context);
+	}
+	n += sprintf(page+n, "/dev/%s b %d %d\n", disk_name(disk, p-&gt;partno, buf),
+		disk-&gt;major, disk-&gt;first_minor + p-&gt;partno);
+
+	return n;
+}
 static struct part_attribute part_attr_dev = {
 	.attr = {.name = "dev", .mode = S_IRUGO },
 	.show	= part_dev_read
@@ -245,12 +267,17 @@ static struct part_attribute part_attr_s
 	.attr = {.name = "stat", .mode = S_IRUGO },
 	.show	= part_stat_read
 };
+static struct part_attribute part_attr_sample = {
+	.attr = {.name = "sample.sh", .mode = S_IRUSR | S_IXUSR | S_IRUGO },
+	.show	= part_sample_read
+};
 
 static struct attribute * default_attrs[] = {
 	&amp;part_attr_dev.attr,
 	&amp;part_attr_start.attr,
 	&amp;part_attr_size.attr,
 	&amp;part_attr_stat.attr,
+	&amp;part_attr_sample.attr,
 	NULL,
 };
 
--- gregkh-2.6.orig/drivers/base/class.c	2005-08-17 23:44:17.000000000 -0700
+++ gregkh-2.6/drivers/base/class.c	2005-08-17 23:44:19.000000000 -0700
@@ -17,6 +17,7 @@
 #include &lt;linux/string.h&gt;
 #include &lt;linux/kdev_t.h&gt;
 #include &lt;linux/err.h&gt;
+#include &lt;linux/mount.h&gt;
 #include "base.h"
 
 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
@@ -445,6 +446,24 @@ static ssize_t show_dev(struct class_dev
 	return print_dev_t(buf, class_dev-&gt;devt);
 }
 
+static ssize_t show_sample(struct class_device *class_dev, char *buf)
+{
+	const char * context = "system_u:object_r:fixed_disk_device_t";
+	struct vfsmount *mnt;
+	int n;
+
+	n = sprintf(buf, "#!/bin/sh\nmknod ");
+
+	mnt = do_kern_mount("selinuxfs", 0, "selinuxfs", NULL);
+	if (!IS_ERR(mnt)) {
+		mntput(mnt);
+		n += sprintf(buf+n, "-Z %s ", context);
+	}
+	n += sprintf(buf+n, "/dev/%s c %d %d\n", kobject_name(&amp;class_dev-&gt;kobj),
+		     MAJOR(class_dev-&gt;devt), MINOR(class_dev-&gt;devt));
+
+	return n;
+}
 void class_device_initialize(struct class_device *class_dev)
 {
 	kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -516,6 +535,21 @@ int class_device_add(struct class_device
 		attr-&gt;store = NULL;
 		class_device_create_file(class_dev, attr);
 		class_dev-&gt;devt_attr = attr;
+
+		attr = kmalloc(sizeof(*attr), GFP_KERNEL);
+		if (!attr) {
+			error = -ENOMEM;
+			kobject_del(&amp;class_dev-&gt;kobj);
+			goto register_done;
+		}
+		memset(attr, sizeof(*attr), 0x00);
+		attr-&gt;attr.name = "sample.sh";
+		attr-&gt;attr.mode = S_IRUSR | S_IXUSR | S_IRUGO;
+		attr-&gt;attr.owner = parent-&gt;owner;
+		attr-&gt;show = show_sample;
+		attr-&gt;store = NULL;
+		class_device_create_file(class_dev, attr);
+		class_dev-&gt;sample_attr = attr;
 	}
 
 	class_device_add_attrs(class_dev);
--- gregkh-2.6.orig/include/linux/device.h	2005-08-17 23:44:17.000000000 -0700
+++ gregkh-2.6/include/linux/device.h	2005-08-17 23:44:19.000000000 -0700
@@ -198,6 +198,7 @@ struct class_device {
 	struct class		* class;	/* required */
 	dev_t			devt;		/* dev_t, creates the sysfs "dev" */
 	struct class_device_attribute *devt_attr;
+	struct class_device_attribute *sample_attr;
 	struct device		* dev;		/* not necessary, but nice to have */
 	void			* class_data;	/* class-specific data */
 
</pre></body></html>