grantpt failed: Read-only file system

Probably one of those weird bug that I've encountered. This happened quite a few times for the past weeks. When I tried to launch a container I've just created, LXC showed me below error message on failling to allocate a pty.
$ sudo lxc-start -n foobar -F
lxc-start: console.c: lxc_console_create: 580 Read-only file system - failed to allocate a pty
lxc-start: start.c: lxc_init: 442 failed to create console
lxc-start: start.c: __lxc_start: 1124 failed to initialize the container
lxc-start: lxc_start.c: main: 344 The container failed to start.
lxc-start: lxc_start.c: main: 348 Additional information can be obtained by setting the --logfile and --logpriority options.

PTY? Is an abbreviation for pseudoterminal, according to Wikipedia,
"is a pair of pseudo-devices, one of which, the slave, emulates a real text terminal device, the other of which, the master, provides the means by which a terminal emulator process controls the slave."
To debug this, I've tried to launch a new Tmux session, which seemed to fail to do so. Suspecting that my Tmux session somehow corrupted, I tried to open Gnome Terminal and obtained this error message "grantpt failed: Read-only file system" as shown below.


Google's search results did suggest a temporary quick solution, which seemed to solve the issue. But still, question remain, what causing /dev/pts having the wrong permissions?
$ sudo mount -o remount,gid=5,mode=620 /dev/pts

Linux Containers (LXC) in Fedora 22 Rawhide - Part 3

Continue from Part 1 and Part 2. We'll discuss another issue caused by the default LXC installation in Fedora 22, which is no default bridge network created although one is set in the config file for each container.

Let's create a dummy container to view the default bridge network interface.
$ sudo lxc-create -t download -n foo -- -d centos -r 6 -a amd64
$ sudo cat /var/lib/lxc/foo/config | grep lxc.network.link
lxc.network.link = lxcbr0

However, as I mentioned earlier, the bridge interface lxcbr0 is not created by default. Note that bridge interface virbr0 was created due to libvirt installation.
$ ip link show | grep br0
6: virbr0:  mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
7: virbr0-nic:  mtu 1500 qdisc fq_codel master virbr0 state DOWN mode DEFAULT group default qlen 500

Or you can use the brctl command to show the available bridge interface. If you can't find the command, just install the bridge-utils package.
$ sudo dnf install bridge-utils
$ brctl show
bridge name     bridge id               STP enabled     interfaces
virbr0          8000.525400c28250       yes             virbr0-nic

Instead of changing the default lxc.network.link item in the container's config file every time we create a container, we can use two ways to resolve this issue. First, by overwrite the default network interface name. Second, is to create the lxcbr0 bridge interface manually.

For the first method, just overwrite the default network interface name.
$ sudo sed -i s/lxcbr0/virbr0/g /etc/lxc/default.conf 
$ cat /etc/lxc/default.conf | grep lxc.network.link
lxc.network.link = virbr0

The issue is such approach is that you'll share the same bridge network interface with libvirt which primary manages KVM (Kernel-based Virtual Machine). Thus, if you need additional customization, for example, like different IP range, is best to create a bridge network interface, which, leads us to the second method.

First, let's duplicate the XML file that define the default bridge network.
sudo cp /etc/libvirt/qemu/networks/default.xml /etc/libvirt/qemu/networks/lxcbr0.xml

Next, we need to generate a random UUID, Universal unique identifier and MAC, media access control address for our new bridge network interface named lxcbr0.

Generating UUID.
$ uuidgen
5df6886c-1dfe-44ca-8865-ebed91bd2646

Generating MAC address.
$ MACADDR="52:54:$(dd if=/dev/urandom count=1 2>/dev/null | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4/')"; echo $MACADDR
52:54:f0:ec:cb:a3

Update the lxcbr0.xml file we've just duplicated and add in both the UUID and MAC address to the file.

The final XML file as shown below:
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
  virsh net-edit lxcbr0
or other application using the libvirt API.
-->

<network>
  <name>lxcbr0</name>
  <uuid>5df6886c-1dfe-44ca-8865-ebed91bd2646</uuid>
  <forward mode='nat'/>
  <bridge name='lxcbr0' stp='on' delay='0'/>
  <mac address='52:54:f0:ec:cb:a3'/>
  <ip address='192.168.125.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.125.2' end='192.168.125.254'/>
    </dhcp>
  </ip>
</network>

Enable, auto start, and start the lxcbr0 bridge interface.
$ sudo virsh net-define /etc/libvirt/qemu/networks/lxcbr0.xml
$ sudo virsh net-autostart lxcbr0
$ sudo virsh net-start lxcbr0

Now both bridge interfaces were created and enabled. You can create any container using the default lxcbr0 bridge network interface.
$ brctl show
bridge name     bridge id               STP enabled     interfaces
lxcbr0          8000.00602f7e384b       yes             lxcbr0-nic
virbr0          8000.525400c28250       yes             veth1HV308
                                                        virbr0-nic

There are many other ways to create and setup a bridge network interface but the method of using virsh command is probably the easiest and fastest. All the necessary steps to configure DHCP through Dnsmasq has been automated. As observed through the Dnsmasq instance after we've started the lxcbr0 bridge network interface.
$ ps aux | grep [l]xcbr0
nobody    9443  0.0  0.0  20500  2424 ?        S    01:08   0:00 /sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/lxcbr0.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
root      9444  0.0  0.0  20472   208 ?        S    01:08   0:00  \_ /sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/lxcbr0.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper

Details of the lxcbro.conf file.
$ sudo cat /var/lib/libvirt/dnsmasq/lxcbr0.conf 
##WARNING:  THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
##OVERWRITTEN AND LOST.  Changes to this configuration should be made using:
##    virsh net-edit lxcbr0
## or other application using the libvirt API.
##
## dnsmasq conf file created by libvirt
strict-order
pid-file=/var/run/libvirt/network/lxcbr0.pid
except-interface=lo
bind-dynamic
interface=lxcbr0
dhcp-range=192.168.125.2,192.168.125.254
dhcp-no-override
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/lxcbr0.hostsfile
addn-hosts=/var/lib/libvirt/dnsmasq/lxcbr0.addnhosts