diff mbox

init: Support mounting devices from kernel command line

Message ID 1310979967-13470-1-git-send-email-levinsasha928@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sasha Levin July 18, 2011, 9:06 a.m. UTC
This patch adds support to mounting devices using a kernel parameter.

Such feature is usefull for virtual guests. It allows easily automating
mounts without having to change the base image (which can be read-only).

In /tools/kvm we are interested in such feature to allow us to automatically
mount user home directory using virtio-9p from the host to the guest
filesystem under '/hostfs'.

Cc: Avi Kivity <avi@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 Documentation/kernel-parameters.txt |    6 +++
 init/do_mounts.c                    |   61 +++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 0 deletions(-)

Comments

Pekka Enberg July 18, 2011, 11:55 a.m. UTC | #1
On Mon, Jul 18, 2011 at 12:06 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
> This patch adds support to mounting devices using a kernel parameter.
>
> Such feature is usefull for virtual guests. It allows easily automating
> mounts without having to change the base image (which can be read-only).
>
> In /tools/kvm we are interested in such feature to allow us to automatically
> mount user home directory using virtio-9p from the host to the guest
> filesystem under '/hostfs'.
>
> Cc: Avi Kivity <avi@redhat.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Pekka Enberg <penberg@kernel.org>
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>

Lets CC fsdevel.

> ---
>  Documentation/kernel-parameters.txt |    6 +++
>  init/do_mounts.c                    |   61 +++++++++++++++++++++++++++++++++++
>  2 files changed, 67 insertions(+), 0 deletions(-)
>
> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
> index aa47be7..e1955fb 100644
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -1476,6 +1476,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
>                        log everything. Information is printed at KERN_DEBUG
>                        so loglevel=8 may also need to be specified.
>
> +       mount=
> +                       [KNL] Mount a device to a mount point after loading
> +                       rootfs and setting up devices. Can be used to mount
> +                       up to 16 devices.
> +                       Format: <source>,<destination>,<fs>[,<params>]
> +
>        mousedev.tap_time=
>                        [MOUSE] Maximum time between finger touching and
>                        leaving touchpad surface for touch to be considered
> diff --git a/init/do_mounts.c b/init/do_mounts.c
> index c0851a8..0948f1d 100644
> --- a/init/do_mounts.c
> +++ b/init/do_mounts.c
> @@ -29,9 +29,24 @@ int root_mountflags = MS_RDONLY | MS_SILENT;
>  static char * __initdata root_device_name;
>  static char __initdata saved_root_name[64];
>  static int __initdata root_wait;
> +static char * __initdata user_mount[16];
> +static int __initdata user_mount_count;
>
>  dev_t ROOT_DEV;
>
> +static int __init setup_user_mount(char *str)
> +{
> +       if (user_mount_count > 15) {
> +               printk(KERN_ERR "More than 16 'mount=' options specified.")
> +               return 1;
> +       }
> +
> +       user_mount[user_mount_count++] = str;
> +
> +       return 1;
> +}
> +__setup("mount=", setup_user_mount);
> +
>  static int __init load_ramdisk(char *str)
>  {
>        rd_doload = simple_strtol(str,NULL,0) & 3;
> @@ -431,6 +446,51 @@ void __init mount_root(void)
>  #endif
>  }
>
> +int __init do_user_mounts(void)
> +{
> +       int i, res;
> +       char *src, *dst, *fs, *params, *cur;
> +
> +       for (i = 0; i < user_mount_count; i++) {
> +               src = user_mount[i];
> +               cur = strstr(user_mount[i], ",");
> +               if (!cur)
> +                       goto fail_str;
> +
> +               *cur = '\0';
> +               dst = ++cur;
> +
> +               cur = strstr(cur, ",");
> +               if (!cur)
> +                       goto fail_str;
> +
> +               *cur = '\0';
> +               fs = ++cur;
> +
> +               cur = strstr(cur, ",");
> +               if (cur) {
> +                       *cur = '\0';
> +                       params = ++cur;
> +               } else {
> +                       params = NULL;
> +               }
> +
> +               res = sys_mount(src, dst, fs, 0, params);
> +               if (res == 0)
> +                       printk(KERN_INFO "Mounted (%s filesystem) %s to %s\n",
> +                               fs, src, dst);
> +               else
> +                       printk(KERN_ERR "Failed mounting (%s filesystem) %s to"
> +                               " %s. Err: %d\n", fs, src, dst, res);
> +       }
> +
> +       return 0;
> +
> +fail_str:
> +       printk(KERN_ERR "Bad mount str: %s\n", user_mount[i]);
> +       return -1;
> +}
> +
>  /*
>  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
>  */
> @@ -490,4 +550,5 @@ out:
>        devtmpfs_mount("dev");
>        sys_mount(".", "/", NULL, MS_MOVE, NULL);
>        sys_chroot((const char __user __force *)".");
> +       do_user_mounts();
>  }
> --
> 1.7.6
>
> --
> 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/
>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michael Tokarev July 18, 2011, 12:15 p.m. UTC | #2
18.07.2011 15:55, Pekka Enberg wrote:
> On Mon, Jul 18, 2011 at 12:06 PM, Sasha Levin <levinsasha928@gmail.com> wrote:
>> This patch adds support to mounting devices using a kernel parameter.
>>
>> Such feature is usefull for virtual guests. It allows easily automating
>> mounts without having to change the base image (which can be read-only).
>>
>> In /tools/kvm we are interested in such feature to allow us to automatically
>> mount user home directory using virtio-9p from the host to the guest
>> filesystem under '/hostfs'.

Can't the same be done within initramfs just as easy?

Long time ago when initramfs first appeared the plan was to,
more or less, move all that mounting and root= handling
functionality to userspae, and here we're adding more
to kernel.  To me that sounds backwards...

Thanks,

/mjt
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pekka Enberg July 18, 2011, 12:27 p.m. UTC | #3
On Mon, Jul 18, 2011 at 3:15 PM, Michael Tokarev <mjt@tls.msk.ru> wrote:
>>> In /tools/kvm we are interested in such feature to allow us to automatically
>>> mount user home directory using virtio-9p from the host to the guest
>>> filesystem under '/hostfs'.
>
> Can't the same be done within initramfs just as easy?
>
> Long time ago when initramfs first appeared the plan was to,
> more or less, move all that mounting and root= handling
> functionality to userspae, and here we're adding more
> to kernel.  To me that sounds backwards...

Well, we can currently boot distro images using custom kernel combined
with distro initramfs. I'm not sure how we can inject our mount point
to initramfs as easily.

I don't think it's backwards progress but then again, I don't really
use initramfs or modules for that matter so maybe I'm just old
fashioned.

                        Pekka
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
James Bottomley July 18, 2011, 7:44 p.m. UTC | #4
On Mon, 2011-07-18 at 15:27 +0300, Pekka Enberg wrote:
> On Mon, Jul 18, 2011 at 3:15 PM, Michael Tokarev <mjt@tls.msk.ru> wrote:
> >>> In /tools/kvm we are interested in such feature to allow us to automatically
> >>> mount user home directory using virtio-9p from the host to the guest
> >>> filesystem under '/hostfs'.
> >
> > Can't the same be done within initramfs just as easy?
> >
> > Long time ago when initramfs first appeared the plan was to,
> > more or less, move all that mounting and root= handling
> > functionality to userspae, and here we're adding more
> > to kernel.  To me that sounds backwards...
> 
> Well, we can currently boot distro images using custom kernel combined
> with distro initramfs. I'm not sure how we can inject our mount point
> to initramfs as easily.

Actually, I think it can.  An initramfs is designed as an effective root
booting system that runs from /sbin/init, does it's stuff like driver
loading and device finding, mounts the real root and pivots to it before
executing /sbin/init.

It strikes me, therefore, that it's fairly easy to insert another initrd
at the beginning of that process, so you alter the kernel to boot with
virt_initrd as the initramfs.  It would prepare all your mount points
(or muck with the parameters so they'd get mounted by the next initrd)
and load any virt drivers, then take the next initrd into a tempfs,
pivot to it and exec /sbin/init.

That would seem to work without needing any kernel patches at all.

James

> I don't think it's backwards progress but then again, I don't really
> use initramfs or modules for that matter so maybe I'm just old
> fashioned.


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index aa47be7..e1955fb 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1476,6 +1476,12 @@  bytes respectively. Such letter suffixes can also be entirely omitted.
 			log everything. Information is printed at KERN_DEBUG
 			so loglevel=8 may also need to be specified.
 
+	mount=
+			[KNL] Mount a device to a mount point after loading
+			rootfs and setting up devices. Can be used to mount
+			up to 16 devices.
+			Format: <source>,<destination>,<fs>[,<params>]
+
 	mousedev.tap_time=
 			[MOUSE] Maximum time between finger touching and
 			leaving touchpad surface for touch to be considered
diff --git a/init/do_mounts.c b/init/do_mounts.c
index c0851a8..0948f1d 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -29,9 +29,24 @@  int root_mountflags = MS_RDONLY | MS_SILENT;
 static char * __initdata root_device_name;
 static char __initdata saved_root_name[64];
 static int __initdata root_wait;
+static char * __initdata user_mount[16];
+static int __initdata user_mount_count;
 
 dev_t ROOT_DEV;
 
+static int __init setup_user_mount(char *str)
+{
+	if (user_mount_count > 15) {
+		printk(KERN_ERR "More than 16 'mount=' options specified.")
+		return 1;
+	}
+	
+	user_mount[user_mount_count++] = str;
+
+	return 1;
+}
+__setup("mount=", setup_user_mount);
+
 static int __init load_ramdisk(char *str)
 {
 	rd_doload = simple_strtol(str,NULL,0) & 3;
@@ -431,6 +446,51 @@  void __init mount_root(void)
 #endif
 }
 
+int __init do_user_mounts(void)
+{
+	int i, res;
+	char *src, *dst, *fs, *params, *cur;
+
+	for (i = 0; i < user_mount_count; i++) {
+		src = user_mount[i];
+		cur = strstr(user_mount[i], ",");
+		if (!cur)
+			goto fail_str;
+
+		*cur = '\0';
+		dst = ++cur;
+
+		cur = strstr(cur, ",");
+		if (!cur)
+			goto fail_str;
+
+		*cur = '\0';
+		fs = ++cur;
+
+		cur = strstr(cur, ",");
+		if (cur) {
+			*cur = '\0';
+			params = ++cur;
+		} else {
+			params = NULL;
+		}
+
+		res = sys_mount(src, dst, fs, 0, params);
+		if (res == 0)
+			printk(KERN_INFO "Mounted (%s filesystem) %s to %s\n",
+				fs, src, dst);
+		else
+			printk(KERN_ERR "Failed mounting (%s filesystem) %s to"
+				" %s. Err: %d\n", fs, src, dst, res);
+	}
+
+	return 0;
+
+fail_str:
+	printk(KERN_ERR "Bad mount str: %s\n", user_mount[i]);
+	return -1;
+}
+
 /*
  * Prepare the namespace - decide what/where to mount, load ramdisks, etc.
  */
@@ -490,4 +550,5 @@  out:
 	devtmpfs_mount("dev");
 	sys_mount(".", "/", NULL, MS_MOVE, NULL);
 	sys_chroot((const char __user __force *)".");
+	do_user_mounts();
 }