Applications


Android Studio – No space left on device 10

Recently we tried to install some packages from the Android SDK through Android Studio 3.0.1 and we got the error that the PC ran out of space while downloading the necessary packages and could not perform the operation.

Full Error Log:

To install:
- Google APIs Intel x86 Atom System Image (system-images;android-27;google_apis;x86)
Preparing "Install Google APIs Intel x86 Atom System Image (revision: 2)".
Downloading https://dl.google.com/android/repository/sys-img/google_apis/x86-27_r02.zip
An error occurred while preparing SDK package Google APIs Intel x86 Atom System Image: Cannot download 'https://dl.google.com/android/repository/sys-img/google_apis/x86-27_r02.zip': No space left on device
, response: 200 OK.
"Install Google APIs Intel x86 Atom System Image (revision: 2)" failed.
Failed packages:
- Google APIs Intel x86 Atom System Image (system-images;android-27;google_apis;x86)

Although the disk had a lot of free space, we got this error because the /tmp partition on our GNU/Linux Fedora 27 workstation was too small (~4GB).

$ df -h;
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 107M 3.8G 3% /dev/shm
tmpfs 3.9G 1.9M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/mapper/fedora-root 50G 35G 12G 75% /
tmpfs 3.9G 2.1M 3.9G 1% /tmp
/dev/sdb1 477M 179M 269M 41% /boot
/dev/mapper/fedora-home 178G 37G 132G 22% /home
tmpfs 794M 16K 794M 1% /run/user/42
tmpfs 794M 9.2M 785M 2% /run/user/1000

/tmp was not explicitly set so it was automatically configured to have half of the size of the RAM.
We didn’t not want to change the download path for the Java environment (and hence Android Studio and Android SDK tools) as after leaving the tmpfs folder it could mean that we would have to manually maintain the new path and clean it up. So we ended up in temporarily increasing the size of /tmp partition which did the trick and the virtual device was installed successfully.

Solution – temporarily increase the size of the /tmp partition:

The command we used to increase the size of the /tmp partition on Fedora 27 was the following:


sudo mount -o remount,size=8G,noatime /tmp;

After executing we, it we immediately saw that the results were applied without the need for a restart or any other operation and we could proceed to use the PC as normal.

$ df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 89M 3.8G 3% /dev/shm
tmpfs 3.9G 1.9M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/mapper/fedora-root 50G 35G 12G 75% /
tmpfs 8.0G 2.0M 8.0G 1% /tmp
/dev/sdb1 477M 179M 269M 41% /boot
/dev/mapper/fedora-home 178G 37G 132G 22% /home
tmpfs 794M 16K 794M 1% /run/user/42
tmpfs 794M 6.9M 787M 1% /run/user/1000

The information for tmpfs we got it from: https://wiki.archlinux.org/index.php/Tmpfs

Full Correct Execution Log:

To install:
- Google APIs Intel x86 Atom System Image (system-images;android-27;google_apis;x86)
Preparing "Install Google APIs Intel x86 Atom System Image (revision: 2)".
Downloading https://dl.google.com/android/repository/sys-img/google_apis/x86-27_r02.zip
"Install Google APIs Intel x86 Atom System Image (revision: 2)" ready.
Installing Google APIs Intel x86 Atom System Image in /home/xeirwn/Android/Sdk/system-images/android-27/google_apis/x86
"Install Google APIs Intel x86 Atom System Image (revision: 2)" complete.
"Install Google APIs Intel x86 Atom System Image (revision: 2)" finished.


How to process tcpdump live data stream from a remote machine on a local WireShark 1

Recently we needed to process the results of a tcpdump command using the GUI version of WireShark on machine that did not have a window manager installed. That device was an embedded device, for which it did not make sense to even consider installing a window manager on it. So, in order to process the results of the tcpdump command we decided to use another machine that had a full working window manager installed and was able to operate the GUI version of WireShark.

For our solution to work some requirements were expected to be met by the embedded device (a.k.a. remote machine).

  1. tcpdump was installed on the remote machine
  2. ssh server was installed on the remote machine and allowed us to connect to it remotely
  3. there was a user that had remote ssh rights on the remote machine that also had the rights to execute tcpdump on the needed interfaces

Synopsis of our solution:

Just execute the following on the machine with the GUI (a.k.a. local machine)


mkfifo /tmp/board;
wireshark -k -i /tmp/board &
ssh [email protected] "tcpdump -s 0 -U -n -w - -i lo not port 22" > /tmp/board;

Explanation of our solution:

Following are the steps that we performed on the local machine to pipe the results of tcpdump on the remote machine on the wireshark on the local machine.

  1. First we created a named pipe as follows:
    mkfifo /tmp/board;
    You can name your pipe anyway you like and place it in any folder you wish. We used /tmp as our pipe is a temporary construct that we do not care to preserve across time/restarts.
  2. Then we started wireshark from a terminal so that we could pass as capture interface the named pipe we just created using the -i /tmp/board parameter. The -k parameter instructs wireshark to start the capture session immediately.
    wireshark -k -i /tmp/board &
    Since this operation was going to execute for a long time, we sent it to the background to release the terminal for further use by placing the & symbol at the end of the command.
  3. Finally, we started tcpdump over ssh on a board and redirected its output to our named pipe.
    ssh [email protected] "tcpdump -s 0 -U -n -w - -i lo not port 22" > /tmp/board;
    The parameters we used on tcpdump have the following effects:
    -s 0 instructs tcpdump to set the snapshot length of data from each packet to the default value of 262144 bytes.
    -U Since the -w option is not specified, make the printed packet output packet-buffered. Which means that it will print the description of the contents of each packet without waiting for the output buffer to get full.
    -n Does not convert host addresses to names. This can be used to avoid DNS lookups.
    -w - Write the raw packets to Standard Output rather than parsing them.
    -i lo Defines which interface to listen on. We wanted the loopback interface to listen to everything.
    not port 22 Since we used ssh to start this command, we do not want to listen to the data that we produce as well and flood the inputs.

 


Enable C++11 standard for GCC on Eclipse CDT

When using Eclipse CDT to write C++, we noticed that it did not enable by default the C++11 standard. Following the steps below, we added the -std=c++11 flag on the GCC C++ Compiler command line arguments enabling the standard for our use.

  1. From the main window of Eclipse, on the list on the left, where your projects are listed, right click on your project and then click Properties from the new menu
  2. In the new window, navigate from the list on the left and expand the C/C++ Build option to view its children and then click the Settings item
  3. In the middle of the window, you will see a new list, expand (if needed) the item GCC C++ Compiler and click on the Miscellaneous child
  4. On the right, a text box named Other Flags will appear, append -std=c++11 to the list of tokens in the box as seen in the image below
  5. Click on the Apply button for the effects to take place and then the OK button to close the properties window

Next time you compile, the -std=c++11 flag will be present on your compiler command line and the C++11 standard will be used.


Start Arduino IDE as root on Fedora / Allow root to start an X application

Solution

Execute the following as a normal user


xhost +si:localuser:root;
sudo ./arduino;

Background Story and More Information

Recently we needed to start the official Arduino IDE as root on Fedora to allow the application to take control of the serial port.
We were getting the following error whenever we tried to upload the application to the board:

processing.app.debug.RunnerException
 at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:160)
 at cc.arduino.UploaderUtils.upload(UploaderUtils.java:78)
 at processing.app.SketchController.upload(SketchController.java:713)
 at processing.app.SketchController.exportApplet(SketchController.java:686)
 at processing.app.Editor$DefaultExportHandler.run(Editor.java:2168)
 at java.lang.Thread.run(Thread.java:748)
Caused by: processing.app.SerialException: Error touching serial port '/dev/ttyACM0'.
 at processing.app.Serial.touchForCDCReset(Serial.java:107)
 at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:144)
 ... 5 more
Caused by: jssc.SerialPortException: Port name - /dev/ttyACM0; Method name - openPort(); Exception type - Permission denied.
 at jssc.SerialPort.openPort(SerialPort.java:170)
 at processing.app.Serial.touchForCDCReset(Serial.java:101)
 ... 6 more

So, we tried to start the arduino IDE using root and got another error:

[george@bytefreaks bin]$ sudo ./arduino;
[sudo] password for george: 
No protocol specified
Picked up JAVA_TOOL_OPTIONS: 
No protocol specified
java.awt.AWTError: Can't connect to X11 window server using ':0' as the value of the DISPLAY variable.
	at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
	at sun.awt.X11GraphicsEnvironment.access$200(X11GraphicsEnvironment.java:65)
	at sun.awt.X11GraphicsEnvironment$1.run(X11GraphicsEnvironment.java:115)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.awt.X11GraphicsEnvironment.(X11GraphicsEnvironment.java:74)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at java.awt.GraphicsEnvironment.createGE(GraphicsEnvironment.java:103)
	at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:82)
	at sun.awt.X11.XToolkit.(XToolkit.java:126)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at java.awt.Toolkit$2.run(Toolkit.java:860)
	at java.awt.Toolkit$2.run(Toolkit.java:855)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.awt.Toolkit.getDefaultToolkit(Toolkit.java:854)
	at java.awt.SystemColor.updateSystemColors(SystemColor.java:473)
	at java.awt.SystemColor.(SystemColor.java:465)
	at processing.app.Theme.init(Theme.java:84)
	at processing.app.Base.(Base.java:219)
	at processing.app.Base.main(Base.java:144)

This error occurred because the default configuration of the X server permissions did not allow the root to connect to it.
To verify this, we used xhost (the X server access control program) to check the permissions.
Executing xhost with no command line arguments gave us a message indicating whether or not access control was currently enabled, followed by the list of those users allowed to connect.
For example in our case the output was as follows:


[george@bytefreaks bin]$ xhost
access control enabled, only authorized clients can connect
SI:localuser:george

To add root to the list of users that was allowed to start an X application we executed the following command:


[george@bytefreaks bin]$ xhost +si:localuser:root
localuser:root being added to access control list

Executing xhost again, we got the updated list which included the root


[george@bytefreaks bin]$ xhost
access control enabled, only authorized clients can connect
SI:localuser:root
SI:localuser:george

After this, we were able to start arduino IDE using sudo with no problems.


[george@bytefreaks bin]$ sudo ./arduino;

Note: This patch is not permanent, we actually execute it once at every restart of the machine.