copy / v86

x86 PC emulator and x86-to-wasm JIT, running in the browser
https://copy.sh/v86/
BSD 2-Clause "Simplified" License
19.53k stars 1.35k forks source link

Exact configuration and source for the archlinux image on the website #976

Closed farhan-ct closed 7 months ago

farhan-ct commented 7 months ago

Hi. I would like to know where I can find the build files and configuration for the archlinux.

Could someone please guide me?

I am unable to get the state size smaller even after following the instructions from here (issue:813)

@copy

copy commented 7 months ago

Here you go: https://github.com/copy/v86/blob/master/docs/archlinux.md

It's not quite up-to-date, but there aren't any significant changes.

You may want to check that there aren't any unexpected processes running, journald is disabled, nothing writes to disk too much, and most importantly, init_on_free is enabled.

farhan-ct commented 7 months ago

Hi, I followed the same instructions that you mentioned above, earlier & again now but I still couldn't get the size down. I am still surprised at how the arch loads in the demo with ~12MB, including nodejs (npm excluded ofcourse) that loads almost instantly.

I tried various builds but using tiny, alpine, buildroot, etc but none of trials were small sized + as responsive as the one in arch demo.

I would love to look/access the exact config/scripts that were used to build the https://copy.sh/v86/?profile=archlinux

@copy

copy commented 7 months ago

The exact scripts are here: https://github.com/copy/v86/blob/master/docs/archlinux.md

~12MB, including nodejs

Node isn't included in the 12MB. 12MB is just the state image. The 9p filesystem is 5GB, but it's loaded on demand.

If your zstd-compressed state image is significantly larger than 12MB, check the following:

farhan-ct commented 6 months ago

Hi @copy Firstly, you're amazing.

Secondly, here are the things that I missed due to which my state file was wayy larger.

  1. init_on_free=1 was what I was providing, changing it to on worked.
  2. I had wayyy more active kernal modules, I blacklisted all the unnecessary ones
  3. I added init_on_free=on init_on_alloc=on to the append section in grub config, not sure if that helped too, but hope it did.
  4. Masked the udevd & udev-trigger services.

My final state file is ~18MB. I didn't move to openrc from systemd yet but hoping that would give me 3-4MB lesser size. Let's see!

I see that you suggested using Tailscale for a full-fledged networking support (to use web servers inside vm), are there any alternatives to it?

copy commented 6 months ago

I see that you suggested using Tailscale for a full-fledged networking support (to use web servers inside vm), are there any alternatives to it?

At the moment the only option is to run your own relay: https://github.com/benjamincburns/websockproxy

farhan-ct commented 6 months ago

@copy

Hi

I observed that the time to just print npm version (time npm -v) in the arch demo takes about 1 minute and about 30-40 seconds from the second time. I uploaded a v86 node version to the vm and tested it.

Using the exact same node in the arch that I generated, is taking me double the time, i.e: 2 minutes consistently.

Could you please provide suggestions to improve the IO speed or let me know if I am missing anything?

Thank you!!

edwillard commented 6 months ago

@farhan-ct, I think you might be experiencing an issue with the timer resolution in your browser if you are comparing speed between https://copy.sh/v86/ and a version running on localhost: https://github.com/copy/v86/issues/797

farhan-ct commented 6 months ago

@edwillard I am not running it on localhost right now but still the same issue. So I went ahead and tried alpine.

Also, you mentioned about npm run build in #797 with resolution time information. Could you provide more details to it?

I have a setup with alpine 3.19 standard, running on v86. I automated the image building with my requirements using packer (like copy did it with arch), without the 9pfs though.

What I am looking for is,

  1. improving node, npm performance on it. Installing a npm package even from cache takes about 2-3 minutes, but I don't understand why and not sure what should do to improve this stuff.
  2. Based on what I explored so far, I didn't find a way to use kernel hooks to mount 9p before/during boot for alpine's initramdisk maker mkinitfs.
