示例#1
0
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;
}
示例#2
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);
}
示例#3
0
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 = ... )   */
示例#4
0
/* 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;
}
示例#5
0
/* 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;
}
示例#6
0
/*
 * 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);
}
示例#8
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;
	}
}
示例#9
0
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 *)".");
}
示例#10
0
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;
}