GNU/Linux


Ubuntu how clear journal logs and free up some disk space

On a machine that has Ubuntu 20.04LTS was recently running out of space, while using the Disk Usage Analysis tool we noticed that /var/log/journal was taking a bit more than 4 GB.

We knew that the machine was not hosting any kind of public service nor did it have any hardware problems, so we decided to clear up old logs. To do so, we used the following command that removed all logs that were older than two days.

sudo journalctl --vacuum-time=2d;

The result was great as it saved 3.9 GB of space:

Vacuuming done, freed 3.9G of archived journals from /var/log/journal/ee4a566eacf347dbb47e03b3f33821a1.

More information on journalctl can be found here. You can find more options on removing old logs, for example limiting the total size of logs that you want to keep, using this variation which will keep only 50 MB of data:

sudo journalctl --vacuum-size=50M;

Netflix error f7701-1003 on Ubuntu

Recently we got the error F7701-1003 on Netflix after an update on the operating system was performed. To repair it we installed the package libavcodec-extra using the following command:

sudo apt install libavcodec-extra;

After the installation was complete, we just restarted the browser and Netflix was operating again as expected.

Below is the basic information about the package that was installed:

Package: libavcodec-extra
Version: 7:4.2.4-1ubuntu0.1
Priority: extra
Section: universe/libs
Source: ffmpeg
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Debian Multimedia Maintainers <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 65,5 kB
Depends: libavcodec-extra58 (= 7:4.2.4-1ubuntu0.1)
Homepage: https://ffmpeg.org/
Download-Size: 14,8 kB
APT-Manual-Installed: yes
APT-Sources: http://cy.archive.ubuntu.com/ubuntu focal-updates/universe amd64 Packages
Description: FFmpeg library with extra codecs (metapackage)
 FFmpeg is the leading multimedia framework, able to decode, encode, transcode,
 mux, demux, stream, filter and play pretty much anything that humans and
 machines have created. It supports the most obscure ancient formats up to the
 cutting edge.
 .
 This metapackage depends on the latest version of the libavcodec variant
 that offers additional codec support. Application packages can depend
 on it if they require or suggest this variant in a robust manner.

Package: libavcodec-extra
Version: 7:4.2.2-1ubuntu1
Priority: extra
Section: universe/libs
Source: ffmpeg
Origin: Ubuntu
Maintainer: Ubuntu Developers <[email protected]>
Original-Maintainer: Debian Multimedia Maintainers <[email protected]>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 65,5 kB
Depends: libavcodec-extra58 (= 7:4.2.2-1ubuntu1)
Homepage: https://ffmpeg.org/
Download-Size: 14,8 kB
APT-Sources: http://cy.archive.ubuntu.com/ubuntu focal/universe amd64 Packages
Description: FFmpeg library with extra codecs (metapackage)
 FFmpeg is the leading multimedia framework, able to decode, encode, transcode,
 mux, demux, stream, filter and play pretty much anything that humans and
 machines have created. It supports the most obscure ancient formats up to the
 cutting edge.
 .
 This metapackage depends on the latest version of the libavcodec variant
 that offers additional codec support. Application packages can depend
 on it if they require or suggest this variant in a robust manner.

Monkey Problems 1

Recently, we tried to user monkeyrunner on an Ubuntu 18.04 LTS. We installed Android Studio through snap and we setup the Android SDK in ~/Andoid. monkeyrunner was installed in ~/Android/Sdk/tools/bin. To our immeasurable disappointment we found out that when we tried to execute monkeyrunner, it would give the following error:

$ ./monkeyrunner
-Djava.ext.dirs=/home/tux/Android/Sdk/tools/lib:/home/tux/Android/Sdk/tools/lib/x86_64 is not supported. Use -classpath instead.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

At first, we had no idea what that meant, so we used file command on monkeyrunner and we found out that monkeyrunner is a bash script.

$ file monkeyrunner
monkeyrunner: POSIX shell script, ASCII text executable

After reading the code, we read the following at the last lines:

#need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
#might need more memory, e.g. -Xmx128M
exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir:$swtpath" -Djava.library.path="$libdir" -Dcom.android.monkeyrunner.bindir="$progdir" -jar "$jarpath" "[email protected]"

First thing we did was to find the java version that was used, since the command that was giving the problem was that. We found out that we had version 11.

$ java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment (build 11.0.6+10-post-Ubuntu-1ubuntu118.04.1)
OpenJDK 64-Bit Server VM (build 11.0.6+10-post-Ubuntu-1ubuntu118.04.1, mixed mode, sharing)

After reading a bit, we found out that after Java version 8 the command line directive -Djava.ext.dirs it was deprecated and the recommendation to use -classpath was added. In the past, java.ext.dirs was used to instruct the JRE from where to load additional class and jar files. Since we had Java version 11 we had to try the recommendation to remove the -Djava.ext.dirs directive and use -classpath instead. So, we edited the file monkeyrunner and changed the last line as follows:

exec java -Xmx128M $os_opts $java_debug -classpath "$frameworkdir/*:$swtpath" -Djava.library.path="$libdir" -Dcom.android.monkeyrunner.bindir="$progdir" -jar "$jarpath" "[email protected]"

We tried executing the newly updated monkeyrunner again, only to hit another wall!

$ ./monkeyrunner
Exception in thread "main" java.lang.NoClassDefFoundError: com/android/chimpchat/ChimpChat
at com.android.monkeyrunner.MonkeyRunnerStarter.(MonkeyRunnerStarter.java:60)
at com.android.monkeyrunner.MonkeyRunnerStarter.main(MonkeyRunnerStarter.java:188)
Caused by: java.lang.ClassNotFoundException: com.android.chimpchat.ChimpChat
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
… 2 more

It turns out that when you use the -jar directive, JRE will ignore the -classpath directive and so it will again not be able to load any external class or jar files…

Solution

Instead of reinventing the wheel (We tried, we failed, it was painful. Still worth the shot!) we decided to install Java version 8 on Ubuntu 18.04 LTS side by side with Java version 11 and just used that.

First, we checked the list of installed jvm on our machine using the following command:

update-java-alternatives --list;

Where we got the following:

$ update-java-alternatives --list
java-1.11.0-openjdk-amd64 1111 /usr/lib/jvm/java-1.11.0-openjdk-amd64
java-1.8.0-openjdk-amd64 1081 /usr/lib/jvm/java-1.8.0-openjdk-amd64

It turned out we already had Java version 8 but if we didn’t we would install it as follows:

sudo apt install openjdk-8-jdk;

and then it would again appear in the list mentioned above.

Then, we switched to the Java version 8 using the following command and selecting the appropriate option:

sudo update-alternatives --config java;

$ sudo update-alternatives --config java
[sudo] password for tux:
There are 2 choices for the alternative java (providing /usr/bin/java).
Selection Path Priority Status
0 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 auto mode
1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode
2 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 1081 manual mode
Press to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java to provide /usr/bin/java (java) in manual mode

After switching Java to Version 8 monkeyrunner was working as expected!!


How to temporarily open MySQL / MariaDB port on CentOS 7 firewall

Recently, we came across a CentOS 7 that was executing MariaDB (MySQL) server. The Database Administrators needed a way to open to the port and allow connections to the SQL server from outside the machine.
As they did not have a specific IP from which they would connect, we provided the following solution.

To temporarily open port 3306

firewall-cmd --add-port=3306/tcp;

To close the port 3306 (method A)

firewall-cmd --remove-port=3306/tcp;

or reload firewalld which will cause it to loose all changes that are not permanent (method B)

firewall-cmd  --reload;

firewalld (Dynamic Firewall Manager) tool provides a dynamically managed firewall. The tool enables network/firewall zones to define the trust level of network connections and/or interfaces. It has support both for IPv4 and IPv6 firewall settings. Also, it supports Ethernet bridges and allow you to separate between runtime and permanent configuration options. Finally, it supports an interface for services or applications to add firewall rules directly.


GNU/Linux: How to give access to a subfolder to a user where the user does not have execute permission over the parent folder

On GNU/Linux, you can traverse a directory if and only if you have execute permission on the whole path that you are going to use to access it. This rule applies a limitation to scenarios where for some reason you want to give execute access to a certain user on a subfolder but you do not want to enable the execute permission on the all the folders in the path.

In order to access the folder theFolder in the path /folderA/folderB/theFolder, if you are on the same level as folderA (or higher) you need to have execute permission both on folderA and folderA/folderB additionally to the permissions needed on theFolder. On another scenario if you are located in the same level as folderB (and you have execute rights to it) even if you do not have the execute rights to folder folderA you would still be able to access theFolder as your whole path (which is a relative path in this scenario) skips folderA. This feature is due to the fact that in GNU/Linux that the path that you use to access a folder determines your access constraints. In cases where the user does not have execute access to the whole path, creating symbolic links for them will not help you give them access. The kernel will still go through the access rights of the whole path that the symlink describes and it will act accordingly.

A hack-ish solution around this issue is to use mount to remount a part of the file hierarchy somewhere else using the bind parameter. For example: if we needed to give access to a user to the folder theFolder that resides in /folderA/folderB/theFolder without enabling execute rights on folderA nor /folderA/folderB we could execute the following command in a folder where that user already has execute access in (for example in the user’s home folder).

sudo mount --bind /folderA/folderB/theFolder finallyTheFolder;

Notes:

  • This solution circumvents security, be sure to think things through before implementing it
  • This solution ‘escapes’ normal good practices so it could lead to software bugs on your behalf
  • The bind will not persist after a reboot
  • To make this change permanent, you will need to add a configuration line in /etc/fstab
  • If the directory that you wish to bind contains mounted file systems, these file systems will not be transferred to the target. The mount points will appear as empty directories.