forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cifs: Add support for root file systems
Introduce a new CONFIG_CIFS_ROOT option to handle root file systems over a SMB share. In order to mount the root file system during the init process, make cifs.ko perform non-blocking socket operations while mounting and accessing it. Cc: Steve French <[email protected]> Reviewed-by: Aurelien Aptel <[email protected]> Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
- Loading branch information
Paulo Alcantara (SUSE)
authored and
Steve French
committed
Sep 16, 2019
1 parent
0892ba6
commit 8eecd1c
Showing
7 changed files
with
207 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
Mounting root file system via SMB (cifs.ko) | ||
=========================================== | ||
|
||
Written 2019 by Paulo Alcantara <[email protected]> | ||
Written 2019 by Aurelien Aptel <[email protected]> | ||
|
||
The CONFIG_CIFS_ROOT option enables experimental root file system | ||
support over the SMB protocol via cifs.ko. | ||
|
||
It introduces a new kernel command-line option called 'cifsroot=' | ||
which will tell the kernel to mount the root file system over the | ||
network by utilizing SMB or CIFS protocol. | ||
|
||
In order to mount, the network stack will also need to be set up by | ||
using 'ip=' config option. For more details, see | ||
Documentation/filesystems/nfs/nfsroot.txt. | ||
|
||
A CIFS root mount currently requires the use of SMB1+UNIX Extensions | ||
which is only supported by the Samba server. SMB1 is the older | ||
deprecated version of the protocol but it has been extended to support | ||
POSIX features (See [1]). The equivalent extensions for the newer | ||
recommended version of the protocol (SMB3) have not been fully | ||
implemented yet which means SMB3 doesn't support some required POSIX | ||
file system objects (e.g. block devices, pipes, sockets). | ||
|
||
As a result, a CIFS root will default to SMB1 for now but the version | ||
to use can nonetheless be changed via the 'vers=' mount option. This | ||
default will change once the SMB3 POSIX extensions are fully | ||
implemented. | ||
|
||
Server configuration | ||
==================== | ||
|
||
To enable SMB1+UNIX extensions you will need to set these global | ||
settings in Samba smb.conf: | ||
|
||
[global] | ||
server min protocol = NT1 | ||
unix extension = yes # default | ||
|
||
Kernel command line | ||
=================== | ||
|
||
root=/dev/cifs | ||
|
||
This is just a virtual device that basically tells the kernel to mount | ||
the root file system via SMB protocol. | ||
|
||
cifsroot=//<server-ip>/<share>[,options] | ||
|
||
Enables the kernel to mount the root file system via SMB that are | ||
located in the <server-ip> and <share> specified in this option. | ||
|
||
The default mount options are set in fs/cifs/cifsroot.c. | ||
|
||
server-ip | ||
IPv4 address of the server. | ||
|
||
share | ||
Path to SMB share (rootfs). | ||
|
||
options | ||
Optional mount options. For more information, see mount.cifs(8). | ||
|
||
Examples | ||
======== | ||
|
||
Export root file system as a Samba share in smb.conf file. | ||
|
||
... | ||
[linux] | ||
path = /path/to/rootfs | ||
read only = no | ||
guest ok = yes | ||
force user = root | ||
force group = root | ||
browseable = yes | ||
writeable = yes | ||
admin users = root | ||
public = yes | ||
create mask = 0777 | ||
directory mask = 0777 | ||
... | ||
|
||
Restart smb service. | ||
|
||
# systemctl restart smb | ||
|
||
Test it under QEMU on a kernel built with CONFIG_CIFS_ROOT and | ||
CONFIG_IP_PNP options enabled. | ||
|
||
# qemu-system-x86_64 -enable-kvm -cpu host -m 1024 \ | ||
-kernel /path/to/linux/arch/x86/boot/bzImage -nographic \ | ||
-append "root=/dev/cifs rw ip=dhcp cifsroot=//10.0.2.2/linux,username=foo,password=bar console=ttyS0 3" | ||
|
||
|
||
1: https://wiki.samba.org/index.php/UNIX_Extensions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* SMB root file system support | ||
* | ||
* Copyright (c) 2019 Paulo Alcantara <[email protected]> | ||
*/ | ||
#include <linux/init.h> | ||
#include <linux/fs.h> | ||
#include <linux/types.h> | ||
#include <linux/ctype.h> | ||
#include <linux/string.h> | ||
#include <linux/root_dev.h> | ||
#include <linux/kernel.h> | ||
#include <linux/in.h> | ||
#include <linux/inet.h> | ||
#include <net/ipconfig.h> | ||
|
||
#define DEFAULT_MNT_OPTS \ | ||
"vers=1.0,cifsacl,mfsymlinks,rsize=1048576,wsize=65536,uid=0,gid=0," \ | ||
"hard,rootfs" | ||
|
||
static char root_dev[2048] __initdata = ""; | ||
static char root_opts[1024] __initdata = DEFAULT_MNT_OPTS; | ||
|
||
static __be32 __init parse_srvaddr(char *start, char *end) | ||
{ | ||
char addr[sizeof("aaa.bbb.ccc.ddd")]; | ||
int i = 0; | ||
|
||
while (start < end && i < sizeof(addr) - 1) { | ||
if (isdigit(*start) || *start == '.') | ||
addr[i++] = *start; | ||
start++; | ||
} | ||
addr[i] = '\0'; | ||
return in_aton(addr); | ||
} | ||
|
||
/* cifsroot=//<server-ip>/<share>[,options] */ | ||
static int __init cifs_root_setup(char *line) | ||
{ | ||
char *s; | ||
int len; | ||
__be32 srvaddr = htonl(INADDR_NONE); | ||
|
||
ROOT_DEV = Root_CIFS; | ||
|
||
if (strlen(line) > 3 && line[0] == '/' && line[1] == '/') { | ||
s = strchr(&line[2], '/'); | ||
if (!s || s[1] == '\0') | ||
return 1; | ||
|
||
s = strchrnul(s, ','); | ||
len = s - line + 1; | ||
if (len <= sizeof(root_dev)) { | ||
strlcpy(root_dev, line, len); | ||
srvaddr = parse_srvaddr(&line[2], s); | ||
if (*s) { | ||
snprintf(root_opts, sizeof(root_opts), "%s,%s", | ||
DEFAULT_MNT_OPTS, s + 1); | ||
} | ||
} | ||
} | ||
|
||
root_server_addr = srvaddr; | ||
|
||
return 1; | ||
} | ||
|
||
__setup("cifsroot=", cifs_root_setup); | ||
|
||
int __init cifs_root_data(char **dev, char **opts) | ||
{ | ||
if (!root_dev[0] || root_server_addr == htonl(INADDR_NONE)) { | ||
printk(KERN_ERR "Root-CIFS: no SMB server address\n"); | ||
return -1; | ||
} | ||
|
||
*dev = root_dev; | ||
*opts = root_opts; | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters