summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-03-07 09:25:44 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2014-03-07 09:25:44 +0100
commit144358e0aa102c84968443460c508eb3d65ccc90 (patch)
tree01b9aafde793d1124976ecd2bae090b9b978f8a3 /common
parente358922a74b01e6272c77caf01bc78a8295cc7d7 (diff)
parent86f681abec4f8485d2e95537e0d59a8d9ab6b546 (diff)
downloadbarebox-144358e0aa102c84968443460c508eb3d65ccc90.tar.gz
barebox-144358e0aa102c84968443460c508eb3d65ccc90.tar.xz
Merge branch 'for-next/nfs'
Conflicts: defaultenv/defaultenv-2-base/bin/ifup
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig1
-rw-r--r--common/blspec.c116
-rw-r--r--common/hush.c2
-rw-r--r--common/menu.c2
-rw-r--r--common/parser.c7
-rw-r--r--common/startup.c8
6 files changed, 123 insertions, 13 deletions
diff --git a/common/Kconfig b/common/Kconfig
index 522483861e..5989502a75 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -596,6 +596,7 @@ config DEFAULT_ENVIRONMENT_GENERIC_NEW
select CMD_DIRNAME
select FLEXIBLE_BOOTARGS
select CMD_BOOT
+ select NET_CMD_IFUP if NET
prompt "Generic environment template"
config DEFAULT_ENVIRONMENT_GENERIC_NEW_MENU
diff --git a/common/blspec.c b/common/blspec.c
index 2244d5a8a8..9b4b096a0a 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*
*/
+#define pr_fmt(fmt) "blspec: " fmt
+
#include <environment.h>
#include <globalvar.h>
#include <readkey.h>
@@ -22,6 +24,7 @@
#include <libbb.h>
#include <init.h>
#include <boot.h>
+#include <net.h>
#include <fs.h>
#include <of.h>
#include <linux/stat.h>
@@ -131,6 +134,107 @@ static int blspec_have_entry(struct blspec *blspec, const char *path)
}
/*
+ * nfs_find_mountpath - Check if a given url is already mounted
+ */
+static const char *nfs_find_mountpath(const char *nfshostpath)
+{
+ struct fs_device_d *fsdev;
+
+ for_each_fs_device(fsdev) {
+ if (fsdev->backingstore && !strcmp(fsdev->backingstore, nfshostpath))
+ return fsdev->path;
+ }
+
+ return NULL;
+}
+
+/*
+ * parse_nfs_url - check for nfs:// style url
+ *
+ * Check if the passed string is a NFS url and if yes, mount the
+ * NFS and return the path we have mounted to.
+ */
+static char *parse_nfs_url(const char *url)
+{
+ char *sep, *str, *host, *port, *path;
+ char *mountpath = NULL, *hostpath = NULL, *options = NULL;
+ const char *prevpath;
+ IPaddr_t ip;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_FS_NFS))
+ return ERR_PTR(-ENOSYS);
+
+ if (strncmp(url, "nfs://", 6))
+ return ERR_PTR(-EINVAL);
+
+ url += 6;
+
+ str = xstrdup(url);
+
+ host = str;
+
+ sep = strchr(str, '/');
+ if (!sep) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ *sep++ = 0;
+
+ path = sep;
+
+ port = strchr(host, ':');
+ if (port)
+ *port++ = 0;
+
+ ret = ifup_all(0);
+ if (ret) {
+ pr_err("Failed to bring up networking\n");
+ goto out;
+ }
+
+ ip = resolv(host);
+ if (ip == 0)
+ goto out;
+
+ hostpath = asprintf("%s:%s", ip_to_string(ip), path);
+
+ prevpath = nfs_find_mountpath(hostpath);
+
+ if (prevpath) {
+ mountpath = xstrdup(prevpath);
+ } else {
+ mountpath = asprintf("/mnt/nfs-%s-blspec-%08x", host, rand());
+ if (port)
+ options = asprintf("mountport=%s,port=%s", port, port);
+
+ ret = make_directory(mountpath);
+ if (ret)
+ goto out;
+
+ pr_debug("host: %s port: %s path: %s\n", host, port, path);
+ pr_debug("hostpath: %s mountpath: %s options: %s\n", hostpath, mountpath, options);
+
+ ret = mount(hostpath, "nfs", mountpath, options);
+ if (ret)
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ free(str);
+ free(hostpath);
+ free(options);
+
+ if (ret)
+ free(mountpath);
+
+ return ret ? ERR_PTR(ret) : mountpath;
+}
+
+/*
* blspec_scan_directory - scan over a directory
*
* Given a root path collects all blspec entries found under /blspec/entries/.
@@ -145,9 +249,13 @@ int blspec_scan_directory(struct blspec *blspec, const char *root)
char *abspath;
int ret, found = 0;
const char *dirname = "loader/entries";
- char *entry_default = NULL, *entry_once = NULL, *name;
+ char *entry_default = NULL, *entry_once = NULL, *name, *nfspath = NULL;
+
+ nfspath = parse_nfs_url(root);
+ if (!IS_ERR(nfspath))
+ root = nfspath;
- pr_debug("%s: %s %s\n", __func__, root, dirname);
+ pr_info("%s: %s %s\n", __func__, root, dirname);
entry_default = read_file_line("%s/default", root);
entry_once = read_file_line("%s/once", root);
@@ -239,6 +347,8 @@ int blspec_scan_directory(struct blspec *blspec, const char *root)
closedir(dir);
err_out:
+ if (!IS_ERR(nfspath))
+ free(nfspath);
free(abspath);
free(entry_default);
free(entry_once);
@@ -276,7 +386,7 @@ static int blspec_scan_cdev(struct blspec *blspec, struct cdev *cdev)
if (type == filetype_mbr || type == filetype_gpt)
return -EINVAL;
- rootpath = cdev_mount_default(cdev);
+ rootpath = cdev_mount_default(cdev, NULL);
if (IS_ERR(rootpath))
return PTR_ERR(rootpath);
diff --git a/common/hush.c b/common/hush.c
index abe2ceda07..bd534c12f5 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -1824,7 +1824,7 @@ static char * make_string(char ** inp)
return str;
}
-int run_command (const char *cmd, int flag)
+int run_command(const char *cmd)
{
struct p_context ctx;
int ret;
diff --git a/common/menu.c b/common/menu.c
index 4cefadb412..54f2c71b29 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -468,7 +468,7 @@ static void menu_action_command(struct menu *m, struct menu_entry *me)
if (!s)
s = e->command;
- ret = run_command (s, 0);
+ ret = run_command(s);
if (ret < 0)
udelay(1000000);
diff --git a/common/parser.c b/common/parser.c
index d390fb6afe..4a48210c4d 100644
--- a/common/parser.c
+++ b/common/parser.c
@@ -176,7 +176,7 @@ static void process_macros (const char *input, char *output)
* creates or modifies environment variables (like "bootp" does).
*/
-int run_command (const char *cmd, int flag)
+int run_command(const char *cmd)
{
char cmdbuf[CONFIG_CBSIZE]; /* working copy of cmd */
char *token; /* start of token in cmdbuf */
@@ -265,18 +265,17 @@ int run_shell(void)
static char lastcommand[CONFIG_CBSIZE] = { 0, };
int len;
int rc = 1;
- int flag;
+
for (;;) {
len = readline (CONFIG_PROMPT, console_buffer, CONFIG_CBSIZE);
- flag = 0; /* assume no special flags for now */
if (len > 0)
strcpy (lastcommand, console_buffer);
if (len == -1)
puts ("<INTERRUPT>\n");
else
- rc = run_command (lastcommand, flag);
+ rc = run_command(lastcommand);
if (rc <= 0) {
/* invalid command or not repeatable, forget it */
diff --git a/common/startup.c b/common/startup.c
index 9c4e995a5e..ceb597b0eb 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -47,9 +47,9 @@ extern initcall_t __barebox_initcalls_start[], __barebox_early_initcalls_end[],
#if defined CONFIG_FS_RAMFS && defined CONFIG_FS_DEVFS
static int mount_root(void)
{
- mount("none", "ramfs", "/");
+ mount("none", "ramfs", "/", NULL);
mkdir("/dev", 0);
- mount("none", "devfs", "/dev");
+ mount("none", "devfs", "/dev", NULL);
return 0;
}
fs_initcall(mount_root);
@@ -95,11 +95,11 @@ void __noreturn start_barebox(void)
pr_info("running /env/bin/init...\n");
if (!stat("/env/bin/init", &s)) {
- run_command("source /env/bin/init", 0);
+ run_command("source /env/bin/init");
} else {
pr_err("/env/bin/init not found\n");
if (IS_ENABLED(CONFIG_CMD_LOGIN))
- while(run_command("login -t 0", 0));
+ while(run_command("login -t 0"));
}
}