Category Archives: Uncategorized

Running MacOS on Ubuntu – Sosumi

Ubuntu has a Snap package that can run MacOS on KVM. It is a pre-built script that bring out the MacOS up and running automatically.

There are plenty of notes on the web, this passage is just my personal notes.

Pre-Requisite – install KVM utils and assign a common user to KVM group

sudo apt-get install cpu-checker qemu-utils
sudo usermod -a -G kvm,libvirt jimmy
sudo chown root:kvm /dev/kvm
sudo chmod 666 /dev/kvm

Install Sosumi

sudo snap install sosumi --edge

Adjust the default CPU cores, RAM size and disk image size

# Try to launch the VM as a normal user
# immediately close the VM at Clover
# go to snap folder and edit the launch file
cd ~/snap/sosumi/common
nano launch
#modify -m 8G / -smp 8,core=4
qemu-img resize macos.qcow2 +20G

Launch the VM and carry out the standard installation process.


Some notes about NewSQL – CockroachDB

I have done some research on CockroachDB recently which make me understand a new class of database called NewSQL.

NewSQL has a few key features which is very attractive, especially we are SQL developers. Corresponding solution in GCP CloudSpanner and AWS Aurora.
1. ACID compliance, but with global locking trade-off
2. Auto-recovery and auto-rebalance under node failure
3. Global Distributed database with localized access of data
4. No phantom read, which maintain global consistency

It sounds pretty attractive in the first view. However, it must be carefully designed in order to enjoy the benefits. Let’s look at how it works first.

0. Define your database cluster topology, which you may define the running instance with Tags, like Region, AZ(AWS Terms), Data Center and Country. These information is useful for locating the table data and index.

1. Each Table will be partitioned by field in columns. The partitioning of data can be done with ENUM for discrete data or range for continous data.

2. Additional Sparse Indexes (Non-primary index) must also be designed with Partition in mind, the best design mechanism is to share the partition key with table data, and add additional fields for improve searching

3. Each Index or Data partition will map to a list of hints which will determine the location that piece of data is stored. CockroachDB will determine the final location by honoring the hints first. However, if there is no living instance which satisfies the hints, it will just pick one node that can spread across the globe.

4. CockroachDB maintains a network latency matrix internally, which keep track of the performance between any 2 nodes. It is a important input to CockroachDB to determine which data partition to update or to read.

5. Each Slice of data, which has a few replica among the living nodes, will elect a “leaseholder” based on table definition hints and usage statistic periodically. All read-write operation MUST go through the leaseholder in order to achieve global consistency and data locking. Since leaseholder is just a pointer among the partition replica, shifting leaseholder is a cheap operation and can change frequently (~10sec) to cope with the shape of traffic.

6. For READ table, the detail mechanism is shown here. The key take away is avoid global query and make the query local, for example, include part of the partition as you searching criterion. The query will route to the leaseholder to process, and the primary concern is the latency between the gateway node and the leaseholder. The performance is excellent in case that everything happens locally.

7. For WRITE table, the detail mechanism is shown here. The key performance trick is the location of majority update. For example, given a 3 replica environment, the leaseholder has to commit 2 out of 3 in order to declare the update is successful, therefore, the delay is related to the 2nd closest replica network latency to the leaseholder.

8. In case of node failure and recovery needed, CockroachDB is doing a great job. It will regenerate the replica at a node that trying to satisfy the hints. Since there are live replica, the performance hits are minimal, and it can self heal when a new instance comes online

9. The DDL and partition configuration can be changed by DDL, Cockroach will help to migrate the slice based on partition hints.

Base on the implementation above, there are some pitfalls which you may keep an eye on.

1. Database topology designs may require some regions clustered together and try to place data locally.

2. Data and Index has to be partitioned seperately, we should put them as closed as possible to make read-write operation localized.

3. Data is committed when majority of partitions report committed to the Leaseholder. It means you need to place the partition wisely and strike a balance between 1) majority of partitions are placed on node which are closed to each others. 2) data must be placed wide apart so that it can archieve Regional replication

4. Average latency measurement
Same City – ~5ms (InterDC dedicated line / AZ)
Same Country, Inter city – ~20ms
Cross Country, e.g. HK-SG – ~50ms
Cross Continenet, e.g. Asia vs EMEA vs US – ~200ms

Base on the latencies, we should be able to precisely predict the expected performance of individual query or operation.


Finally get my Hackintosh (High Sierra) working!!!!!!

After serveral years of studies and trial, I finally get a Hackintosh working with spared parts. I know the cost for a proper Mac Book Pro is far below my time cost, but it is really a great learning experience for me.

Before I start, here is my hardware list, I just purchase 2nd parts, with my old parts and my brother-in-law decomissioned parts.

Intel E3-1275 (Sandy Bridge)
Biostar B75S3E (B75 mATX board)
Asus GT1030 2GB
Crucial BX500 240G SSD

