int parse(struct file_system_info *fsinfo, int argc, char **argv){ int i = 0; if ((argc == 2) && ((strcmp(argv[1], OPT_VERSION) == 0) || (strcmp(argv[1], OPT_VERSION_FULL) == 0))){ printf(PROGRAM_NAME " - filesystem in userspace for rdiff-backup repositories; version %s\n", PACKAGE_VERSION); exit(0); }; if (argc < 3) fail(ERR_PARAMETRES); for (i = 1; i < argc; i++){ if (isOption(argv[i]) == 1) parse_option(fsinfo, argc, argv, &i); else if (mount == NULL) parse_mount(argv[i]); else parse_repo(fsinfo, argc, argv, &i); }; if (mount == NULL) fail(ERR_NO_MOUNT); if (fsinfo->repo_count == 0) fail(ERR_NO_REPO); if ((layout == LAYOUT_LAST) && (structure != STRUCTURE_FULL)) fail(ERR_FULL_ONLY); return 0; };
static int parse_dir_ask(char **conf) { char name[80]; char *mnt; int error; printf("\nLoader variables:\n"); parse_dir_ask_printenv("vfs.root.mountfrom"); parse_dir_ask_printenv("vfs.root.mountfrom.options"); printf("\nManual root filesystem specification:\n"); printf(" <fstype>:<device> [options]\n"); printf(" Mount <device> using filesystem <fstype>\n"); printf(" and with the specified (optional) option list.\n"); printf("\n"); printf(" eg. ufs:/dev/da0s1a\n"); printf(" zfs:tank\n"); printf(" cd9660:/dev/acd0 ro\n"); printf(" (which is equivalent to: "); printf("mount -t cd9660 -o ro /dev/acd0 /)\n"); printf("\n"); printf(" ? List valid disk boot devices\n"); printf(" . Yield 1 second (for background tasks)\n"); printf(" <empty line> Abort manual input\n"); do { error = EINVAL; printf("\nmountroot> "); cngets(name, sizeof(name), GETS_ECHO); if (name[0] == '\0') break; if (name[0] == '?' && name[1] == '\0') { printf("\nList of GEOM managed disk devices:\n "); g_dev_print(); continue; } if (name[0] == '.' && name[1] == '\0') { pause("rmask", hz); continue; } mnt = name; error = parse_mount(&mnt); if (error == -1) printf("Invalid file system specification.\n"); } while (error != 0); return (error); }
static int vfs_mountroot_parse(struct sbuf *sb, struct mount *mpdevfs) { struct mount *mp; char *conf; int error; root_mount_mddev = -1; retry: conf = sbuf_data(sb); mp = TAILQ_NEXT(mpdevfs, mnt_list); error = (mp == NULL) ? 0 : EDOOFUS; root_mount_onfail = A_CONTINUE; while (mp == NULL) { error = parse_skipto(&conf, CC_NONWHITESPACE); if (error == PE_EOL) { parse_advance(&conf); continue; } if (error < 0) break; switch (parse_peek(&conf)) { case '#': error = parse_skipto(&conf, '\n'); break; case '.': error = parse_directive(&conf); break; default: error = parse_mount(&conf); break; } if (error < 0) break; /* Ignore any trailing garbage on the line. */ if (parse_peek(&conf) != '\n') { printf("mountroot: advancing to next directive...\n"); (void)parse_skipto(&conf, '\n'); } mp = TAILQ_NEXT(mpdevfs, mnt_list); } if (mp != NULL) return (0); /* * We failed to mount (a new) root. */ switch (root_mount_onfail) { case A_CONTINUE: break; case A_PANIC: panic("mountroot: unable to (re-)mount root."); /* NOTREACHED */ case A_RETRY: goto retry; case A_REBOOT: kern_reboot(RB_NOSYNC); /* NOTREACHED */ } return (error); }
int nfs_mount(fs_cookie *fs, fs_id id, const char *device, void *args, vnode_id *root_vnid) { nfs_fs *nfs; int err; char ip_addr_str[128]; ipv4_addr ip_addr; TRACE("nfs_mount: fsid 0x%x, device '%s'\n", id, device); /* create the fs structure */ nfs = kmalloc(sizeof(nfs_fs)); if(!nfs) { err = ERR_NO_MEMORY; goto err; } memset(nfs, 0, sizeof(nfs_fs)); mutex_init(&nfs->lock, "nfs lock"); err = parse_mount(device, ip_addr_str, sizeof(ip_addr_str), nfs->server_path, sizeof(nfs->server_path)); if(err < 0) { err = ERR_NET_BAD_ADDRESS; goto err1; } err = parse_ipv4_addr_str(&ip_addr, ip_addr_str); if(err < 0) { err = ERR_NET_BAD_ADDRESS; goto err1; } nfs->id = id; nfs->server_addr.type = ADDR_TYPE_IP; nfs->server_addr.len = 4; NETADDR_TO_IPV4(nfs->server_addr) = ip_addr; // set up the rpc state rpc_init_state(&nfs->rpc); rpc_open_socket(&nfs->rpc, &nfs->server_addr); // look up the port numbers for mount and nfs rpc_pmap_lookup(&nfs->server_addr, MOUNTPROG, MOUNTVERS, IP_PROT_UDP, &nfs->mount_port); rpc_pmap_lookup(&nfs->server_addr, NFSPROG, NFSVERS, IP_PROT_UDP, &nfs->nfs_port); nfs->root_vnode = new_vnode_struct(nfs); nfs->root_vnode->st = STREAM_TYPE_DIR; // try to mount the filesystem err = nfs_mount_fs(nfs, nfs->server_path); if(err < 0) goto err2; // build the vnode hash table and stick the root vnode in it nfs->handle_hash = hash_init(1024, offsetof(struct nfs_vnode, hash_next), nfs_handle_hash_compare, nfs_handle_hash); if (!nfs->handle_hash) { err = ERR_NO_MEMORY; goto err2; } hash_insert(nfs->handle_hash, nfs->root_vnode); *fs = nfs; *root_vnid = VNODETOVNID(nfs->root_vnode); return 0; err2: destroy_vnode_struct(nfs->root_vnode); rpc_destroy_state(&nfs->rpc); err1: mutex_destroy(&nfs->lock); kfree(nfs); err: return err; }
int parse_mounts(const glightui *gui,const char *fn){ char *mnt,*dev,*ops,*fs; off_t len,idx; char *map; int fd; if((map = map_virt_file(fn,&fd,&len)) == MAP_FAILED){ return -1; } idx = 0; dev = mnt = fs = ops = NULL; while(idx < len){ char buf[PATH_MAX + 1]; struct statvfs vfs; struct stat st; device *d; char *rp; int r; free(dev); free(mnt); free(fs); free(ops); if((r = parse_mount(map + idx,len - idx,&dev,&mnt,&fs,&ops)) < 0){ goto err; } idx += r; if(statvfs(mnt,&vfs)){ int skip = 0; // We might have mounted a new target atop or above an // already existing one, in which case we'll need // possibly recreate the directory structure on the // newly-mounted filesystem. if(growlight_target){ if(strncmp(mnt,growlight_target,strlen(growlight_target)) == 0){ if(make_parent_directories(mnt) == 0){ skip = 1; } // FIXME else remount? otherwise writes // go to new filesystem rather than old...? } } if(!skip){ diag("Couldn't stat fs %s (%s?)\n",mnt,strerror(errno)); r = -1; continue; } } if(*dev != '/'){ // have to get zfs's etc if(fstype_virt_p(fs)){ continue; } if((d = lookup_device(dev)) == NULL){ verbf("virtfs %s at %s\n",fs,mnt); continue; } }else{ rp = dev; if(lstat(rp,&st) == 0){ if(S_ISLNK(st.st_mode)){ if((r = readlink(dev,buf,sizeof(buf))) < 0){ diag("Couldn't deref %s (%s?)\n",dev,strerror(errno)); continue; } if((size_t)r >= sizeof(buf)){ diag("Name too long for %s (%d?)\n",dev,r); continue; } buf[r] = '\0'; rp = buf; } } if((d = lookup_device(rp)) == NULL){ continue; } } free(dev); dev = NULL; if(d->mnttype && strcmp(d->mnttype,fs)){ diag("Already had mounttype for %s: %s (got %s)\n", d->name,d->mnttype,fs); free(d->mnttype); d->mnttype = NULL; free_stringlist(&d->mntops); free_stringlist(&d->mnt); d->mnttype = fs; }else{ free(fs); } fs = NULL; if(add_string(&d->mnt,mnt)){ goto err; } if(add_string(&d->mntops,ops)){ goto err; } d->mntsize = (uintmax_t)vfs.f_bsize * vfs.f_blocks; if(d->layout == LAYOUT_PARTITION){ d = d->partdev.parent; } d->uistate = gui->block_event(d,d->uistate); if(growlight_target){ if(strcmp(mnt,growlight_target) == 0){ mount_target(); } } } free(mnt); free(fs); free(ops); mnt = fs = ops = NULL; munmap_virt(map,len); close(fd); return 0; err: free(dev); free(mnt); free(fs); free(ops); munmap_virt(map,len); close(fd); return -1; }