blob: 3b807736facfd7480bd5e4b56e7ffc039dd7f202 [file] [log] [blame]
#include <arpa/inet.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "kinit.h"
#include "netdev.h"
#include "nfsmount.h"
static char *sub_client(__u32 client, char *path, size_t len)
{
struct in_addr addr = { client };
char buf[len];
if (strstr(path, "%s") != NULL) {
if (client == INADDR_NONE) {
fprintf(stderr, "Root-NFS: no client address\n");
exit(1);
}
snprintf(buf, len, path, inet_ntoa(addr));
strcpy(path, buf);
}
return path;
}
#define NFS_ARGC 6
#define MOUNT_POINT "/root"
int mount_nfs_root(int argc, char *argv[], int flags)
{
(void)flags; /* FIXME - don't ignore this */
struct in_addr addr = { INADDR_NONE };
__u32 client = INADDR_NONE;
const int len = 1024;
struct netdev *dev;
char *mtpt = MOUNT_POINT;
char *path = NULL;
char *dev_bootpath = NULL;
char root[len];
char *x, *opts;
int ret = 0;
int a = 1;
char *nfs_argv[NFS_ARGC + 1] = { "NFS-Mount" };
for (dev = ifaces; dev; dev = dev->next) {
if (dev->ip_server != INADDR_NONE &&
dev->ip_server != INADDR_ANY) {
addr.s_addr = dev->ip_server;
client = dev->ip_addr;
dev_bootpath = dev->bootpath;
break;
}
if (dev->ip_addr != INADDR_NONE && dev->ip_addr != INADDR_ANY)
client = dev->ip_addr;
}
/*
* if the "nfsroot" option is set then it overrides
* bootpath supplied by the boot server.
*/
if ((path = get_arg(argc, argv, "nfsroot=")) == NULL) {
if ((path = dev_bootpath) == NULL || path[0] == '\0')
/* no path - set a default */
path = (char *)"/tftpboot/%s";
} else if (dev_bootpath && dev_bootpath[0] != '\0')
fprintf(stderr,
"nfsroot=%s overrides boot server bootpath %s\n",
path, dev_bootpath);
if ((opts = strchr(path, ',')) != NULL) {
*opts++ = '\0';
nfs_argv[a++] = (char *)"-o";
nfs_argv[a++] = opts;
}
if ((x = strchr(path, ':')) == NULL) {
if (addr.s_addr == INADDR_NONE) {
fprintf(stderr, "Root-NFS: no server defined\n");
exit(1);
}
snprintf(root, len, "%s:%s", inet_ntoa(addr), path);
} else {
strcpy(root, path);
}
nfs_argv[a++] = sub_client(client, root, len);
dprintf("NFS-Root: mounting %s on %s with options \"%s\"\n",
nfs_argv[a-1], mtpt, opts ? opts : "");
nfs_argv[a++] = mtpt;
nfs_argv[a] = NULL;
assert(a <= NFS_ARGC);
dump_args(a, nfs_argv);
if ((ret = nfsmount_main(a, nfs_argv)) != 0) {
ret = -1;
goto done;
}
done:
return ret;
}