Basically it covers the following major steps. I use Hackintosh Zone High Sierra for installation.
1. Setup the BIOS according to the Hackintosh guide
2. Setup the Hackintosh with relevant settings
3. Upgarde to 10.13.6 (3 Updates)
4. Use Clover Configurator to setup the SMIBIOS, prepare for Web Drivers and enable SSDT flags for power management
5. Use Multibeast to install a bunch of Drivers
6. Install Nvidia Web Driver to enable the graphics acceleration of GT1030
7. Convert APFS and configure mount point noatime to preserve SSD wearing
8. Homebrew
9. Enjoy!!

The detail procedure is as followed

2. Setup the Hackintosh with relevant settings
I have done the following settings in the configuration for Installing the base MacOS
a. Enable Network
b. Enable USB Support for Intel 7/8/9 family USB
c. Disable NullCPUPowerManagement (enable by Default)

4. Use Clover Configurator to setup the SMIBIOS, prepare for Web Drivers and enable SSDT flags for power management
Primarily, this settings is for SSDT to enable power management in Clover Configurator. My Settings are as followed.

5. Use Multibeast to install a bunch of Drivers.
Multibeast is used to install a bunch of drivers to fit my hardware. The list is as followed.

6. Nvidia Web Drivers
Nvidia Web Driver is provided by nVidia (not Apple) to drive the latest GeForce series graphics card. Unfortunate, it supports only up to High Sierra, no Majove or Catalina. We could download here. It has to match with your MacOS version, including sub-version and patch level

7. APFS and noatime mount options
APFS is the latest file system of MacOS which support SSD Trim command. In the Niresh Hackintosh Disc, it doesn’t come with the drivers, which I cannot install MacOS on my SSD. Therefore, I need to make conversion after installation. Luckily, the installation is very simple.
1. Boot into recovery mode
2. Unmount the Disk
3. Edit => Convert to APFS
In unix file system, it has a function named atime, which will log the time for every file access. It is no big deal in Magnetic hard disk, however, it is a matter for SSD as it hugely increase the wearing of SSD. Furthermore, because it saves a write operation, the disk will also perform slightly faster, especially for compiling program
2. Reboot, check with “mount”

