On Tue, Jan 13, 2015 at 02:44:25PM +0100, Markus Pargmann wrote: > Adding support to nbd to use it as a root device. This code essentially > provides a minimal nbd-client implementation within the kernel. It opens > a socket and makes the negotiation with the server. Afterwards it passes > the socket to the normal nbd-code to handle the connection. > > The arguments for the server are passed via module parameter. The > module parameter has the format > '[:]/'. > SERVER_IP is optional. If it is not available it will use the > root_server_addr transmitted through DHCP. > > Based on those arguments, the connection to the server is established > and is connected to the nbd0 device. The rootdevice therefore is > root=/dev/nbd0. > > Signed-off-by: Markus Pargmann > --- > drivers/block/nbd.c | 306 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 306 insertions(+) > > diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c > index 11f7644be111..ac881ae3c15a 100644 > --- a/drivers/block/nbd.c > +++ b/drivers/block/nbd.c > @@ -32,12 +32,17 @@ > #include > #include > #include > +#include > +#include > +#include > > #include > #include > > #include > > +#define ADDR_NONE cpu_to_be32(INADDR_NONE) > + > #define NBD_MAGIC 0x68797548 > > #ifdef NDEBUG > @@ -71,6 +76,20 @@ static int max_part; > */ > static DEFINE_SPINLOCK(nbd_lock); > > +static const char nbd_magic[] = "NBDMAGIC"; > +static const u64 nbd_opts_magic = 0x49484156454F5054LL; > + > +/* Options used for the kernel driver */ > +#define NBD_OPT_EXPORT_NAME 1 > + > +#define NBD_DEFAULT_BLOCKSIZE 1024 > + > +extern __be32 root_nfs_parse_addr(char *name); > + > +static __be32 nbd_server_addr = ADDR_NONE; > +static __be32 nbd_server_port; > +static char nbd_server_export[128] = ""; > + > #ifndef NDEBUG > static const char *ioctl_cmd_to_ascii(int cmd) > { > @@ -105,6 +124,52 @@ static const char *nbdcmd_to_ascii(int cmd) > } > #endif /* NDEBUG */ > > +/* > + * Parse format "[:]/" > + */ > +static int nbd_server_addr_set(const char *val, const struct kernel_param *kp) > +{ > + char *export; > + u16 port; > + int ret; > + char buf[128]; > + > + strncpy(buf, val, 128); > + > + nbd_server_addr = root_nfs_parse_addr(buf); > + > + if (*buf == '\0') { > + ret = -EINVAL; > + goto free_buf; > + } > + export = strchr(buf, '/'); > + if (!export || *(export + 1) == '\0') { > + ret = -EINVAL; > + goto free_buf; > + } > + *export = '\0'; > + ++export; > + > + ret = kstrtou16(buf, 10, &port); > + if (ret) > + goto free_buf; > + > + memmove(buf, export, strlen(export) + 1); This memmove() is a leftover from a previous version, it is removed for the next series version. I also added some documentation patches that describe this feature in Documentation/blockdev/nbd.txt. I will send it at the end of this week. Best regards, Markus -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |