Patchset related to hibernation resume: one enhancement to make the use
of an existing resume file more general and one enhances name_to_dev_t
to ignore the trailing newlines coming from userspace.
Both patches are based on the 3.11 tag. This was tested on a
Pandaboard with partial hibernation support, and compiled for x86.
Further testing is needed on other platforms. Please let me know if
you're able to verify this on any other systems.
[PATCH 1/2] init/do_mounts.c: ignore final \n in name_to_dev_t
init/do_mounts.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
Changes name_to_dev_t to handle a trailing newline in the
input buffer, which will allow name_to_dev_t to be used
directly with user buffers without requiring a copy.
Also adds a const to the name parameter which reflects
how name_to_dev_t is treating the input buffer currently.
This also allows direct use of user buffers
(from resume_store for example).
[PATCH 2/2] PM / Hibernate: use name_to_dev_t to parse resume
kernel/power/hibernate.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
Use name_to_dev_t to parse the /sys/power/resume file making the
syntax more flexible. It supports the previous use syntax
and additionally can support other formats such as
/dev/devicenode and UUID= formats.
By changing /sys/debug/resume to accept the same syntax as
the resume=device parameter, we can parse the resume=device
in the initrd init script and use the resume device directly
from the kernel command line.
Changes in v3:
--------------
* Dropped documentation patch as it went in through trivial
* Added patch for name_to_dev_t to support directly parsing userspace
buffer
Changes in v2:
--------------
* Added check for null return of kstrndup in hibernate.c
Thanks,
Sebastian
Enhance name_to_dev_t to handle trailing newline characters
on device paths. Some inputs to name_to_dev_t may come from
userspace where oftentimes a '\n' is appended to the path.
Added const to the name buffer in both the function
declaration and the prototype to reflect input buffer
handling.
By handling trailing newlines in name_to_dev_t, userspace
buffers may be directly passed to name_to_dev_t without
modification.
Signed-off-by: Sebastian Capella <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: "Eric W. Biederman" <[email protected]>
Cc: Serge Hallyn <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Stephen Warren <[email protected]>
Cc: Jens Axboe <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Al Viro <[email protected]>
---
include/linux/mount.h | 2 +-
init/do_mounts.c | 25 +++++++++++++++++++------
2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 73005f9..b024d5c 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -76,6 +76,6 @@ extern struct vfsmount *vfs_kern_mount(struct file_system_type *type,
extern void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list);
extern void mark_mounts_for_expiry(struct list_head *mounts);
-extern dev_t name_to_dev_t(char *name);
+extern dev_t name_to_dev_t(const char *name);
#endif /* _LINUX_MOUNT_H */
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 816014c..5a031de 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -143,6 +143,13 @@ static dev_t devt_from_partuuid(const char *uuid_str)
clear_root_wait = true;
goto done;
}
+ if (uuid_str[cmp.len - 1] == '\n') {
+ cmp.len--;
+ if (!cmp.len) {
+ clear_root_wait = true;
+ goto done;
+ }
+ }
dev = class_find_device(&block_class, NULL, &cmp,
&match_dev_by_uuid);
@@ -202,12 +209,13 @@ done:
* bangs.
*/
-dev_t name_to_dev_t(char *name)
+dev_t name_to_dev_t(const char *name)
{
char s[32];
char *p;
dev_t res = 0;
int part;
+ int n;
#ifdef CONFIG_BLOCK
if (strncmp(name, "PARTUUID=", 9) == 0) {
@@ -228,7 +236,7 @@ dev_t name_to_dev_t(char *name)
goto fail;
} else {
res = new_decode_dev(simple_strtoul(name, &p, 16));
- if (*p)
+ if (*p && *p != '\n')
goto fail;
}
goto done;
@@ -236,15 +244,20 @@ dev_t name_to_dev_t(char *name)
name += 5;
res = Root_NFS;
- if (strcmp(name, "nfs") == 0)
+ if (strncmp(name, "nfs", 3) == 0)
goto done;
res = Root_RAM0;
- if (strcmp(name, "ram") == 0)
+ if (strncmp(name, "ram", 3) == 0)
goto done;
- if (strlen(name) > 31)
+ n = strlen(name);
+ if (n != 0 && name[n - 1] == '\n')
+ n--;
+ if (n > 31)
goto fail;
- strcpy(s, name);
+ strncpy(s, name, n);
+ s[n] = '\0';
+
for (p = s; *p; p++)
if (*p == '/')
*p = '!';
--
1.7.9.5
Use the name_to_dev_t call to parse the device name echo'd to
to /sys/power/resume. This imitates the method used in hibernate.c
in software_resume, and allows the resume partition to be specified
using other equivalent device formats as well. By allowing
/sys/debug/resume to accept the same syntax as the resume=device
parameter, we can parse the resume=device in the init script and
use the resume device directly from the kernel command line.
Signed-off-by: Sebastian Capella <[email protected]>
Cc: Len Brown <[email protected]>
Cc: Pavel Machek <[email protected]>
Cc: "Rafael J. Wysocki" <[email protected]>
---
kernel/power/hibernate.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index b26f5f1..8b253c2 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -971,16 +971,11 @@ static ssize_t resume_show(struct kobject *kobj, struct kobj_attribute *attr,
static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t n)
{
- unsigned int maj, min;
dev_t res;
- int ret = -EINVAL;
- if (sscanf(buf, "%u:%u", &maj, &min) != 2)
- goto out;
-
- res = MKDEV(maj,min);
- if (maj != MAJOR(res) || min != MINOR(res))
- goto out;
+ res = name_to_dev_t(buf);
+ if (res == 0)
+ return -EINVAL;
lock_system_sleep();
swsusp_resume_device = res;
@@ -988,9 +983,7 @@ static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
printk(KERN_INFO "PM: Starting manual resume from disk\n");
noresume = 0;
software_resume();
- ret = n;
- out:
- return ret;
+ return n;
}
power_attr(resume);
--
1.7.9.5
On Wed 2013-09-18 16:29:01, Sebastian Capella wrote:
> Enhance name_to_dev_t to handle trailing newline characters
> on device paths. Some inputs to name_to_dev_t may come from
> userspace where oftentimes a '\n' is appended to the path.
> Added const to the name buffer in both the function
> declaration and the prototype to reflect input buffer
> handling.
>
> By handling trailing newlines in name_to_dev_t, userspace
> buffers may be directly passed to name_to_dev_t without
> modification.
>
> Signed-off-by: Sebastian Capella <[email protected]>
> Cc: Pavel Machek <[email protected]>
Reviewed-by: Pavel Machek <[email protected]>
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On Wed 2013-09-18 16:29:02, Sebastian Capella wrote:
> Use the name_to_dev_t call to parse the device name echo'd to
> to /sys/power/resume. This imitates the method used in hibernate.c
> in software_resume, and allows the resume partition to be specified
> using other equivalent device formats as well. By allowing
> /sys/debug/resume to accept the same syntax as the resume=device
> parameter, we can parse the resume=device in the init script and
> use the resume device directly from the kernel command line.
>
> Signed-off-by: Sebastian Capella <[email protected]>
> Cc: Len Brown <[email protected]>
Acked-by: Pavel Machek <[email protected]>
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html