Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OSv on bhyve

OSv on bhyve

Takuya ASADA

March 12, 2014
Tweet

More Decks by Takuya ASADA

Other Decks in Technology

Transcript

  1. 8IBUJT04W w 04WJTPQFOTPVSDF04XIJDIEFTJHOFEUPFYFDVUFB TJOHMFBQQMJDBUJPOPOUPQPGBIZQFSWJTPS w #FUUFSQFSGPSNBODF FBTZUPNBOBHF w %FWFMPQJOHCZ$MPVEJVT4ZTUFNT *TMBFMJTUBSUVQ


    $PSFNFNCFSBSFDPNFGSPN2VNSBOFU
 $50"WJ,JWJUZ b'BUIFS`PG,7.  w 0⒏DJBMTJUFIUUQPTWJP w (JUIVCIUUQHJUIVCDPNDMPVEJVTTZTUFNTPTW
  2. A Historical Anomaly Hardware Hypervisor Operating System JVM Application Server

    Your App provides protection and abstraction provides protection and abstraction provides protection and abstraction
  3. Too Many Layers, Too Little Value Property/Component Hardware abstraction Isolation

    Resource virtualization Backward compatibility Security Memory management I/O stack Configuration VMM OS runtime Duplication
  4. The new Cloud Stack - OSv Hardware Hypervisor Core JVM

    Application Server Your App Single Process Kernel space only Linked to existing JVMs App sees no change
  5. Use cases •  Rent-an-instance on a public cloud •  Internal

    instance on a private cloud •  Pre-packaged apps ◦  MemCache, NoSQL •  OEM virtual appliance
  6. 04WJOUFSOBMTUSVDUVSF w 5IJO04DPSF  'SFF#4%;'4  5$1*1BOENVTM MJCD w "CMFUPMPBESVO

    -JOVYCJOBSZPG 0QFO+%, OpenJDK OSv kernel FBSD code ZFS TCP/ IP COM port virtio- blk virtio- net clock ACPI sched uler ramfs VFS MM libc ELF loader syscall emu libjvm.so java.so CRuSH JRuby Sinat ra Pum a HTTP SSH 0SJHJOBMDPEFʢ$ ʣ 1PSUJOH -JOVYCJOBSZ +BWBCZUFDPEF
  7. $BQQPO04W w "MMBQQMJDBUJPOTIPVMECFDPNQJMFEXJUI
 $'-"(4 G1*$
 -%'-"(4TIBSFE
 ˠ4IBSFEMJCSBSZ CVUXJUINBJO  w

    :PVDBOMPBE-JOVYTIBSFEMJCSBSZ CVUOFFEUP SFDPNQJMFFYFDVUBCMFT w -JOVYDPNQBUJCJMJUZJTJNQMFNFOUFEPOMJCDMBZFS w /PTZTDBMM
  8. "WBJMBCMFBQQT w 0QFO+%, w $BTTBOESB w 5PNDBU w IBQSPYZ w

    NFNDBDIFE w SPHVF w NSVCZ w TRMJUF w CFODINBSLT OFUQFSG JQFSG TQFDKWN
  9. 5SBEJUJPOBMCPPUQSPDFEVSF XJUI#*04 w #*04MPBETCPPUTFDUPSGSPN.#3POBEJTL w #PPUTFDUPSMPBETBOEKVNQTUPCPPUMPBEFS
 #*04DBMMVTFEGPS*0  w #PPUMPBEFSJOJUJBMJ[FTQBHFUBCMF

    (%5BOETQFDJBMSFHJTUFST w #PPUMPBEFSMPDBUFTBOEMPBETLFSOFM
 #*04DBMMVTFEGPS*0  w #PPUMPBEFSTXJUDIFTUPCJUNPEF KVNQTUPLFSOFMFOUSZ QPJOU
  10. %JSFDUCPPU w #*04MPBETCPPUTFDUPSGSPN.#3POBEJTL w #PPUTFDUPSMPBETBOEKVNQTUPCPPUMPBEFS
 #*04DBMMVTFEGPS*0  w #PPUMPBEFSJOJUJBMJ[FTQBHFUBCMF (%5BOETQFDJBMSFHJTUFST

    w #PPUMPBEFSMPDBUFTBOEMPBETLFSOFM
 #*04DBMMVTFEGPS*0  w #PPUMPBEFSTXJUDIFTUPCJUNPEF KVNQTUPLFSOFMFOUSZ QPJOU %PJUJO)PTU04
  11. DPEFFYBNQMF  w 1SJOUTUSJOHPODPOTPMF #*04*/5I 
 printf() w 3FBEEJTL #*04*/5I

    
 fd  =  open(disk_image)
 read(fd,  buf,  len)   w NFNPSZBDDFTT
 ctx  =  vm_open(vm_name)
 ptr  =  vm_map_gpa(ctx,  offset,  len)
 memcpy(ptr,  data,  len)
  12. DPEFFYBNQMF  w 3FHJTUFSXSJUF OPSNBMSFHJTUFST 
 ctx  =  vm_open(vm_name)
 vm_set_register(ctx,

     cpuno,   VM_REG_GUEST_RFLAGS,  val)   w 3FHJTUFSXSJUF 4FHNFOUSFHJTUFST 
 ctx  =  vm_open(vm_name)
 vm_set_desc(ctx,  cpuno,  VM_REG_GUEST_CS,   base,  limit,  access)
 vm_set_register(ctx,  cpuno,   VM_REG_GUEST_CS,  selector)
  13. -FU`TCFHJOUPUSBOTMBUF CPPU4 w IUUQTHJUIVCDPNDMPVEJVTTZTUFNTPTWCMPC NBTUFSBSDIYCPPU4 w *U`TPO.#3CPPUTFDUPS w -PBELFSOFMBSHVNFOUGSPNEJTL w

    -PBELFSOFM&-'CJOBSZGSPNEJTL w (FUNFNPSZNBQGSPN#*04 F  w &OUSZUPLFSOFMCJUQSPUFDUFENPEFDPEF
  14. EJTLJNBHFMBZPVUPG04W w %PFTOPUVTFTUBOEBSE CPPUMPBEFS &Y(36# UP CPPUGBTUFS w LFSOFMBSHVNFOU LFSOFM

    &-'CJOBSZBSFQMBDFEPO pYFETFDUPS MBR (boot16.S) 0 1 cmdline 64 128 blank? loader.elf 262144 bootfs (bootfs.manifest) nsectors ZFS (usr.manifest)
  15. 5SBOTMBUFCPPUDPEF  
 DNEMJOFMPBE cmdline  =  0x7e00   ! mb_info

     =  0x1000   mb_cmdline  =  (mb_info  +  16)       ! int1342_boot_struct:  #  for  command  line  ←  DAP                  .byte  0x10  ←  size  of  DAP                  .byte  0  ←  unused                  .short  0x3f      #  31.5k  ←  number  of  sectors  to  be  read                  .short  cmdline  ←  segment:offset  pointer  to  the  memory  bufferʢoffsetଆʣ                  .short  0  ←ʢsegmentଆʣ                  .quad  1  ←  absolute  number  of  the  start  of  the  sectors  to  be  read   ! init:                  xor  %ax,  %ax                  mov  %ax,  %ds  ←  DS  =  0   !                lea  int1342_boot_struct,  %si  ←  DS:SIͰDAPΛࢦఆ                  mov  $0x42,  %ah                  mov  $0x80,  %dl                  int  $0x13  ←  INT  13h  AH=42h:  Extended  Read  Sectors  From  Drive                  movl  $cmdline,  mb_cmdline  ←  mb_info-­‐>mb_cmdlineʹ0x7e00Λ୅ೖ
  16. 5SBOTMBUFCPPUDPEF  
 DNEMJOFMPBE char  *cmdline;   struct  multiboot_info_type  *mb_info;

      ! cmdline  =  vm_map_gpa(ctx,  0x7e00,  1  *   512);   pread(disk_fd,  cmdline,  0x3f  *  512,  1  *   512);   ! mb_info  =  vm_map_gpa(ctx,  0x1000,   sizeof(*mb_info));   mb_info-­‐>cmdline  =  0x7e00;  
  17. 5SBOTMBUFCPPUDPEF  
 LFSOFMMPBE tmp  =  0x80000   count32:  .short

     4096  #  in  32k  units,  4096=128MB   int1342_struct:                  .byte  0x10                  .byte  0                  .short  0x40      #  32k                  .short  0                  .short  tmp  /  16   lba:                  .quad  128   ! read_disk:                  lea  int1342_struct,  %si                  mov  $0x42,  %ah                  mov  $0x80,  %dl                  int  $0x13                  jc  done_disk                  cli                  lgdtw  gdt                  mov  $0x11,  %ax                  lmsw  %ax                  ljmp  $8,  $1f   1:                  .code32                  mov  $0x10,  %ax                  mov  %eax,  %ds                  mov  %eax,  %es                  mov  $tmp,  %esi                  mov  xfer,  %edi                  mov  $0x8000,  %ecx                  rep  movsb                  mov  %edi,  xfer                  mov  $0x20,  %al                  mov  %eax,  %ds                  mov  %eax,  %es                  ljmpw  $0x18,  $1f   1:                  .code16                  mov  $0x10,  %eax                  mov  %eax,  %cr0                  ljmpw  $0,  $1f   1:                  xor  %ax,  %ax                  mov  %ax,  %ds                  mov  %ax,  %es                  sti                  addl  $(0x8000  /  0x200),  lba                  decw  count32                  jnz  read_disk  ←  count32ճϧʔϓ   done_disk:
  18. 5SBOTMBUFCPPUDPEF  
 LFSOFMMPBE char  *target;   ! target  =

     vm_map_gpa(ctx,  0x200000,  1  *   512);   pread(disk_fd,  target,  0x40  *  4096  *   512,  128  *  512);
  19. 5SBOTMBUFCPPUDPEF  
 NFNPSZNBQ F mb_info  =  0x1000   mb_mmap_len

     =  (mb_info  +  44)   mb_mmap_addr  =  (mb_info  +  48)   e820data  =  0x2000   !                mov  $e820data,  %edi  ←  ES:DI   Buffer  Pointer                  mov  %edi,  mb_mmap_addr  ←  mb_info-­‐>mb_mmap_addrʹ0x2000Λ୅ೖ                  xor  %ebx,  %ebx  ←  Continuation   more_e820:                  mov  $100,  %ecx  ←  Buffer  Size                  mov  $0x534d4150,  %edx  ←  Signature  'SMAP'                    mov  $0xe820,  %ax                  add  $4,  %edi                  int  $0x15  ←  INT  15h,  AX=E820h  -­‐  Query  System  Address  Map                  jc  done_e820                  mov  %ecx,  -­‐4(%edi)                  add  %ecx,  %edi                  test  %ebx,  %ebx                  jnz  more_e820   done_e820:                  sub  $e820data,  %edi                  mov  %edi,  mb_mmap_len  ←  mb_info-­‐>mb_mmap_lenʹe820dataͷαΠζΛ୅ೖ
  20. 5SBOTMBUFCPPUDPEF  
 NFNPSZNBQ F struct  e820ent  *e820data;   !

    e820data  =  vm_map_gpa(ctx,  0x1100,  sizeof(struct  e820ent)  *  3);   e820data[0].ent_size  =  20;   e820data[0].addr  =  0x0;   e820data[0].size  =  654336;   e820data[0].type  =  1;   e820data[1].ent_size  =  20;   e820data[1].addr  =  0x100000;   e820data[1].size  =  mem_size  -­‐  0x100000;   e820data[1].type  =  1;   e820data[2].ent_size  =  20;   e820data[2].addr  =  0;   e820data[2].size  =  0;   e820data[2].type  =  0;   ! mb_info-­‐>mmap_addr  =  0x1100;   mb_info-­‐>mmap_length  =  sizeof(struct  e820ent)  *  3;
  21. 5SBOTMBUFCPPUDPEF  
 FOUSZUPQSPUFDUFENPEF cmdline  =  0x7e00   target  =

     0x200000   entry  =  24+target   mb_info  =  0x1000   !                ljmp  $8,  $1f   1:                  .code32                  mov  $0x10,  %ax                  mov  %eax,  %ds                  mov  %eax,  %es                  mov  %eax,  %gs                  mov  %eax,  %fs                  mov  %eax,  %ss                  mov  $target,  %eax  ←  0x200000Λeaxʹઃఆ                  mov  $mb_info,  %ebx  ←  0x1000Λebxʹઃఆ                  jmp  *entry  ←  32bit  protected  modeͷίʔυΛಈ͔ͭ͢΋Γ͸ͳ͍ͷͰແࢹ
  22. 5SBOTMBUFCPPUDPEF  
 *OJUJBMJ[F(%5 gdt_desc:          .short

     gdt_end  -­‐  gdt  -­‐  1          .long  gdt   ! .align  8   gdt  =  .  -­‐  8          .quad  0x00af9b000000ffff  #  64-­‐bit  code  segment          .quad  0x00cf93000000ffff  #  64-­‐bit  data  segment          .quad  0x00cf9b000000ffff  #  32-­‐bit  code  segment   gdt_end  =  .   ! lgdt  gdt_desc
  23. 5SBOTMBUFCPPUDPEF  
 *OJUJBMJ[F(%5 /*  gdtr͸ۭ͍ͯͦ͏ͳద౰ͳྖҬʹஔ͘  */
 uint64_t  *gdtr  =

     vm_map_gpa(ctx,  0x5000,   sizeof(struct  uint64_t)  *  4);
 gdtr[0]  =  0x0;
 gdtr[1]  =  0x00af9b000000ffff;  
 gdtr[2]  =  0x00cf93000000ffff;
 gdtr[3]  =  0x00cf9b000000ffff;
 
 vm_set_desc(ctx,  0,  VM_REG_GUEST_GDTR,  gdtr,   sizeof(struct  uint64_t)  *  4  -­‐  1,  0);  
  24. 5SBOTMBUFCPPUDPEF  
 *OJUJBMJ[F1BHF5BCMF .data   .align  4096   ident_pt_l4:

             .quad  ident_pt_l3  +  0x67          .rept  511          .quad  0          .endr   ident_pt_l3:          .quad  ident_pt_l2  +  0x67          .rept  511          .quad  0          .endr   ident_pt_l2:          index  =  0          .rept  512          .quad  (index  <<  21)  +  0x1e7          index  =  index  +  1          .endr   ! lea  ident_pt_l4,  %eax   mov  %eax,  %cr3
  25. 5SBOTMBUFCPPUDPEF  
 *OJUJBMJ[F1BHF5BCMF uint64_t  *PT4;
 uint64_t  *PT3;
 uint64_t  *PT2;


    
 /*  PT4-­‐2͸ۭ͍ͯͦ͏ͳద౰ͳྖҬʹஔ͘  */
 PT4  =  vm_map_gpa(ctx,  0x4000,  sizeof(uint64_t)  *  512);
 PT3  =  vm_map_gpa(ctx,  0x3000,  sizeof(uint64_t)  *  512);
 PT2  =  vm_map_gpa(ctx,  0x2000,  sizeof(uint64_t)  *  512);
 
 for  (i  =  0;  i  <  512;  i++)  {
          PT4[i]  =  (uint64_t)  ADDR_PT3;
          PT4[i]  |=  PG_V  |  PG_RW  |  PG_U;
          PT3[i]  =  (uint64_t)  ADDR_PT2;
          PT3[i]  |=  PG_V  |  PG_RW  |  PG_U;
          PT2[i]  =  i  *  (2  *  1024  *  1024);
          PT2[i]  |=  PG_V  |  PG_RW  |  PG_PS  |  PG_U;
 }
 
 vm_set_register(ctx,  0,  VM_REG_GUEST_CR3,  0x4000);
  26. 5SBOTMBUFCPPUDPEF  
 *OJUJBMJ[FTQFDJBMSFHJTUFSTGPSCJUNPEF #define  BOOT_CR0  (  X86_CR0_PE  \  

                                     |  X86_CR0_WP  \                                    |  X86_CR0_PG  )   ! #define  BOOT_CR4  (  X86_CR4_DE                  \                                    |  X86_CR4_PSE                \                                    |  X86_CR4_PAE                \                                    |  X86_CR4_PGE                \                                    |  X86_CR4_PCE                \                                    |  X86_CR4_OSFXSR          \                                    |  X86_CR4_OSXMMEXCPT  )          and  $~7,  %esp          mov  $BOOT_CR4,  %eax          mov  %eax,  %cr4  ←  PAE༗ޮͳͲ          mov  $0xc0000080,  %ecx          mov  $0x00000900,  %eax          xor  %edx,  %edx          wrmsr  ←  EFERͷLMEϑϥάΛཱ͍ͯͯΔ          mov  $BOOT_CR0,  %eax          mov  %eax,  %cr0  ←  PE,PG༗ޮͳͲ
        ljmpl  $8,  $start64   .code64   .global  start64   start64:
  27. 5SBOTMBUFCPPUDPEF  
 *OJUJBMJ[FTQFDJBMSFHJTUFSTGPSCJUNPEF vm_set_register(ctx,  0,  VM_REG_GUEST_RSP,   ADDR_STACK);
 vm_set_register(ctx,

     0,   VM_REG_GUEST_EFER,  0x00000d00);
 vm_set_register(ctx,  0,  VM_REG_GUEST_CR4,   0x000007b8);
 vm_set_register(ctx,  0,  VM_REG_GUEST_CR0,   0x80010001);
  28. 5SBOTMBUFCPPUDPEF  
 CJUFOUSZQPJOU #define  BOOT_CR0  (  X86_CR0_PE  \  

                                     |  X86_CR0_WP  \                                    |  X86_CR0_PG  )   ! #define  BOOT_CR4  (  X86_CR4_DE                  \                                    |  X86_CR4_PSE                \                                    |  X86_CR4_PAE                \                                    |  X86_CR4_PGE                \                                    |  X86_CR4_PCE                \                                    |  X86_CR4_OSFXSR          \                                    |  X86_CR4_OSXMMEXCPT  )          and  $~7,  %esp          mov  $BOOT_CR4,  %eax          mov  %eax,  %cr4          mov  $0xc0000080,  %ecx          mov  $0x00000900,  %eax          xor  %edx,  %edx          wrmsr          mov  $BOOT_CR0,  %eax          mov  %eax,  %cr0
        ljmpl  $8,  $start64   .code64   .global  start64    ←  Want  to  set  RIP  here   start64:
  29. -FU`TQBSTF&-'IFBEFS *NQMFNFOUTZNCPMOBNFUPBEESFTTGVODUJPO VTJOHFMG  BOEHFMG   JOUFMGQBSTF@PQFO@NFNPSZ DIBS JNBHF

    TJ[F@U TJ[F TUSVDUFMGQBSTF FQ  int  elfparse_close(struct  elfparse  *ep);   uintmax_t  elfparse_resolve_symbol(struct   elfparse  *ep,  char  *name);
  30. 5SBOTMBUFCPPUDPEF  
 CJUFOUSZQPJOU struct  elfparse  ep;
 uint64_t  start64;
 


    if  (elfparse_open_memory(target,  0x40  *   4096  *  512,  &ep));
 start64  =  elfparse_resolve_symbol(&ep,   "start64");
 vm_set_register(ctx,  0,  VM_REG_GUEST_RIP,   start64);
  31. $PNQMFUFEJNQMFNFOUBUJPO #  /usr/local/sbin/bhyveosvload  -­‐m  1024  -­‐d  ../loader.img  osv0   sizeof

     e820data=48   cmdline=java.so  -­‐jar  /usr/mgmt/web-­‐1.0.0.jar  app  prod   start64:0x208f13   ident_pt_l4:0x8d5000   gdt_desc:0x8d8000   #  /usr/sbin/bhyve  -­‐c  1  -­‐m  1024  -­‐AI  -­‐H  -­‐P  -­‐g  0  -­‐s  0:0,hostbridge  -­‐s   1:0,virtio-­‐net,tap0  -­‐s  2:0,virtio-­‐blk,../loader.img  -­‐S  31,uart,stdio  osv0   ACPI:  RSDP  0xf0400  00024  (v02  BHYVE  )   ACPI:  XSDT  0xf0480  00034  (v01  BHYVE    BVXSDT      00000001  INTL  20130823)   ACPI:  APIC  0xf0500  0004A  (v01  BHYVE    BVMADT      00000001  INTL  20130823)   ACPI:  FACP  0xf0600  0010C  (v05  BHYVE    BVFACP      00000001  INTL  20130823)   ACPI:  DSDT  0xf0800  000F2  (v02  BHYVE    BVDSDT      00000001  INTL  20130823)   ACPI:  FACS  0xf0780  00040   Assertion  failed:  st  ==  AE_OK  (../../drivers/hpet.cc:  hpet_init:  171)   Aborted