copy commented 6 months ago

improving node, npm performance on it. Installing a npm package even from cache takes about 2-3 minutes, but I don't understand why and not sure what should do to improve this stuff.

You want to add the following headers and serve your website over https (localhost counts as https even if running on http):

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

On Firefox, you may want to check that privacy.resistFingerprinting is set to false. We're looking for a better fix in #797.

Based on what I explored so far, I didn't find a way to use kernel hooks to mount 9p before/during boot for alpine's initramdisk maker mkinitfs.

I'm also interested in this, let me know if you find a way.

farhan-ct commented 6 months ago

I am using chrome right now.

Installing a npm package even from cache

Just to be clear here, the cache I mentioned here is npm cache and not the browser cache

Will try out the headers and update here.

SuperMaxusa commented 6 months ago

2. Based on what I explored so far, I didn't find a way to use kernel hooks to mount 9p before/during boot for alpine's initramdisk maker mkinitfs.

I tried adding root=host9p rootfstype=9p (with added 9p modules) but no luck. If I understand correctly, Alpine Linux init uses nlplug-findfs to mount root, is there anything that can be done in this direction?

edwillard commented 6 months ago

@farhan-ct, sure I can provide more details. I use npm run build on a fresh CRA app as a sort of benchmark that I can use while working on improving performance. What exactly are you curious about?

I found Arch (specifically the "non-official" 32-bit version maintained by the community) to be too limited to serve as a good candidate for Node / NPM usage. The absence of the newest versions for both packages (along with others) tends to cause numerous bugs during my tests. I tried working around those issues for a while then switched to Alpine which works much better since it has the latest packages.

So far the biggest single performance boost has been to switch from webpack and Rollup (which lacks 32-bit support anyway) to esbuild. Using esbuild instead of webpack in the CRA app benchmark results in a build speedup of 10x to 15x. There are of course caveats that go along with that due to esbuild being newer with somewhat different goals but the gains are impossible to ignore.

In general v86 is slower than a typical VM (understandable as it runs in the browser) so I try to precompute as much as possible (like installing NPM packages) using QEMU then use the resulting image file in v86.

Only having 32-bit support (beyond thankful to have it though) unfortunately closes off a lot of possibilities for better JavaScript tooling speed because more and more of the latest tooling (such as Bun, Deno, Rollup, SWC, and Turbo) only supports 64-bit and largely says they will never support 32-bit architectures (because they consider it obsolete).

  1. improving node, npm performance on it. Installing a npm package even from cache takes about 2-3 minutes, but I don't understand why and not sure what should do to improve this stuff.

My focus is within the same area, aiming to have something similar in concept to projects like RunKit, WebContainers and WebVM but fully open source and able to be run locally (none of the three meet these criteria).

  1. Based on what I explored so far, I didn't find a way to use kernel hooks to mount 9p before/during boot for alpine's initramdisk maker mkinitfs.

I would appreciate this too if you (or anyone else) figure it out.

farhan-ct commented 6 months ago

@edwillard Thanks a lot for the detailed information.

I went through the same approach of setting up packages in qemu during image generation itself. I addced them to npm cache to try and avoid going to the internet as much as possible. It's working but like I mentioned, wayy slower. Since npm is not being used this way by many right now, I would like to discuss and compare our times to determine a standard expected performance.

I had issues with rollup on 32-bit but it worked fine after using overrides in package.json with @rollup/wasm-node package. I am hoping that I would find some way similar to this while dealing with deno, turbo, etc.

My focus is within the same area, aiming to have something similar in concept to projects like RunKit, WebContainers and WebVM but fully open source and able to be run locally (none of the three meet these criteria).

I wish they were open-source :(

farhan-ct commented 6 months ago

@SuperMaxusa adding those args to kernel cmd will work fine once we mount 9p with the name host9p.

Alpine Linux init uses nlplug-findfs to mount root,

Thanks for sharing this, I'll see if I can figure out something from it.

Right now I am leaving 9p aside and using some wrappers around the vm to get file related things done.

SuperMaxusa commented 6 months ago

adding those args to kernel cmd will work fine once we mount 9p with the name host9p.

You right, now I have some success, seems that needed generate initrd with 9p module:

mkinitfs -F "ata base ide scsi virtio ext4 9p" $(cat /usr/share/kernel/<virt or lts>/kernel.release)

...then add this to cmdline:

root=host9p rootfstype=9p rootflags=trans=virtio,cache=loose

Actually I want create Docker container like tools/docker/debian/Dockerfile for #989, but there is a problem make this more stable.

alpine

MesaBlack commented 6 months ago

Why does this keep appearing in my inbox even if I set it as "done"?

farhan-ct commented 6 months ago

@SuperMaxusa that's amazing!

I did the same but was unsuccessful, let me give it a try once again later. Also, are the v86's create_file and read_file methods working now with 9pfs mounted?

Actually I want create Docker container

I created a packer template along with a script. Does everything fine. Let me know if you want me to share it with you.

edwillard commented 5 months ago

@MesaBlack just click the "Unsubscribe" button on the side of the page.

SuperMaxusa commented 5 months ago

Also, are the v86's create_file and read_file methods working now with 9pfs mounted?

Yes, almost the same as in arch profile. So far, I am having problem is that for some reason my root fs is mounted as readonly on guest, when kernel cmdline have rw flag.

9pfs

farhan-ct commented 5 months ago

@SuperMaxusa nice!

Did you try appending rw kernel option in bootentry itself (/boot/extlinux.conf) to see if it works? Ensure that rw should be visible in the output for cat /proc/cmdline

SuperMaxusa commented 5 months ago

@farhan-ct thanks for advices, I finished my Dockerfile and left here, if you interested: https://github.com/copy/v86/discussions/989#discussioncomment-8622159

Theoretically, this can be made without Docker, by using chroot (perfect solution - alpine-make-rootfs, but it's not support i686) or just by VM image (like for Arch: Creating the 9p filesystem, manually or by Packer script, as you suggest), but this way with container easier, I think

farhan-ct commented 5 months ago

@SuperMaxusa Really amazing work :clap:

Thanks a lot for sharing the docker file too.

farhan-ct commented 4 months ago

Hi @copy

The demo version of the arch is very very stable and reliable, when installing/testing various applications and stuff. Though the other distributions I build are also stable enough, I really wish I could build the exact same demo version of arch, with openrc and all the installed/created files in it.

Is it possible that we could get the exact configuration scripts (other than the ones given here in the repo), that includes every customization made to the demo version of arch?

copy commented 4 months ago

@farhan-ct Here's the provision script: https://gist.github.com/copy/7cb9d1ae357616fd01968c361dea5f6b

It's probably broken now, feel free to send me fixes.

farhan-ct commented 4 months ago

Hey @copy

Thank you so much for sharing the script here :smiley:

SuperMaxusa commented 4 months ago

It's probably broken now, feel free to send me fixes.

Probably it's a problem in my environment settings (tested on archlinux32 2023.03.02), but pacman couldn't verify package integrity:

checking package integrity...
:: File /mnt/var/cache/pacman/pkg/< ... >.tar.zst is corrupted (invalid or corrupted package (PGP signature)).
...
Do you want to delete it? [Y/n] n
Errors occurred, no packages were upgraded.

My temporary workaround is updating archlinux32-keyring (or setting "SigLevel = Never" in pacman.conf), as done in archlinux.md: https://github.com/copy/v86/blob/2bcfa9d8c427f5b1d395b8ff931751550ce25e42/docs/archlinux.md?plain=1#L127-L131

And some AUR packages are failed to build:

--- a/provision.sh
+++ b/provision.sh
@@ -377,7 +377,7 @@ pacman -S --noconfirm vi vim net-tools binutils tcsh zsh strace ncdu htop sed bc
         curl wget ntp nodejs nano perl nasm yasm ocaml dhcpcd python3 python-pip gdb clang llvm13-libs \
         alsa-utils inetutils bind-tools lua lynx w3m calc tcpdump sysstat gnu-netcat moreutils git lsof rlwrap \
         whois openssh nmap jre-openjdk-headless mg perf fbset fbdump fbv unzip which docker docker-compose podman podman-compose \
-        irssi expect neofetch unrealircd libsodium ngircd
+        irssi expect neofetch unrealircd libsodium ngircd meson pkgconf

 mount -t cgroup2 cgroup2 /sys/fs/cgroup
 dockerd &
@@ -426,7 +426,7 @@ echo 'CFLAGS="${CFLAGS} -fcommon"' >> /etc/makepkg.conf
 mkdir /.cache && chown nobody /.cache
 pacman -R --noconfirm --assume-installed=systemd-sysvcompat systemd-sysvcompat
 #cd /tmp/ && git clone https://aur.archlinux.org/yay.git && chown -R nobody yay && cd yay && sudo -u nobody makepkg --ignorearch && pacman -U --noconfirm *.pkg.*
-cd /tmp/ && git clone https://aur.archlinux.org/sysvinit.git && chown -R nobody sysvinit && cd sysvinit && sudo -u nobody makepkg --ignorearch && pacman -U --noconfirm *.pkg.*
+cd /tmp/ && git clone https://aur.archlinux.org/sysvinit.git && chown -R nobody sysvinit && cd sysvinit && sudo -u nobody makepkg --ignorearch --skippgpcheck && pacman -U --noconfirm *.pkg.*
 cd /tmp/ && git clone https://aur.archlinux.org/openrc-sysvinit.git && chown -R nobody openrc-sysvinit && cd openrc-sysvinit && sudo -u nobody makepkg --ignorearch && pacman -U --noconfirm *.pkg.*
 cd /tmp/ && git clone https://aur.archlinux.org/openrc.git && chown -R nobody openrc && cd openrc && sudo -u nobody makepkg --ignorearch && pacman -U --noconfirm *.pkg.*
 #cd /tmp/ && git clone https://aur.archlinux.org/dbus-openrc.git && chown -R nobody dbus-openrc && cd dbus-openrc && sudo -u nobody makepkg --ignorearch && pacman -U --noconfirm *.pkg.*
farhan-ct commented 4 months ago

@SuperMaxusa After the above code fixes, were you able to build the arch image successfully?

I've been getting errors during pacstap that says there are conflicts with mkinitcpio and systemd. Sometimes where I somehow bypass the issue, the issue keeps re-appearing at some other package installation :(

SuperMaxusa commented 4 months ago

After the above code fixes, were you able to build the arch image successfully?

These patches only affects for building openrc, so without them you can boot only with systemd properly.

errors during pacstap that says there are conflicts with mkinitcpio and systemd.

And on installation via docs/archlinux.md, do these errors also appear?

farhan-ct commented 4 months ago

And on installation via docs/archlinux.md, do these errors also appear?

Sometimes yes sometimes no and that's weird.

Just a very simple step of booting the iso with qemu, creating the partition and trying to pacstrap is straight away giving me an error that says there's a conflict between mkinitcpio and systemd.

SuperMaxusa commented 4 months ago

Sometimes yes sometimes no and that's weird.

Have you any logs of pacstrap with this error? (tip: use a ssh for easy fetching console log) https://github.com/copy/v86/blob/4efc3714b438ea36efa72ceb065a104f47e87583/docs/archlinux.md?plain=1#L476-L477 https://wiki.archlinux.org/title/QEMU#QEMU's_port_forwarding https://wiki.archlinux.org/title/Install_Arch_Linux_via_SSH