8. Homebrew,
/usr/bin/ruby -e “$(curl -fsSL”

There are some pitfall which I have encountered, the best recommendation is still strictly follow the tonymacx86 purchase list, and don’t even derivate a single model from it.

The pitfall are as followed.

1. Sandy Bridge CPU E3 1275 iGPU is HD P3000 which has a different hardware device ID with a standard Sandy Bridge HD3000. Inject Intel and FakeIntelGPU may work, but fail due to point 2
2. Mix of Sandy Bridge CPU + Ivy Bridge Mainboard will cause issue. Apple treats mainboard as the platform, which you need to match up with CPU and iGPU by configuration SMIBIOS. I cannot get the iGPU working and need to use a GT1030 card
3. MacOS is not happy with nVidia Maxwell and Pascal GPU out of the box, that’s the 9xx and 10xx family. They cannot run on Mojave OR Catalina right now. For High Sierra, nVidia has provide official Drivers named Nvidia Web Driver, You need to pick the right version against your current Mac Version, 10.13.0 has different driver from 10.13.6.
4. Picking a Kelper Nvidia GPU is a MUST for Mojave or Catalina. Comments from forum suggest RX570. I am wondering if a RX460 from China, which is the salvage of Crypto Mining Machine is a good deal
4. You MUST go to Recovery Mode and UNMOUNT the system volume to convert the primary partition to APFS
5. Don’t need to install the NullCPUManagement.kext. The AppleIntelCPUPowerManagement.kext should be fine and working with the Clover C-State parameters


WebDAV Server on Apache

MS Office has native support of WebDAV, you can quickly setup a WebDAV server in Apache for testing, instead of spinning up the fully functioning SharePoint Server.

Here is the quick settings for setting up a Apache WebDAV server.

a2enmod dav
a2enmod dav_fs

And then add a new site in /etc/apache2/sites-available/ as followed.

<VirtualHost *:80>
        ServerAdmin [email protected]
        DocumentRoot /var/www/webdav

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        <Directory />
                Options FollowSymLinks
                AllowOverride None
        <Directory /var/www/webdav/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all

        Alias /svn /var/www/webdav/svn
        <Location /svn>
                DAV On

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

Meltdown and Spectre affects you?

These few vulnerabilities claims to be the most widely spread potential security issue in the last few years. M$ and Linux has provided corresponding patch in fixing it. However, the fix is not free, it usually counts for ~10% of performance reduction, the effect may be magnified in IO intensive usage.

I found my machine compiling our source slower than before by slim margin (~30 sec difference) and try to dig out the reason of the slowness.

There are ways to stop the patch in either Linux and Windows.



Honestly, I am not a terrorist nor government officers, given my notebook is sitting behind the company firewall, I am safe to reclaim my PC performance. You may check that out too, but do at your own risk.

Self Reflection on IT company structure

Interesting stories to share

I am imagining how’s CX handle this incident internally and how to avoid. CX “supposes” to have good system and control, every thing should have check and balance. Who should be responsible for this?????

Imagining there are standard in-house software development structure, different teams would have claims as followed.
Business User: IT is shit, making rubbish, charge me so much (transfer pricing). Fire them all!!! (Yes, they did, I think they deserve)

Business Analyst: I have already documented the user requirement and expectation, modifying the ticket class is not a valid use case, it should be security team responsibility, definitely not my fault.

Security Team: My responsibility is using the million dollars app scanner, network scanner, IDS (Intrusion detection system) and XYZXYZ (lots of buzz words) to do regular checking, I just know scanning, but nothing about business.

Dev Team: Such validation is not written on the specification, it makes no sense for me to implement it.

Micro-service Dev Team: This logic suppose to be validated by XXX Team, it is not my responsibility to re-validate and I am NOT TOLD TO DO SO.

Architect: (Playing fingers) It is business use case, not on my dish.

QA: BA, pls confirm(The requirement). DB Team, pls confirm. Dev Team, pls confirm. I don’t know who should I ask to confirm. I am just a test plan executor. I can be BA if I know the business well, I could be a programmer if I can code test case. This incident is definitely not my issue.

DB Team: I only deal with DB Structure and constraint.

Support / Customer Service: The phones are all ringing, the customer has fxxked us so hard. Dev Team, pls advice. BA, pls advice. DB Team, pls advice. Architect Team, pls advice.

Internal Audit Team: I am just a Business Man, knowing how to present and tender external party for auditing. I don’t really know how the system works, how could I audit to this level?

The management may claim everyone is responsible, but eventually it means no one is responsible.

It is ironic that simple script kiddie technique can break several million dollars project, and destroy the brand. I don’t think this is the only bug on the system or any other multi billions dollars organization, from banks, to hospitals, to varies online providers.

Disclaimer: Any similarity is mere coincidence

Build my Fusion Drive with LVM-Cache

LVM Cache is a interesting feature that I saw some web review on the web. It can speed up traditional mechanical disk with a cache partition on SSD. Essentially the concept is the same as Windows Readyboost or Fusion Drive, which the caching is controlled by firmware.

Resize the SSD

e2fsck /dev/sda1

resize2fs /dev/sda1 100000M

Use GParted to adjust the partition size

Mark Data(sdb1), Cache(sda2) and Meta(sda3) as LVM PV

sudo pvcreate /dev/sdb1 

sudo pvcreate /dev/sda2

sudo pvcreate /dev/sda3

Create Volume Group with the PVs

# Must spare some space
sudo vgcreate VG /dev/sdb1 /dev/sda2 /dev/sda3

sudo lvcreate -l 95%FREE -n data VG /dev/sdb1

sudo lvcreate -l 95%FREE -n cache VG /dev/sda2

sudo lvcreate -l 95%FREE -n meta VG /dev/sda3

Create Cache Pool and config cache mode as Writeback (improve read / write performance)

sudo lvconvert --type cache-pool --poolmetadata VG/meta VG/cache

sudo lvconvert --type cache --cachepool VG/cache --cachemode writeback VG/data

In case you are unlucky that u encounter the cache corruption. You need to execute the following commands to rebuild the cache

vgchange -a y VG
lvchange -a y VG/data
lvconvert --repair VG/data


Nginx per user directory

It is common for hosting company to share the same host and create per user directory, so that every user can browse with the following url.


It can be achieved easily by nginx configuration.

sudo vi /etc/nginx/sites-available/default

Add the following code under “server” section

location ~ ^/~(.+?)(/.*)?$ {
alias /home/$1/www$2;
autoindex on;

Add the user to www-data group

sudo usermod -aG www-data $USER

Change the www directory under user home to mod 755, so that others can access the folder with execute right

chown 755 -R ~/www/

Some notes

sshpass -p ‘*******’ rsync -avzh -e ‘ssh -p 40022’ XXXXFILEXXXX [email protected]:Downloads/

# Search for my current IP
dig +short

We can use openssl command to verify the connection.

openssl s_client -connect -cert cont-public.cert -key cont.key

In order to create a java keystore, we have to create a P12 keystore first and then use keytool to import as Java Keystore. The commands are as followed.

openssl pkcs12 -export -in cont-public.cert -inkey cont.key -out cont20161209.p12 -name initiator
keytool -importkeystore -destkeystore initiator.jks -srckeystore cont20161209.p12 -srcstoretype PKCS12 -alias initiator

Finally, we “Trust” the public certificates

keytool -import -trustcacerts -file ullink.cert -alias ullink -keystore initiator.jks

And we can verify with the following command

keytool -list -v -keystore initiator.jks