Re: [PATCH 2/8] PM: suspend_block: Add driver to access suspend blockers from user-space

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri 2010-04-30 15:36:55, Arve Hj??nnev??g wrote:
> Add a misc device, "suspend_blocker", that allows user-space processes
> to block auto suspend. The device has ioctls to create a suspend_blocker,
> and to block and unblock suspend. To delete the suspend_blocker, close
> the device.

Yeah, this one is overly complex; instead of having 'open blocks
suspend' semantics and lsof listing active blockers, it adds strange
ioctl based interface passing names, and then adds debugfs
infrastructure listing those back.

I guess this is why you are getying 'it should be in /proc, no in
/sys, no in debugfs, no in /proc' kind of feedback. This should simply
not exist in the first place...

> Signed-off-by: Arve Hj??nnev??g <arve@xxxxxxxxxxx>

NAK.

> ---
>  Documentation/ioctl/ioctl-number.txt          |    3 +-
>  Documentation/power/opportunistic-suspend.txt |   17 ++++
>  include/linux/suspend_block_dev.h             |   25 +++++
>  kernel/power/Kconfig                          |    9 ++
>  kernel/power/Makefile                         |    1 +
>  kernel/power/user_suspend_blocker.c           |  128 +++++++++++++++++++++++++
>  6 files changed, 182 insertions(+), 1 deletions(-)
>  create mode 100644 include/linux/suspend_block_dev.h
>  create mode 100644 kernel/power/user_suspend_blocker.c
> 
> diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
> index dd5806f..e2458f7 100644
> --- a/Documentation/ioctl/ioctl-number.txt
> +++ b/Documentation/ioctl/ioctl-number.txt
> @@ -254,7 +254,8 @@ Code  Seq#(hex)	Include File		Comments
>  'q'	80-FF	linux/telephony.h	Internet PhoneJACK, Internet LineJACK
>  		linux/ixjuser.h		<http://www.quicknet.net>
>  'r'	00-1F	linux/msdos_fs.h and fs/fat/dir.c
> -'s'	all	linux/cdk.h
> +'s'	all	linux/cdk.h	conflict!
> +'s'	all	linux/suspend_block_dev.h	conflict!
>  't'	00-7F	linux/if_ppp.h
>  't'	80-8F	linux/isdn_ppp.h
>  't'	90	linux/toshiba.h
> diff --git a/Documentation/power/opportunistic-suspend.txt b/Documentation/power/opportunistic-suspend.txt
> index 3d060e8..f2b145e 100644
> --- a/Documentation/power/opportunistic-suspend.txt
> +++ b/Documentation/power/opportunistic-suspend.txt
> @@ -117,3 +117,20 @@ if (list_empty(&state->pending_work))
>  else
>  	suspend_block(&state->suspend_blocker);
>  
> +User-space API
> +==============
> +
> +To create a suspend_blocker from user-space, open the suspend_blocker device:
> +    fd = open("/dev/suspend_blocker", O_RDWR | O_CLOEXEC);
> +then call:
> +    ioctl(fd, SUSPEND_BLOCKER_IOCTL_INIT(strlen(name)), name);
> +
> +To activate a suspend_blocker call:
> +    ioctl(fd, SUSPEND_BLOCKER_IOCTL_BLOCK);
> +
> +To unblock call:
> +    ioctl(fd, SUSPEND_BLOCKER_IOCTL_UNBLOCK);
> +
> +To destroy the suspend_blocker, close the device:
> +    close(fd);
> +
> diff --git a/include/linux/suspend_block_dev.h b/include/linux/suspend_block_dev.h
> new file mode 100644
> index 0000000..24bc5c7
> --- /dev/null
> +++ b/include/linux/suspend_block_dev.h
> @@ -0,0 +1,25 @@
> +/* include/linux/suspend_block_dev.h
> + *
> + * Copyright (C) 2009 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef _LINUX_SUSPEND_BLOCK_DEV_H
> +#define _LINUX_SUSPEND_BLOCK_DEV_H
> +
> +#include <linux/ioctl.h>
> +
> +#define SUSPEND_BLOCKER_IOCTL_INIT(len)		_IOC(_IOC_WRITE, 's', 0, len)
> +#define SUSPEND_BLOCKER_IOCTL_BLOCK		_IO('s', 1)
> +#define SUSPEND_BLOCKER_IOCTL_UNBLOCK		_IO('s', 2)
> +
> +#endif
> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
> index 55a06a1..fe5a2f2 100644
> --- a/kernel/power/Kconfig
> +++ b/kernel/power/Kconfig
> @@ -146,6 +146,15 @@ config OPPORTUNISTIC_SUSPEND
>  	  determines the sleep state the system will be put into when there are
>  	  no active suspend blockers.
>  
> +config USER_SUSPEND_BLOCKERS
> +	bool "Userspace suspend blockers"
> +	depends on OPPORTUNISTIC_SUSPEND
> +	default y
> +	---help---
> +	  User-space suspend block api. Creates a misc device with ioctls
> +	  to create, block and unblock a suspend_blocker. The suspend_blocker
> +	  will be deleted when the device is closed.
> +
>  config HIBERNATION_NVS
>  	bool
>  
> diff --git a/kernel/power/Makefile b/kernel/power/Makefile
> index ee5276d..78f703b 100644
> --- a/kernel/power/Makefile
> +++ b/kernel/power/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_PM_SLEEP)		+= console.o
>  obj-$(CONFIG_FREEZER)		+= process.o
>  obj-$(CONFIG_SUSPEND)		+= suspend.o
>  obj-$(CONFIG_OPPORTUNISTIC_SUSPEND)	+= suspend_blocker.o
> +obj-$(CONFIG_USER_SUSPEND_BLOCKERS)	+= user_suspend_blocker.o
>  obj-$(CONFIG_PM_TEST_SUSPEND)	+= suspend_test.o
>  obj-$(CONFIG_HIBERNATION)	+= hibernate.o snapshot.o swap.o user.o
>  obj-$(CONFIG_HIBERNATION_NVS)	+= hibernate_nvs.o
> diff --git a/kernel/power/user_suspend_blocker.c b/kernel/power/user_suspend_blocker.c
> new file mode 100644
> index 0000000..dc1d06f
> --- /dev/null
> +++ b/kernel/power/user_suspend_blocker.c
> @@ -0,0 +1,128 @@
> +/* kernel/power/user_suspend_block.c
> + *
> + * Copyright (C) 2009-2010 Google, Inc.
> + *
> + * This software is licensed under the terms of the GNU General Public
> + * License version 2, as published by the Free Software Foundation, and
> + * may be copied, distributed, and modified under those terms.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include <linux/fs.h>
> +#include <linux/miscdevice.h>
> +#include <linux/module.h>
> +#include <linux/uaccess.h>
> +#include <linux/slab.h>
> +#include <linux/suspend_blocker.h>
> +#include <linux/suspend_block_dev.h>
> +
> +enum {
> +	DEBUG_FAILURE	= BIT(0),
> +};
> +static int debug_mask = DEBUG_FAILURE;
> +module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
> +
> +static DEFINE_MUTEX(ioctl_lock);
> +
> +struct user_suspend_blocker {
> +	struct suspend_blocker	blocker;
> +	char			name[0];
> +};
> +
> +static int create_user_suspend_blocker(struct file *file, void __user *name,
> +				 size_t name_len)
> +{
> +	struct user_suspend_blocker *bl;
> +	if (file->private_data)
> +		return -EBUSY;
> +	if (name_len > NAME_MAX)
> +		return -ENAMETOOLONG;
> +	bl = kzalloc(sizeof(*bl) + name_len + 1, GFP_KERNEL);
> +	if (!bl)
> +		return -ENOMEM;
> +	if (copy_from_user(bl->name, name, name_len))
> +		goto err_fault;
> +	suspend_blocker_init(&bl->blocker, bl->name);
> +	file->private_data = bl;
> +	return 0;
> +
> +err_fault:
> +	kfree(bl);
> +	return -EFAULT;
> +}
> +
> +static long user_suspend_blocker_ioctl(struct file *file, unsigned int cmd,
> +				unsigned long _arg)
> +{
> +	void __user *arg = (void __user *)_arg;
> +	struct user_suspend_blocker *bl;
> +	long ret;
> +
> +	mutex_lock(&ioctl_lock);
> +	if ((cmd & ~IOCSIZE_MASK) == SUSPEND_BLOCKER_IOCTL_INIT(0)) {
> +		ret = create_user_suspend_blocker(file, arg, _IOC_SIZE(cmd));
> +		goto done;
> +	}
> +	bl = file->private_data;
> +	if (!bl) {
> +		ret = -ENOENT;
> +		goto done;
> +	}
> +	switch (cmd) {
> +	case SUSPEND_BLOCKER_IOCTL_BLOCK:
> +		suspend_block(&bl->blocker);
> +		ret = 0;
> +		break;
> +	case SUSPEND_BLOCKER_IOCTL_UNBLOCK:
> +		suspend_unblock(&bl->blocker);
> +		ret = 0;
> +		break;
> +	default:
> +		ret = -ENOTSUPP;
> +	}
> +done:
> +	if (ret && (debug_mask & DEBUG_FAILURE))
> +		pr_err("user_suspend_blocker_ioctl: cmd %x failed, %ld\n",
> +			cmd, ret);
> +	mutex_unlock(&ioctl_lock);
> +	return ret;
> +}
> +
> +static int user_suspend_blocker_release(struct inode *inode, struct file *file)
> +{
> +	struct user_suspend_blocker *bl = file->private_data;
> +	if (!bl)
> +		return 0;
> +	suspend_blocker_destroy(&bl->blocker);
> +	kfree(bl);
> +	return 0;
> +}
> +
> +const struct file_operations user_suspend_blocker_fops = {
> +	.release = user_suspend_blocker_release,
> +	.unlocked_ioctl = user_suspend_blocker_ioctl,
> +};
> +
> +struct miscdevice user_suspend_blocker_device = {
> +	.minor = MISC_DYNAMIC_MINOR,
> +	.name = "suspend_blocker",
> +	.fops = &user_suspend_blocker_fops,
> +};
> +
> +static int __init user_suspend_blocker_init(void)
> +{
> +	return misc_register(&user_suspend_blocker_device);
> +}
> +
> +static void __exit user_suspend_blocker_exit(void)
> +{
> +	misc_deregister(&user_suspend_blocker_device);
> +}
> +
> +module_init(user_suspend_blocker_init);
> +module_exit(user_suspend_blocker_exit);

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
_______________________________________________
linux-pm mailing list
linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux