Archive for September, 2014

How to install ReiserFS in CentOS?

These are the steps to install ReiserFS in CentOS (currently it worked for 6.4):

Add the ElRepo repository to your YUM configuration (follow the directions at the "Get Started" section of the ElRepo site)

rpm –import

rpm -Uvh

Run "yum update" to pull in repo metadata about the available packages.

Run "yum install kmod-reiserfs reiserfs-utils"

This will install both the kernel module and the needed userland utility programs (mount, mkfs, fsck, etc).

BTRFS utility result in kernel crash

I have installed Qubes OS, which comes installed with BTRFS filesystem.

Have it dual boot with CentOS (by installing CentOS first, and Qubes will autodetect that).

To debug a infinite loop in Qubes, I have it bootup in CentOS, which have kdump enabled (as below):

And after "sudo yum install btrfs-prog", and then using "mount /dev/sda6 /mnt" where /dev/sda6 is a BTRFS formatted Qubes partition, it immediately result in kdump generated crash.

KERNEL: /boot/vmlinux
DATE: Sun Sep 14 16:27:27 2014
UPTIME: 00:16:21
LOAD AVERAGE: 0.08, 0.09, 0.08
TASKS: 395
NODENAME: tthtlchp
RELEASE: 2.6.32-358.el6.x86_64
VERSION: #1 SMP Fri Feb 22 00:31:26 UTC 2013
MACHINE: x86_64 (2294 Mhz)
PANIC: "Oops: 0000 [#1] SMP " (check log for details)
PID: 4430
COMMAND: "mount"
TASK: ffff88023e317540 [THREAD_INFO: ffff880236520000]
CPU: 0

crash> bt
PID: 4430 TASK: ffff88023e317540 CPU: 0 COMMAND: "mount"
#0 [ffff880236521820] machine_kexec at ffffffff81035b7b
#1 [ffff880236521880] crash_kexec at ffffffff810c0db2
#2 [ffff880236521950] oops_end at ffffffff815111d0
#3 [ffff880236521980] no_context at ffffffff81046bfb
#4 [ffff8802365219d0] __bad_area_nosemaphore at ffffffff81046e85
#5 [ffff880236521a20] bad_area at ffffffff81046fae
#6 [ffff880236521a50] __do_page_fault at ffffffff81047760
#7 [ffff880236521b70] do_page_fault at ffffffff8151311e
#8 [ffff880236521ba0] page_fault at ffffffff815104d5
[exception RIP: selinux_set_mnt_opts+63]
RIP: ffffffff8122a16f RSP: ffff880236521c58 RFLAGS: 00010292
RAX: ffffffffa079da73 RBX: ffff880236521ce8 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff880236521ce8 RDI: ffff880258c18000
RBP: ffff880236521cd8 R8: 0000000000000000 R9: 000000000000001d
R10: 0000000000000003 R11: 0000000000031d84 R12: ffff880258c18000
R13: 0000000000000000 R14: ffff880258c18000 R15: 0000000000000000
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
#9 [ffff880236521ce0] superblock_doinit at ffffffff8122a711
#10 [ffff880236521d30] selinux_sb_kern_mount at ffffffff8122a7c9
#11 [ffff880236521df0] security_sb_kern_mount at ffffffff8121b8b6
#12 [ffff880236521e00] vfs_kern_mount at ffffffff81183847
#13 [ffff880236521e50] do_kern_mount at ffffffff811839c2
#14 [ffff880236521ea0] do_mount at ffffffff811a3c12
#15 [ffff880236521f20] sys_mount at ffffffff811a42a0
#16 [ffff880236521f80] system_call_fastpath at ffffffff8100b072
RIP: 00007f582966109a RSP: 00007ffffb177f88 RFLAGS: 00010206
RAX: 00000000000000a5 RBX: ffffffff8100b072 RCX: ffffffffc0ed0000
RDX: 00007f582a9a4640 RSI: 00007f582a99b850 RDI: 00007f582a99b830
RBP: 00000000c0ed0000 R8: 0000000000000000 R9: 00007f582a9a4640
R10: ffffffffc0ed0000 R11: 0000000000000206 R12: 0000000000000000
R13: 00007f582a99b850 R14: 00007f582a99b830 R15: 0000000000000000
ORIG_RAX: 00000000000000a5 CS: 0033 SS: 002b

Above indicated crash at selinux_set_mnt_opts:

crash> dis selinux_set_mnt_opts+63 100
0xffffffff8122a16f <selinux_set_mnt_opts+63>: mov 0x0(%r13),%rax
0xffffffff8122a173 <selinux_set_mnt_opts+67>: mov 0x68(%rax),%rax
0xffffffff8122a177 <selinux_set_mnt_opts+71>: mov 0x10(%rax),%rax
0xffffffff8122a17b <selinux_set_mnt_opts+75>: mov 0x230(%rax),%rax
0xffffffff8122a182 <selinux_set_mnt_opts+82>: mov %rax,-0x58(%rbp)
0xffffffff8122a186 <selinux_set_mnt_opts+86>: lea 0x30(%r13),%rax
0xffffffff8122a18a <selinux_set_mnt_opts+90>: mov (%rsi),%rbx
0xffffffff8122a18d <selinux_set_mnt_opts+93>: mov 0x8(%rsi),%r15
0xffffffff8122a191 <selinux_set_mnt_opts+97>: mov 0x10(%rsi),%esi
0xffffffff8122a194 <selinux_set_mnt_opts+100>: mov %rax,%rdi
0xffffffff8122a197 <selinux_set_mnt_opts+103>: mov %rax,-0x50(%rbp)
0xffffffff8122a19b <selinux_set_mnt_opts+107>: mov %esi,-0x44(%rbp)

where %r13 is completely NULL.

A "dmesg" command in crash show the place of crash as well:

TECH PREVIEW: btrfs may not be fully supported.
Please review provided documentation for limitations.
Btrfs loaded
device label qubes_dom0 devid 1 transid 154 /dev/sda6
btrfs: disk space caching is enabled
BTRFS: couldn't mount because of unsupported optional features (40).
btrfs: open_ctree failed
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [] selinux_set_mnt_opts+0x3f/0x580
Oops: 0000 [#1] SMP
last sysfs file: /sys/devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/dev
Modules linked in: btrfs(T) zlib_deflate lzo_decompress lzo_compress libcrc32c fuse ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat xt_CHECKSUM iptable_mangle bridge autofs4 sunrpc 8021q garp stp llc cpufreq_ondemand acpi_cpufreq freq_table mperf ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 vhost_net macvtap macvlan tun kvm_intel kvm uinput arc4 hp_accel lis3lv02d input_polldev iwlwifi mac80211 cfg80211 rfkill r8169 mii sg uvcvideo videodev v4l2_compat_ioctl32 microcode i2c_i801 iTCO_wdt iTCO_vendor_support shpchp snd_hda_codec_hdmi snd_hda_codec_idt snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc xhci_hcd ext4 mbcache jbd2 sd_mod crc_t10dif sr_mod cdrom ahci i915 nouveau ttm drm_kms_helper drm i2c_algo_bit i2c_core mxm_wmi video output wmi dm_mirror dm_region_hash dm_log dm_mod [last unloaded: scsi_wait_scan]

Pid: 4430, comm: mount Tainted: G --------------- T 2.6.32-358.el6.x86_64 #1 Hewlett-Packard HP Pavilion dv6 Notebook PC/181B
RIP: 0010:[] [] selinux_set_mnt_opts+0x3f/0x580
RSP: 0018:ffff880236521c58 EFLAGS: 00010292
RAX: ffffffffa079da73 RBX: ffff880236521ce8 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffff880236521ce8 RDI: ffff880258c18000
RBP: ffff880236521cd8 R08: 0000000000000000 R09: 000000000000001d
R10: 0000000000000003 R11: 0000000000031d84 R12: ffff880258c18000
R13: 0000000000000000 R14: ffff880258c18000 R15: 0000000000000000
FS: 00007f582a38f7e0(0000) GS:ffff88002c200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000236600000 CR4: 00000000001407f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process mount (pid: 4430, threadinfo ffff880236520000, task ffff88023e317540)
ffff880256306400 0000000000000006 ffffffffa079da73 ffff880254be1c00
ffff880232de2530 ffff880258c2b5c0 ffff880258c18000 ffff880232de2000
0000000000000000 ffffffffffffffea ffff880236521cc8 ffff880236521ce8
Call Trace:
[] superblock_doinit+0x61/0xd0
[] ? deactivate_locked_super+0x5e/0x90
[] selinux_sb_kern_mount+0x49/0xd0
[] security_sb_kern_mount+0x16/0x20
[] vfs_kern_mount+0xa7/0x1b0
[] do_kern_mount+0x52/0x130
[] do_mount+0x2d2/0x8d0
[] ? strndup_user+0x64/0xc0
[] sys_mount+0x90/0xe0
[] system_call_fastpath+0x16/0x1b
Code: 00 00 65 48 8b 04 25 c0 cb 00 00 48 8b 80 48 06 00 00 49 89 fe 48 89 45 98 48 8b 47 30 4c 8b af c0 00 00 00 48 8b 00 48 89 45 90 8b 45 00 48 8b 40 68 48 8b 40 10 48 8b 80 30 02 00 00 48 89
RIP [] selinux_set_mnt_opts+0x3f/0x580
CR2: 0000000000000000

Searching for the btrfs-prog source code:

yumdb info btrfs-progs
Loaded plugins: fastestmirror, refresh-packagekit
checksum_data = 689790cd69d452ee13936f47a96f308d3ae876245477c523e37f5f0b195136db
checksum_type = sha256

The same package name was found.

After downloading the source, and using ctags to generate the tags file (or just “make tags” inside linux kernel untarred directory), and using vi to navigate the source code (using ctrl-]), the following code was identified:

static int superblock_doinit(struct super_block *sb, void *data)
int rc = 0;
char *options = data;
struct security_mnt_opts opts;


if (!data)
goto out;

BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);

rc = selinux_parse_opts_str(options, &opts);
if (rc)
goto out_err;

rc = selinux_set_mnt_opts(sb, &opts);

And according to Linux kernel calling convention (, %RDI is the first argument, (value is 0xffff880258c18000):

crash> x /100x 0xffff880258c18000
0xffff880258c18000: 0x58c18000 0xffff8802 0x58c18000 0xffff8802
0xffff880258c18010: 0x0000001d 0x00000000 0x00001000 0x00000000
0xffff880258c18020: 0x0000000c 0x00000000 0xffffffff 0x7fffffff
0xffff880258c18030: 0xa07ac8e0 0xffffffff 0xa0799080 0xffffffff
0xffff880258c18040: 0x81623040 0xffffffff 0x816230e0 0xffffffff
0xffff880258c18050: 0xa079cfc0 0xffffffff 0x20810000 0x00000000
0xffff880258c18060: 0x9123683e 0x00000000 0x00000000 0x00000000
0xffff880258c18070: 0x00000000 0x00000000 0x00000000 0x00000000

Oh….well, if u traverse down the binaries, it is possible to find out where is the fault (one of the following lines):

static int selinux_set_mnt_opts(struct super_block *sb,
struct security_mnt_opts *opts)
const struct cred *cred = current_cred();
int rc = 0, i;
struct superblock_security_struct *sbsec = sb->s_security;
const char *name = sb->s_type->name;
struct inode *inode = sbsec->sb->s_root->d_inode;
struct inode_security_struct *root_isec = inode->i_security;
u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
u32 defcontext_sid = 0;
char **mount_options = opts->mnt_opts;
int *flags = opts->mnt_opts_flags;
int num_opts = opts->num_mnt_opts;

How to write a simple OS based on outputting on UART

Writing to the UART offer an opportunity to receive and transmit out of the SoC, and therefore the simplest OS should be rather easy to write, simply by receiving and transmiting at the UART interface.

Below are the many examples of simple program written for some popular SoC:

Singpolyma » Writing a Simple OS Kernel — Part 7, Serial Port Driver

And a simple example to write to UART:

A complete program running on baremetal RPI writing Hello to UART is shown below:

And just in case u have got no money to buy any SoC board:

(which have a very good explanation of generating the binaries and laying it out in memories for the hardware simulator).

Exploring BTRFS filesystem internals (userspace + kernel)

Starting with a design documentation:
A good intro writeup:
Lots of technical details:
Elaborating on the COW mechanism in BTRFS (similar to ZFS):
Performance comparison:
Now some hands-on (a good system admin guide:
First create a file to be used as a virtual disk:
truncate -s 10G test-image.1
Next ensure the userspace tools for BTRFS are installed (I am on Ubuntu 12.04 LTS 64-bit):
sudo apt-get install btrfs-tools
Next make BTRFS filesystem on the virtual disk:
mkfs.btrfs test-image.1
Is the btrfs kernel module loaded?
lsmod|grep btr
No.   Check if it is compiled into the kernel?
grep -i btrfs /boot/config-3.8.0-29-generic 
Oh, yes, it is compiled into kernel as a loadable module.   So we shall load it:
sudo modprobe btrfs
Now use that to mount a BTRFS filesystem:
sudo mkdir  /btrfs
sudo mount test-image.1 /btrfs
sudo chmod 777 /btrfs/
Next we can start doing filesystem testing on /btrfs, using tools from below:
And to understand the filesystem internals, we can use ftrace, the sequence of operation are captured essentially as follows:
sudo mkdir /debug
sudo mount -t debugfs nodev /debug
echo 0 >/debug/tracing/tracing_on
echo ‘btrfs_*’ ‘journal_*’ > /debug/tracing/set_ftrace_filter
cat /debug/tracing/enabled_functions 
We can see many BTRFS functions which is partially listed here:
btrfs_create_qgroup [btrfs] (1)
btrfs_remove_qgroup [btrfs] (1)
btrfs_limit_qgroup [btrfs] (1)
btrfs_qgroup_record_ref [btrfs] (1)
btrfs_qgroup_account_ref [btrfs] (1)
btrfs_run_qgroups [btrfs] (1)
btrfs_qgroup_inherit [btrfs] (1)
btrfs_qgroup_reserve [btrfs] (1)
btrfs_qgroup_free [btrfs] (1)
btrfs_ioctl_send [btrfs] (1)
btrfs_init_dev_replace [btrfs] (1)
btrfs_after_dev_replace_commit [btrfs] (1)
btrfs_dev_replace_is_ongoing [btrfs] (1)
btrfs_dev_replace_lock [btrfs] (1)
btrfs_dev_replace_unlock [btrfs] (1)
btrfs_resume_dev_replace_async [btrfs] (1)
btrfs_dev_replace_finishing [btrfs] (1)
btrfs_dev_replace_suspend_for_unmount [btrfs] (1)
btrfs_dev_replace_cancel [btrfs] (1)
btrfs_dev_replace_status [btrfs] (1)
btrfs_dev_replace_kthread [btrfs] (1)
btrfs_dev_replace_start [btrfs] (1)
btrfs_run_dev_replace [btrfs] (1)
btrfs_set_acl [btrfs] (1)
btrfs_xattr_acl_set [btrfs] (1)
btrfs_get_acl [btrfs] (1)
btrfs_xattr_acl_get [btrfs] (1)
btrfs_init_acl [btrfs] (1)
btrfs_acl_chmod [btrfs] (1)
btrfs_interface_exit [btrfs] (1)
btrfs_find_highest_objectid [btrfs] (1)
echo function >/debug/tracing/current_tracer
echo 1 >/debug/tracing/tracing_on
ls -alR /btrfs
cp /bin/l* /btrfs
sleep 3
echo 0 >/debug/tracing/tracing_on
cat /debug/tracing/trace
And looking into the output:
  1.            <…>-7497  [003] ….  8751.390285: btrfs_real_readdir <-vfs_readdir
  2.            <…>-7497  [003] ….  8751.390286: btrfs_alloc_path <-btrfs_real_readdir
  3.            <…>-7497  [003] ….  8751.390288: btrfs_get_delayed_items <-btrfs_real_readdir
  4.            <…>-7497  [003] ….  8751.390288: btrfs_get_delayed_node <-btrfs_get_delayed_items
  5.            <…>-7497  [003] ….  8751.390289: btrfs_search_slot <-btrfs_real_readdir
And the full trace is here (for pid=7497):
And some of the userspace command features of BTRFS:

btrfs subvolume snapshot <source> [<dest>/]<name>
Create a writable snapshot of the subvolume <source> with
the name <name> in the <dest> directory.
btrfs subvolume delete <subvolume>
Delete the subvolume <subvolume>.
btrfs subvolume create [<dest>/]<name>
Create a subvolume in <dest> (or the current directory if
not passed).
btrfs subvolume list <path>
List the snapshot/subvolume of a filesystem.
btrfs subvolume find-new <path> <last_gen>
List the recently modified files in a filesystem.
btrfs filesystem defragment [-vcf] [-s start] [-l len] [-t size] <file>|<dir> [<file>|<dir>…]
Defragment a file or a directory.
btrfs subvolume set-default <id> <path>
Set the subvolume of the filesystem <path> which will be mounted
as default.
btrfs filesystem sync <path>
Force a sync on the filesystem <path>.
btrfs filesystem resize [+/-]<newsize>[gkm]|max <filesystem>
Resize the file system. If ‘max’ is passed, the filesystem
will occupe all available space on the device.
btrfs filesystem show [<uuid>|<label>]
Show the info of a btrfs filesystem. If no <uuid> or <label>
is passed, info of all the btrfs filesystem are shown.
btrfs filesystem df <path>
Show space usage information for a mount point
btrfs filesystem balance <path>
Balance the chunks across the device.
btrfs device scan [<device> [<device>..]
Scan all device for or the passed device for a btrfs
btrfs device add <dev> [<dev>..] <path>
Add a device to a filesystem.
btrfs device delete <dev> [<dev>..] <path>
Remove a device from a filesystem.

btrfs help|–help|-h
Show the help.

Btrfs Btrfs v0.19

And some other commands:
btrfsck btrfs-debug-tree
%d bloggers like this: