diff options
Diffstat (limited to 'arch/um/os-Linux/start_up.c')
-rw-r--r-- | arch/um/os-Linux/start_up.c | 173 |
1 files changed, 26 insertions, 147 deletions
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 5178eba9afa5..79471f85eb89 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -17,10 +17,10 @@ | |||
17 | #include <sys/time.h> | 17 | #include <sys/time.h> |
18 | #include <sys/wait.h> | 18 | #include <sys/wait.h> |
19 | #include <sys/mman.h> | 19 | #include <sys/mman.h> |
20 | #include <sys/resource.h> | ||
20 | #include <asm/unistd.h> | 21 | #include <asm/unistd.h> |
21 | #include <asm/page.h> | 22 | #include <asm/page.h> |
22 | #include <sys/types.h> | 23 | #include <sys/types.h> |
23 | #include "user_util.h" | ||
24 | #include "kern_util.h" | 24 | #include "kern_util.h" |
25 | #include "user.h" | 25 | #include "user.h" |
26 | #include "signal_kern.h" | 26 | #include "signal_kern.h" |
@@ -329,8 +329,32 @@ static void __init check_ptrace(void) | |||
329 | 329 | ||
330 | extern void check_tmpexec(void); | 330 | extern void check_tmpexec(void); |
331 | 331 | ||
332 | void os_early_checks(void) | 332 | static void __init check_coredump_limit(void) |
333 | { | 333 | { |
334 | struct rlimit lim; | ||
335 | int err = getrlimit(RLIMIT_CORE, &lim); | ||
336 | |||
337 | if(err){ | ||
338 | perror("Getting core dump limit"); | ||
339 | return; | ||
340 | } | ||
341 | |||
342 | printf("Core dump limits :\n\tsoft - "); | ||
343 | if(lim.rlim_cur == RLIM_INFINITY) | ||
344 | printf("NONE\n"); | ||
345 | else printf("%lu\n", lim.rlim_cur); | ||
346 | |||
347 | printf("\thard - "); | ||
348 | if(lim.rlim_max == RLIM_INFINITY) | ||
349 | printf("NONE\n"); | ||
350 | else printf("%lu\n", lim.rlim_max); | ||
351 | } | ||
352 | |||
353 | void __init os_early_checks(void) | ||
354 | { | ||
355 | /* Print out the core dump limits early */ | ||
356 | check_coredump_limit(); | ||
357 | |||
334 | check_ptrace(); | 358 | check_ptrace(); |
335 | 359 | ||
336 | /* Need to check this early because mmapping happens before the | 360 | /* Need to check this early because mmapping happens before the |
@@ -528,148 +552,3 @@ int __init parse_iomem(char *str, int *add) | |||
528 | out: | 552 | out: |
529 | return 1; | 553 | return 1; |
530 | } | 554 | } |
531 | |||
532 | |||
533 | /* Changed during early boot */ | ||
534 | int pty_output_sigio = 0; | ||
535 | int pty_close_sigio = 0; | ||
536 | |||
537 | /* Used as a flag during SIGIO testing early in boot */ | ||
538 | static volatile int got_sigio = 0; | ||
539 | |||
540 | static void __init handler(int sig) | ||
541 | { | ||
542 | got_sigio = 1; | ||
543 | } | ||
544 | |||
545 | struct openpty_arg { | ||
546 | int master; | ||
547 | int slave; | ||
548 | int err; | ||
549 | }; | ||
550 | |||
551 | static void openpty_cb(void *arg) | ||
552 | { | ||
553 | struct openpty_arg *info = arg; | ||
554 | |||
555 | info->err = 0; | ||
556 | if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) | ||
557 | info->err = -errno; | ||
558 | } | ||
559 | |||
560 | static int async_pty(int master, int slave) | ||
561 | { | ||
562 | int flags; | ||
563 | |||
564 | flags = fcntl(master, F_GETFL); | ||
565 | if(flags < 0) | ||
566 | return -errno; | ||
567 | |||
568 | if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || | ||
569 | (fcntl(master, F_SETOWN, os_getpid()) < 0)) | ||
570 | return -errno; | ||
571 | |||
572 | if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) | ||
573 | return -errno; | ||
574 | |||
575 | return(0); | ||
576 | } | ||
577 | |||
578 | static void __init check_one_sigio(void (*proc)(int, int)) | ||
579 | { | ||
580 | struct sigaction old, new; | ||
581 | struct openpty_arg pty = { .master = -1, .slave = -1 }; | ||
582 | int master, slave, err; | ||
583 | |||
584 | initial_thread_cb(openpty_cb, &pty); | ||
585 | if(pty.err){ | ||
586 | printk("openpty failed, errno = %d\n", -pty.err); | ||
587 | return; | ||
588 | } | ||
589 | |||
590 | master = pty.master; | ||
591 | slave = pty.slave; | ||
592 | |||
593 | if((master == -1) || (slave == -1)){ | ||
594 | printk("openpty failed to allocate a pty\n"); | ||
595 | return; | ||
596 | } | ||
597 | |||
598 | /* Not now, but complain so we now where we failed. */ | ||
599 | err = raw(master); | ||
600 | if (err < 0) | ||
601 | panic("check_sigio : __raw failed, errno = %d\n", -err); | ||
602 | |||
603 | err = async_pty(master, slave); | ||
604 | if(err < 0) | ||
605 | panic("tty_fds : sigio_async failed, err = %d\n", -err); | ||
606 | |||
607 | if(sigaction(SIGIO, NULL, &old) < 0) | ||
608 | panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); | ||
609 | new = old; | ||
610 | new.sa_handler = handler; | ||
611 | if(sigaction(SIGIO, &new, NULL) < 0) | ||
612 | panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); | ||
613 | |||
614 | got_sigio = 0; | ||
615 | (*proc)(master, slave); | ||
616 | |||
617 | close(master); | ||
618 | close(slave); | ||
619 | |||
620 | if(sigaction(SIGIO, &old, NULL) < 0) | ||
621 | panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); | ||
622 | } | ||
623 | |||
624 | static void tty_output(int master, int slave) | ||
625 | { | ||
626 | int n; | ||
627 | char buf[512]; | ||
628 | |||
629 | printk("Checking that host ptys support output SIGIO..."); | ||
630 | |||
631 | memset(buf, 0, sizeof(buf)); | ||
632 | |||
633 | while(os_write_file(master, buf, sizeof(buf)) > 0) ; | ||
634 | if(errno != EAGAIN) | ||
635 | panic("check_sigio : write failed, errno = %d\n", errno); | ||
636 | while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; | ||
637 | |||
638 | if(got_sigio){ | ||
639 | printk("Yes\n"); | ||
640 | pty_output_sigio = 1; | ||
641 | } | ||
642 | else if(n == -EAGAIN) printk("No, enabling workaround\n"); | ||
643 | else panic("check_sigio : read failed, err = %d\n", n); | ||
644 | } | ||
645 | |||
646 | static void tty_close(int master, int slave) | ||
647 | { | ||
648 | printk("Checking that host ptys support SIGIO on close..."); | ||
649 | |||
650 | close(slave); | ||
651 | if(got_sigio){ | ||
652 | printk("Yes\n"); | ||
653 | pty_close_sigio = 1; | ||
654 | } | ||
655 | else printk("No, enabling workaround\n"); | ||
656 | } | ||
657 | |||
658 | void __init check_sigio(void) | ||
659 | { | ||
660 | if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && | ||
661 | (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ | ||
662 | printk("No pseudo-terminals available - skipping pty SIGIO " | ||
663 | "check\n"); | ||
664 | return; | ||
665 | } | ||
666 | check_one_sigio(tty_output); | ||
667 | check_one_sigio(tty_close); | ||
668 | } | ||
669 | |||
670 | void os_check_bugs(void) | ||
671 | { | ||
672 | check_ptrace(); | ||
673 | check_sigio(); | ||
674 | } | ||
675 | |||