#include #include #include #include #include #include #include #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; }