From pjones@redhat.com Sat Jun 25 09:19:56 2005 Subject: /sys/block/hda/sample.sh From: Peter Jones To: gregkh@suse.de Date: Sat, 25 Jun 2005 11:57:46 -0400 Message-Id: <1119715067.22239.1.camel@localhost.localdomain> 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 Signed-off-by: Greg Kroah-Hartman --- block/genhd.c | 13 +++++++++++++ drivers/base/class.c | 22 ++++++++++++++++++++++ fs/partitions/check.c | 14 ++++++++++++++ include/linux/device.h | 1 + 4 files changed, 50 insertions(+) --- gregkh-2.6.orig/block/genhd.c +++ gregkh-2.6/block/genhd.c @@ -401,6 +401,14 @@ 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]; + + return sprintf(page, "#!/bin/sh\nmknod /dev/%s b %d %d\n", + disk_name(disk, 0, buf), + disk->major, disk->first_minor); +} static struct disk_attribute disk_attr_uevent = { .attr = {.name = "uevent", .mode = S_IWUSR }, .store = disk_uevent_store @@ -425,6 +433,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[] = { &disk_attr_uevent.attr, @@ -433,6 +445,7 @@ static struct attribute * default_attrs[ &disk_attr_removable.attr, &disk_attr_size.attr, &disk_attr_stat.attr, + &disk_attr_sample.attr, NULL, }; --- gregkh-2.6.orig/fs/partitions/check.c +++ gregkh-2.6/fs/partitions/check.c @@ -249,6 +249,15 @@ static ssize_t part_stat_read(struct hd_ p->ios[0], (unsigned long long)p->sectors[0], p->ios[1], (unsigned long long)p->sectors[1]); } +static ssize_t part_sample_read(struct hd_struct *p, char *page) +{ + struct gendisk *disk = container_of(p->kobj.parent, struct gendisk, kobj); + char buf[BDEVNAME_SIZE]; + + return sprintf(page, "#!/bin/sh\nmknod /dev/%s b %d %d\n", + disk_name(disk, p->partno, buf), + disk->major, disk->first_minor + p->partno); +} static struct part_attribute part_attr_uevent = { .attr = {.name = "uevent", .mode = S_IWUSR }, .store = part_uevent_store @@ -269,6 +278,10 @@ 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[] = { &part_attr_uevent.attr, @@ -276,6 +289,7 @@ static struct attribute * default_attrs[ &part_attr_start.attr, &part_attr_size.attr, &part_attr_stat.attr, + &part_attr_sample.attr, NULL, }; --- gregkh-2.6.orig/drivers/base/class.c +++ gregkh-2.6/drivers/base/class.c @@ -468,6 +468,13 @@ static ssize_t store_uevent(struct class return count; } +static ssize_t show_sample(struct class_device *class_dev, char *buf) +{ + return sprintf(buf, "#!/bin/sh\nmknod /dev/%s c %d %d\n", + kobject_name(&class_dev->kobj), + MAJOR(class_dev->devt), MINOR(class_dev->devt)); +} + void class_device_initialize(struct class_device *class_dev) { kobj_set_kset_s(class_dev, class_obj_subsys); @@ -548,6 +555,21 @@ int class_device_add(struct class_device attr->show = show_dev; class_device_create_file(class_dev, attr); class_dev->devt_attr = attr; + + attr = kzalloc(sizeof(*attr), GFP_KERNEL); + if (!attr) { + error = -ENOMEM; + kobject_del(&class_dev->kobj); + goto register_done; + } + + attr->attr.name = "sample.sh"; + attr->attr.mode = S_IRUSR | S_IXUSR | S_IRUGO; + attr->attr.owner = parent_class->owner; + attr->show = show_sample; + attr->store = NULL; + class_device_create_file(class_dev, attr); + class_dev->sample_attr = attr; } class_device_add_attrs(class_dev); --- gregkh-2.6.orig/include/linux/device.h +++ gregkh-2.6/include/linux/device.h @@ -222,6 +222,7 @@ struct class_device { dev_t devt; /* dev_t, creates the sysfs "dev" */ struct class_device_attribute *devt_attr; struct class_device_attribute uevent_attr; + struct class_device_attribute *sample_attr; struct device * dev; /* not necessary, but nice to have */ void * class_data; /* class-specific data */ struct class_device *parent; /* parent of this child device, if there is one */