static dev_t try_name(char *name, int part) { char path[64]; char buf[32]; int range; dev_t res; char *s; int len; int fd; unsigned int maj, min; /* read device number from .../dev */ sprintf(path, "/sys/block/%s/dev", name); fd = sys_open(path, 0, 0); if (fd < 0) goto fail; len = sys_read(fd, buf, 32); sys_close(fd); if (len <= 0 || len == 32 || buf[len - 1] != '\n') goto fail; buf[len - 1] = '\0'; if (sscanf(buf, "%u:%u", &maj, &min) == 2) { /* * Try the %u:%u format -- see print_dev_t() */ res = MKDEV(maj, min); if (maj != MAJOR(res) || min != MINOR(res)) goto fail; } else { /* * Nope. Try old-style "0321" */ res = new_decode_dev(simple_strtoul(buf, &s, 16)); if (*s) goto fail; } /* if it's there and we are not looking for a partition - that's it */ if (!part) return res; /* otherwise read range from .../range */ sprintf(path, "/sys/block/%s/range", name); fd = sys_open(path, 0, 0); if (fd < 0) goto fail; len = sys_read(fd, buf, 32); sys_close(fd); if (len <= 0 || len == 32 || buf[len - 1] != '\n') goto fail; buf[len - 1] = '\0'; range = simple_strtoul(buf, &s, 10); if (*s) goto fail; /* if partition is within range - we got it */ if (part < range) return res + part; fail: return 0; }
/* Close file descriptor allocated above (user can also use close(2)). */ static int autofs_dev_ioctl_closemount(struct file *fp, struct autofs_sb_info *sbi, struct autofs_dev_ioctl *param) { return sys_close(param->ioctlfd); }
static int load_svr3_binary (struct linux_binprm *bprm, struct pt_regs *regs) { struct file *file; int error, retval, i, j, shlibs; int fd[1+SHLIB_MAX]; long entry; unsigned long rlim; unsigned long p = bprm->p; struct filehdr *fh; struct aouthdr *ah; struct scnhdr *sh; char *buf, *libs_buf; /* Main binary + SHLIB_MAX */ struct bin_info bin_info[SHLIB_MAX + 1]; /* Cheking accessable headers by bprm->buf (128 bytes). */ fh = (struct filehdr *) bprm->buf; if (fh->f_magic != MC68MAGIC || fh->f_opthdr < AOUTSZ || fh->f_nscns < 3 || !(fh->f_flags & F_AR32W) || !(fh->f_flags & F_EXEC) ) return -ENOEXEC; ah = (struct aouthdr *) ((char *) bprm->buf + FILHSZ); if (ah->magic == SHMAGIC) return -ELIBEXEC; if ((ah->magic != DMAGIC && ah->magic != ZMAGIC) || !ah->tsize || ah->tsize + ah->dsize + FILHSZ + fh->f_opthdr + SCNHSZ * fh->f_nscns > bprm->inode->i_size || ah->text_start + ah->tsize > ah->data_start ) return -ENOEXEC; if (fh->f_nscns > 24) { printk ("Too many sections in svr3 binary file\n"); return -ENOEXEC; } /* Touch main binary file (which has # 0). */ fd[0] = open_inode (bprm->inode, O_RDONLY); if (fd[0] < 0) return fd[0]; buf = (char *) kmalloc (2*1024, GFP_KERNEL); if (!buf) { sys_close (fd[0]); return -ENOMEM; } libs_buf = buf + 1024; retval = touch_svr3_binary (fd[0], buf, &bin_info[0], 0); if (retval < 0) { sys_close(fd[0]); kfree (buf); return retval; } /* Looking for STYP_LIB section for shared libraries. */ sh = (struct scnhdr *) (buf + FILHSZ + fh->f_opthdr); for (i = 0; i < fh->f_nscns; i++) if (sh[i].s_flags == STYP_LIB) break; if (i == fh->f_nscns) shlibs = 0; else shlibs = sh[i].s_nlib; /* Touch target shared library binary files (## 1--SHLIB_MAX). */ if (shlibs) { void *p; int slib_size = sh[i].s_size; if (shlibs > SHLIB_MAX) { retval = -ELIBMAX; goto error_close; } file = bin_info[0].file; retval = sys_lseek (fd[0], sh[i].s_scnptr, 0); if (retval < 0) goto error_close; if (retval != sh[i].s_scnptr) { retval = -EACCES; goto error_close; } set_fs (KERNEL_DS); retval = file->f_op->read (file->f_inode, file, libs_buf, 1024); set_fs (USER_DS); if (retval < 0) goto error_close; if (retval < slib_size) { retval = -ELIBSCN; goto error_close; } for (p = libs_buf, j = 1; j <= shlibs; j++) { int len; char *name; struct slib *slibh = (struct slib *) p; p += slibh->sl_pathndx * 4; len = (slibh->sl_entsz - slibh->sl_pathndx) * 4; if (len <= 0 || p + len > (void *) libs_buf + slib_size) { retval = -ELIBSCN; goto error_close; } /* Target shared library path name. Must be followed by one or more zeroes. */ name = (char *) p; /* Try to access this library. */ set_fs (KERNEL_DS); fd[j] = sys_open (name, 0, 0); set_fs (USER_DS); if (fd[j] < 0) { retval = fd[j]; goto error_close; } retval = touch_svr3_binary (fd[j],buf,&bin_info[j],SHMAGIC); if (retval < 0) { /* Renumbering for shared library context. */ if (retval == -ENOEXEC) retval = -ELIBBAD; else if (retval == -EACCES) retval = -ELIBACC; goto error_close; } p += len; } } /* if (shlibs) .... */ /* Check initial limits. This avoids letting people circumvent * size limits imposed on them by creating programs with large * arrays in the data or bss. */ rlim = current->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; if (ah->dsize + ah->bsize > rlim) { /* XXX: but in shlibs too */ retval = -ENOMEM; goto error_close; } kfree (buf); /* OK, this is the point of noreturn. */ entry = ah->entry & ~0x1; /* Avoids possibly hult after `rte' ??? */ flush_old_exec (bprm); current->personality = PER_SVR3; current->mm->end_code = bin_info[0].text_len + (current->mm->start_code = bin_info[0].text_addr); current->mm->end_data = bin_info[0].data_len + (current->mm->start_data = bin_info[0].data_addr); current->mm->brk = bin_info[0].bss_len + (current->mm->start_brk = current->mm->end_data); current->mm->rss = 0; current->mm->mmap = NULL; current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; current->flags &= ~PF_FORKNOEXEC; /* mmap all binaries */ for (i = 0; i < 1 + shlibs; i++) { struct bin_info *binf = &bin_info[i]; unsigned int blocksize = binf->file->f_inode->i_sb->s_blocksize; unsigned int start_bss, end_bss; if (binf->text_addr & (PAGE_SIZE - 1) || binf->data_addr & (PAGE_SIZE - 1) || binf->text_offs & (blocksize - 1) || binf->data_offs & (blocksize - 1) || !binf->file->f_op->mmap ) { /* cannot mmap immediatly */ do_mmap (NULL, PAGE_ROUND(binf->text_addr), binf->text_len + (binf->text_addr - PAGE_ROUND(binf->text_addr)), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); read_exec (binf->file->f_inode, binf->text_offs, (char *) binf->text_addr, binf->text_len, 0); do_mmap (NULL, PAGE_ROUND(binf->data_addr), binf->data_len + (binf->data_addr - PAGE_ROUND(binf->data_addr)), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); read_exec (binf->file->f_inode, binf->data_offs, (char *) binf->data_addr, binf->data_len, 0); /* there's no nice way of flushing a number of user pages to ram 8*( */ flush_cache_all(); } else { error = do_mmap (binf->file, binf->text_addr, binf->text_len, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, binf->text_offs); if (error != binf->text_addr) goto error_kill_close; error = do_mmap (binf->file, binf->data_addr, binf->data_len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, binf->data_offs); if (error != binf->data_addr) goto error_kill_close; #ifdef DMAGIC_NODEMAND /* DMAGIC is for pure executable (not demand loading). But let the shared libraries be demand load ??? */ if (i == 0 && ah->magic == DMAGIC) { volatile char c; unsigned long addr; /* Touch all pages in .text and .data segments. */ for (addr = binf->text_addr; addr < binf->text_addr + binf->text_len; addr += PAGE_SIZE ) c = get_fs_byte ((char *) addr); for (addr = binf->data_addr; addr < binf->data_addr + binf->data_len; addr += PAGE_SIZE ) c = get_fs_byte ((char *) addr); } #endif } sys_close (fd[i]); start_bss = PAGE_ALIGN(binf->data_addr + binf->data_len); end_bss = PAGE_ALIGN(binf->data_addr + binf->data_len + binf->bss_len); /* svr3 binaries very hope that .bss section had been initialized by zeroes. Oh... */ if (binf->bss_len != 0) { /* Because there may be skipped heap by alignment. */ int addr = binf->data_addr + binf->data_len; int i = start_bss - addr; /* start_bss is aligned, addr may be no */ while (i & 0x3) { put_fs_byte (0, (char *) addr); addr++; i--; } i >>= 2; while (i--) { put_fs_long (0, (long *) addr); addr += sizeof (long); } } if (end_bss >= start_bss) do_mmap (NULL, start_bss, end_bss - start_bss, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); #ifdef DMAGIC_NODEMAND /* The same reason as above. */ if (i == 0 && ah->magic == DMAGIC) { volatile char c; unsigned long addr; for (addr = start_bss; addr < end_bss; addr += PAGE_SIZE) c = get_fs_byte ((char *) addr); } #endif /* OK, now all is mmapped for binary # i */ } /* for (i = ... ) */
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ int load_565rle_image(char *filename, bool bf_supported) { struct fb_info *info; int fd, count, err = 0; unsigned max; unsigned short *data, *bits, *ptr; #ifndef CONFIG_FRAMEBUFFER_CONSOLE struct module *owner; #endif info = registered_fb[0]; if (!info) { printk(KERN_WARNING "%s: Can not access framebuffer\n", __func__); return -ENODEV; } #ifndef CONFIG_FRAMEBUFFER_CONSOLE while(!mdp_resource_initialized) { msleep(10); } owner = info->fbops->owner; if (!try_module_get(owner)) return -ENODEV; if (info->fbops->fb_open && info->fbops->fb_open(info, 0)) { module_put(owner); return -ENODEV; } #endif fd = sys_open(filename, O_RDONLY, 0); if (fd < 0) { printk(KERN_WARNING "%s: Can not open %s\n", __func__, filename); return -ENOENT; } count = sys_lseek(fd, (off_t)0, 2); if (count <= 0) { err = -EIO; goto err_logo_close_file; } sys_lseek(fd, (off_t)0, 0); data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_WARNING "%s: Can not alloc data\n", __func__); err = -ENOMEM; goto err_logo_close_file; } if (sys_read(fd, (char *)data, count) != count) { err = -EIO; goto err_logo_free_data; } max = fb_width(info) * fb_height(info); ptr = data; if (bf_supported && (info->node == 1 || info->node == 2)) { err = -EPERM; pr_err("%s:%d no info->creen_base on fb%d!\n", __func__, __LINE__, info->node); goto err_logo_free_data; } bits = (unsigned short *)(info->screen_base); while (count > 3) { unsigned n = ptr[0]; if (n > max) break; if (info->var.bits_per_pixel >= 24) { /* rgb888 */ memset16_rgb8888(bits, ptr[1], n << 1); bits += n * 2; } else { memset16(bits, ptr[1], n << 1); bits += n; } max -= n; ptr += 2; count -= 4; } flush_cache_all(); outer_flush_all(); err_logo_free_data: kfree(data); err_logo_close_file: sys_close(fd); return err; }
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ int load_565rle_image(char *filename, bool bf_supported) { struct fb_info *info; int fd,count, err = 0; unsigned max; unsigned short *data, *ptr ; uint32_t *bits; unsigned int out; info = registered_fb[0]; if (!info) { printk(KERN_WARNING "%s: Can not access framebuffer\n", __func__); return -ENODEV; } fd = sys_open(filename, O_RDONLY, 0); if (fd < 0) { printk(KERN_WARNING "%s: Can not open %s\n", __func__, filename); return -ENOENT; } count = sys_lseek(fd, (off_t)0, 2); if (count <= 0) { err = -EIO; goto err_logo_close_file; } sys_lseek(fd, (off_t)0, 0); data = kmalloc(count, GFP_KERNEL); if (!data) { printk(KERN_WARNING "%s: Can not alloc data\n", __func__); err = -ENOMEM; goto err_logo_close_file; } if (sys_read(fd, (char *)data, count) != count) { err = -EIO; goto err_logo_free_data; } max = fb_width(info) * fb_height(info); ptr = data; if (bf_supported && (info->node == 1 || info->node == 2)) { err = -EPERM; pr_err("%s:%d no info->creen_base on fb%d!\n", __func__, __LINE__, info->node); goto err_logo_free_data; } bits = (uint32_t*)(info->screen_base); while (count > 3) { unsigned n = ptr[0]; if (n > max) break; out = rgb32(ptr[1]); memset32(bits, out, n << 2); bits += n; max -= n; ptr += 2; count -= 4; } err_logo_free_data: kfree(data); err_logo_close_file: sys_close(fd); return err; }
/* * This is the task which runs the usermode application */ static int ____call_usermodehelper(void *data) { struct subprocess_info *sub_info = data; int retval; /* Install input pipe when needed */ if (sub_info->stdin) { struct files_struct *f = current->files; struct fdtable *fdt; /* no races because files should be private here */ sys_close(0); fd_install(0, sub_info->stdin); spin_lock(&f->file_lock); fdt = files_fdtable(f); FD_SET(0, fdt->open_fds); FD_CLR(0, fdt->close_on_exec); spin_unlock(&f->file_lock); /* and disallow core files too */ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0}; } /* We can run anywhere, unlike our parent keventd(). */ set_cpus_allowed(current, CPU_MASK_ALL); retval = __exec_usermodehelper(sub_info->path, sub_info->argv, sub_info->envp, sub_info->ring); /* Exec failed? */ sub_info->retval = retval; do_exit(0); } /* Keventd can't block, but this (a child) can. */ static int wait_for_helper(void *data) { struct subprocess_info *sub_info = data; pid_t pid; struct k_sigaction sa; /* Install a handler: if SIGCLD isn't handled sys_wait4 won't * populate the status, but will return -ECHILD. */ sa.sa.sa_handler = SIG_IGN; sa.sa.sa_flags = 0; siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD)); do_sigaction(SIGCHLD, &sa, NULL); allow_signal(SIGCHLD); pid = kernel_thread(____call_usermodehelper, sub_info, SIGCHLD); if (pid < 0) { sub_info->retval = pid; } else { /* * Normally it is bogus to call wait4() from in-kernel because * wait4() wants to write the exit code to a userspace address. * But wait_for_helper() always runs as keventd, and put_user() * to a kernel address works OK for kernel threads, due to their * having an mm_segment_t which spans the entire address space. * * Thus the __user pointer cast is valid here. */ sys_wait4(pid, (int __user *) &sub_info->retval, 0, NULL); } complete(sub_info->complete); return 0; } /* This is run by khelper thread */ static void __call_usermodehelper(void *data) { struct subprocess_info *sub_info = data; pid_t pid; int wait = sub_info->wait; /* CLONE_VFORK: wait until the usermode helper has execve'd * successfully We need the data structures to stay around * until that is done. */ if (wait) pid = kernel_thread(wait_for_helper, sub_info, CLONE_FS | CLONE_FILES | SIGCHLD); else pid = kernel_thread(____call_usermodehelper, sub_info, CLONE_VFORK | SIGCHLD); if (pid < 0) { sub_info->retval = pid; complete(sub_info->complete); } else if (!wait) complete(sub_info->complete); } /** * call_usermodehelper_keys - start a usermode application * @path: pathname for the application * @argv: null-terminated argument list * @envp: null-terminated environment list * @session_keyring: session keyring for process (NULL for an empty keyring) * @wait: wait for the application to finish and return status. * * Runs a user-space application. The application is started * asynchronously if wait is not set, and runs as a child of keventd. * (ie. it runs with full root capabilities). * * Must be called from process context. Returns a negative error code * if program was not execed successfully, or 0. */ int call_usermodehelper_keys(char *path, char **argv, char **envp, struct key *session_keyring, int wait) { DECLARE_COMPLETION_ONSTACK(done); struct subprocess_info sub_info = { .complete = &done, .path = path, .argv = argv, .envp = envp, .ring = session_keyring, .wait = wait, .retval = 0, }; DECLARE_WORK(work, __call_usermodehelper, &sub_info); if (!khelper_wq) return -EBUSY; if (path[0] == '\0') return 0; queue_work(khelper_wq, &work); wait_for_completion(&done); return sub_info.retval; } EXPORT_SYMBOL(call_usermodehelper_keys); int call_usermodehelper_pipe(char *path, char **argv, char **envp, struct file **filp) { DECLARE_COMPLETION(done); struct subprocess_info sub_info = { .complete = &done, .path = path, .argv = argv, .envp = envp, .retval = 0, }; struct file *f; DECLARE_WORK(work, __call_usermodehelper, &sub_info); if (!khelper_wq) return -EBUSY; if (path[0] == '\0') return 0; f = create_write_pipe(); if (!f) return -ENOMEM; *filp = f; f = create_read_pipe(f); if (!f) { free_write_pipe(*filp); return -ENOMEM; } sub_info.stdin = f; queue_work(khelper_wq, &work); wait_for_completion(&done); return sub_info.retval; } EXPORT_SYMBOL(call_usermodehelper_pipe); void __init usermodehelper_init(void) { khelper_wq = create_singlethread_workqueue("khelper"); BUG_ON(!khelper_wq); }
void syscall(struct trapframe *tf) { int callno; int32_t retval; int err; KASSERT(curthread != NULL); KASSERT(curthread->t_curspl == 0); KASSERT(curthread->t_iplhigh_count == 0); callno = tf->tf_v0; /* * Initialize retval to 0. Many of the system calls don't * really return a value, just 0 for success and -1 on * error. Since retval is the value returned on success, * initialize it to 0 by default; thus it's not necessary to * deal with it except for calls that return other values, * like write. */ retval = 0; switch (callno) { case SYS_reboot: err = sys_reboot(tf->tf_a0); break; case SYS___time: err = sys___time((userptr_t)tf->tf_a0, (userptr_t)tf->tf_a1); break; //#if OPT_A2 case SYS_write: err = sys_write((int)tf->tf_a0, (userptr_t)tf->tf_a1, (int)tf->tf_a2, (int *)(&retval)); break; case SYS__exit: sys__exit((int)tf->tf_a0); /* sys__exit does not return, execution should not get here */ panic("unexpected return from sys__exit"); break; case SYS_open: err = sys_open((char *) tf->tf_a0, (int) tf->tf_a1, tf->tf_a2);// (int *)(&retval)); if(err > 0) { retval = err; err = 0; } break; case SYS_close: err = sys_close(tf->tf_a0); break; case SYS_read: err = sys_read((int)tf->tf_a0, (userptr_t)tf->tf_a1, (int)tf->tf_a2, (int *)(&retval)); //kprintf("\n\n\nniggas\n%d\nin paris\n\n\n",err); if (err > 0){ retval = err; err = 0; } break; case SYS_getpid: err = sys_getpid(); if(err > 0){ retval = err; err = 0; } break; case SYS_waitpid: //err = sys_waitpid(tf->tf_a0, (int *)tf->tf_a1, tf->tf_a2); break; default: kprintf("Unknown syscall %d\n", callno); err = ENOSYS; break; } if (err) { /* * Return the error code. This gets converted at * userlevel to a return value of -1 and the error * code in errno. */ tf->tf_v0 = err; tf->tf_a3 = 1; /* signal an error */ } else { /* Success. */ tf->tf_v0 = retval; tf->tf_a3 = 0; /* signal no error */ } /* * Now, advance the program counter, to avoid restarting * the syscall over and over again. */ tf->tf_epc += 4; /* Make sure the syscall code didn't forget to lower spl */ KASSERT(curthread->t_curspl == 0); /* ...or leak any spinlocks */ KASSERT(curthread->t_iplhigh_count == 0); }
static int syscall_dispatch(uint32_t sysnum, uint32_t args, regs_t *regs) { switch (sysnum) { case SYS_waitpid: return sys_waitpid((waitpid_args_t *) args); case SYS_exit: do_exit((int) args); panic("exit failed!\n"); return 0; case SYS_thr_exit: kthread_exit((void *) args); panic("thr_exit failed!\n"); return 0; case SYS_thr_yield: sched_make_runnable(curthr); sched_switch(); return 0; case SYS_fork: return sys_fork(regs); case SYS_getpid: return curproc->p_pid; case SYS_sync: sys_sync(); return 0; #ifdef __MOUNTING__ case SYS_mount: return sys_mount((mount_args_t *) args); case SYS_umount: return sys_umount((argstr_t *) args); #endif case SYS_mmap: return (int) sys_mmap((mmap_args_t *) args); case SYS_munmap: return sys_munmap((munmap_args_t *) args); case SYS_open: return sys_open((open_args_t *) args); case SYS_close: return sys_close((int) args); case SYS_read: return sys_read((read_args_t *) args); case SYS_write: return sys_write((write_args_t *) args); case SYS_dup: return sys_dup((int) args); case SYS_dup2: return sys_dup2((dup2_args_t *) args); case SYS_mkdir: return sys_mkdir((mkdir_args_t *) args); case SYS_rmdir: return sys_rmdir((argstr_t *) args); case SYS_unlink: return sys_unlink((argstr_t *) args); case SYS_link: return sys_link((link_args_t *) args); case SYS_rename: return sys_rename((rename_args_t *) args); case SYS_chdir: return sys_chdir((argstr_t *) args); case SYS_getdents: return sys_getdents((getdents_args_t *) args); case SYS_brk: return (int) sys_brk((void *) args); case SYS_lseek: return sys_lseek((lseek_args_t *) args); case SYS_halt: sys_halt(); return -1; case SYS_set_errno: curthr->kt_errno = (int) args; return 0; case SYS_errno: return curthr->kt_errno; case SYS_execve: return sys_execve((execve_args_t *) args, regs); case SYS_stat: return sys_stat((stat_args_t *) args); case SYS_uname: return sys_uname((struct utsname *) args); case SYS_debug: return sys_debug((argstr_t *) args); case SYS_kshell: return sys_kshell((int) args); default: dbg(DBG_ERROR, "ERROR: unknown system call: %d (args: %#08x)\n", sysnum, args); curthr->kt_errno = ENOSYS; return -1; } }
static int __init mount_nfs_root(void) { char *root_dev, *root_data; unsigned int timeout; int try, err; err = nfs_root_data(&root_dev, &root_data); if (err != 0) return 0; /* * The server or network may not be ready, so try several * times. Stop after a few tries in case the client wants * to fall back to other boot methods. */ timeout = NFSROOT_TIMEOUT_MIN; for (try = 1; ; try++) { err = do_mount_root(root_dev, "nfs", root_mountflags, root_data); if (err == 0) return 1; if (try > NFSROOT_RETRY_MAX) break; /* Wait, in case the server refused us immediately */ ssleep(timeout); timeout <<= 1; if (timeout > NFSROOT_TIMEOUT_MAX) timeout = NFSROOT_TIMEOUT_MAX; } return 0; } #endif #if defined(CONFIG_BLK_DEV_RAM) || defined(CONFIG_BLK_DEV_FD) void __init change_floppy(char *fmt, ...) { struct termios termios; char buf[80]; char c; int fd; va_list args; va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0); if (fd >= 0) { sys_ioctl(fd, FDEJECT, 0); sys_close(fd); } printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf); fd = sys_open("/dev/console", O_RDWR, 0); if (fd >= 0) { sys_ioctl(fd, TCGETS, (long)&termios); termios.c_lflag &= ~ICANON; sys_ioctl(fd, TCSETSF, (long)&termios); sys_read(fd, &c, 1); termios.c_lflag |= ICANON; sys_ioctl(fd, TCSETSF, (long)&termios); sys_close(fd); } } #endif void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS if (ROOT_DEV == Root_NFS) { if (mount_nfs_root()) return; printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n"); ROOT_DEV = Root_FD0; } #endif #ifdef CONFIG_BLK_DEV_FD if (MAJOR(ROOT_DEV) == FLOPPY_MAJOR) { /* rd_doload is 2 for a dual initrd/ramload setup */ if (rd_doload==2) { if (rd_load_disk(1)) { ROOT_DEV = Root_RAM1; root_device_name = NULL; } } else change_floppy("root floppy"); } #endif #ifdef CONFIG_BLOCK create_dev("/dev/root", ROOT_DEV); mount_block_root("/dev/root", root_mountflags); #endif } /* * Prepare the namespace - decide what/where to mount, load ramdisks, etc. */ void __init prepare_namespace(void) { int is_floppy; if (root_delay) { printk(KERN_INFO "Waiting %dsec before mounting root device...\n", root_delay); ssleep(root_delay); } /* * wait for the known devices to complete their probing * * Note: this is a potential source of long boot delays. * For example, it is not atypical to wait 5 seconds here * for the touchpad of a laptop to initialize. */ wait_for_device_probe(); md_run_setup(); if (saved_root_name[0]) { root_device_name = saved_root_name; if (!strncmp(root_device_name, "mtd", 3) || !strncmp(root_device_name, "ubi", 3)) { mount_block_root(root_device_name, root_mountflags); goto out; } ROOT_DEV = name_to_dev_t(root_device_name); if (strncmp(root_device_name, "/dev/", 5) == 0) root_device_name += 5; } if (initrd_load()) goto out; /* wait for any asynchronous scanning to complete */ if ((ROOT_DEV == 0) && root_wait) { printk(KERN_INFO "Waiting for root device %s...\n", saved_root_name); while (driver_probe_done() != 0 || (ROOT_DEV = name_to_dev_t(saved_root_name)) == 0) msleep(100); async_synchronize_full(); } is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR; if (is_floppy && rd_doload && rd_load_disk(0)) ROOT_DEV = Root_RAM0; mount_root(); out: devtmpfs_mount("dev"); sys_mount(".", "/", NULL, MS_MOVE, NULL); sys_chroot((const char __user __force *)"."); }
int init_file_list (struct file_list_struct* file_list, char* file_list_path) { mm_segment_t old_fs = get_fs (); int fd, rc = -1, copyed; int count; struct file* file = NULL; loff_t pos = 0; //change it later mutex_init (&file_list->file_list_mutex); file_list_path = "/replay_logdb/file_list"; printk ("Pid %d begins init_file_list, filename %s\n", current->pid, file_list_path); set_fs (KERNEL_DS); fd = sys_open (file_list_path, O_RDONLY, 0); if (fd < 0) { printk ("init_file_list , cannot open file %s, return %d\n", file_list_path, fd); goto exit; } file = fget (fd); //read the count for ignored files copyed = vfs_read (file, (char*) &count, sizeof(int), &pos); if (copyed != sizeof (int)) { printk ("init_file_list: ftried to read count for ignored_file_list, got rc %d\n", copyed); rc = copyed; goto exit; } if (count > 0) { file_list->ignored_count = count; file_list->ignored_list = (struct file_list_name_struct*) kmalloc (count * sizeof(struct file_list_name_struct), GFP_KERNEL); if (file_list->ignored_list == NULL) { printk ("init_file_list: unable to allocate ignored_list with size %d\n", count*sizeof(struct file_list_name_struct)); rc = -ENOMEM; goto exit; } copyed = vfs_read (file, (char*)file_list->ignored_list, count*sizeof(struct file_list_name_struct), &pos); if (copyed != count*sizeof(struct file_list_name_struct)) { printk ("init_file_list: ftried to read ignored_list for ignored_file_list, got rc %d, expected:%d\n", copyed, count*sizeof(struct file_list_name_struct)); rc = copyed; goto exit; } } else { file_list->ignored_count = 0; file_list->ignored_list = NULL; } //read the count for modify files copyed = vfs_read (file, (char*) &count, sizeof(int), &pos); if (copyed != sizeof (int)) { printk ("init_file_list: ftried to read count for modify_file_list, got rc %d\n", copyed); rc = copyed; goto exit; } if (count > 0) { file_list->modify_count = count; file_list->modify_list = (struct file_list_name_struct*) kmalloc (count * sizeof(struct file_list_name_struct), GFP_KERNEL); if (file_list->modify_list == NULL) { printk ("init_file_list: unable to allocate modify_list with size %d\n", count*sizeof(struct file_list_name_struct)); rc = -ENOMEM; goto exit; } copyed = vfs_read (file, (char*)file_list->modify_list, count*sizeof(struct file_list_name_struct), &pos); if (copyed != count*sizeof(struct file_list_name_struct)) { printk ("init_file_list: ftried to read modify_list for modify_file_list, got rc %d, expected:%d\n", copyed, count*sizeof(struct file_list_name_struct)); rc = copyed; goto exit; } } else { file_list->modify_count = 0; file_list->modify_list = NULL; } printk ("Pid %d init_file_list done.\n", current->pid); exit: if (fd >= 0) { rc = sys_close (fd); if (rc < 0) printk ("init_file_list: close returns %d\n", rc); } if (file) fput(file); set_fs(old_fs); if (rc < 0) return rc; return 0; }