udev rule for USB flash drive

For some requirements I needed to call a script whenever there is a flash drive inserted into my Arch Linux system, So got to know udev is the better option for this. So wrote small udev rule to achieve this.  One specific requirement I had is, the script should be called only for partion devices like sda1, sda2 etc not for sda.

Lets start with the device info:

$ udevadm info -a /dev/sdb1

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

looking at device ‘/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host27/target27:0:0/27:0:0:0/block/sdb/sdb1’:
KERNEL==”sdb1″
SUBSYSTEM==”block”
DRIVER==””
ATTR{alignment_offset}==”0″
ATTR{discard_alignment}==”0″
ATTR{inflight}==”       0        0″
ATTR{partition}==”1″
ATTR{ro}==”0″
ATTR{size}==”2097152″
ATTR{start}==”2048″
ATTR{stat}==”      60        0     4160      580        0        0        0        0        0      480      580″

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host27/target27:0:0/27:0:0:0/block/sdb’:
KERNELS==”sdb”
SUBSYSTEMS==”block”
DRIVERS==””
ATTRS{alignment_offset}==”0″
ATTRS{capability}==”51″
ATTRS{discard_alignment}==”0″
ATTRS{events}==”media_change”
ATTRS{events_async}==””
ATTRS{events_poll_msecs}==”-1″
ATTRS{ext_range}==”256″
ATTRS{inflight}==”       0        0″
ATTRS{range}==”16″
ATTRS{removable}==”1″
ATTRS{ro}==”0″
ATTRS{size}==”7837696″
ATTRS{stat}==”     279        0    18680     2540        0        0        0        0        0      643     2540″

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host27/target27:0:0/27:0:0:0’:
KERNELS==”27:0:0:0″
SUBSYSTEMS==”scsi”
DRIVERS==”sd”
ATTRS{device_blocked}==”0″
ATTRS{device_busy}==”0″
ATTRS{dh_state}==”detached”
ATTRS{eh_timeout}==”10″
ATTRS{evt_capacity_change_reported}==”0″
ATTRS{evt_inquiry_change_reported}==”0″
ATTRS{evt_lun_change_reported}==”0″
ATTRS{evt_media_change}==”0″
ATTRS{evt_mode_parameter_change_reported}==”0″
ATTRS{evt_soft_threshold_reached}==”0″
ATTRS{inquiry}==””
ATTRS{iocounterbits}==”32″
ATTRS{iodone_cnt}==”0x27d”
ATTRS{ioerr_cnt}==”0x1″
ATTRS{iorequest_cnt}==”0x27d”
ATTRS{max_sectors}==”240″
ATTRS{model}==”Cruzer Blade    ”
ATTRS{queue_depth}==”1″
ATTRS{queue_type}==”none”
ATTRS{rev}==”1.00″
ATTRS{scsi_level}==”3″
ATTRS{state}==”running”
ATTRS{timeout}==”30″
ATTRS{type}==”0″
ATTRS{vendor}==”SanDisk ”

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host27/target27:0:0’:
KERNELS==”target27:0:0″
SUBSYSTEMS==”scsi”
DRIVERS==””

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0/host27’:
KERNELS==”host27″
SUBSYSTEMS==”scsi”
DRIVERS==””

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7/usb5/5-1/5-1:1.0’:
KERNELS==”5-1:1.0″
SUBSYSTEMS==”usb”
DRIVERS==”usb-storage”
ATTRS{authorized}==”1″
ATTRS{bAlternateSetting}==” 0″
ATTRS{bInterfaceClass}==”08″
ATTRS{bInterfaceNumber}==”00″
ATTRS{bInterfaceProtocol}==”50″
ATTRS{bInterfaceSubClass}==”06″
ATTRS{bNumEndpoints}==”02″
ATTRS{supports_autosuspend}==”1″

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7/usb5/5-1’:
KERNELS==”5-1″
SUBSYSTEMS==”usb”
DRIVERS==”usb”
ATTRS{authorized}==”1″
ATTRS{avoid_reset_quirk}==”0″
ATTRS{bConfigurationValue}==”1″
ATTRS{bDeviceClass}==”00″
ATTRS{bDeviceProtocol}==”00″
ATTRS{bDeviceSubClass}==”00″
ATTRS{bMaxPacketSize0}==”64″
ATTRS{bMaxPower}==”200mA”
ATTRS{bNumConfigurations}==”1″
ATTRS{bNumInterfaces}==” 1″
ATTRS{bcdDevice}==”0100″
ATTRS{bmAttributes}==”80″
ATTRS{busnum}==”5″
ATTRS{configuration}==””
ATTRS{devnum}==”23″
ATTRS{devpath}==”1″
ATTRS{idProduct}==”5567″
ATTRS{idVendor}==”0781″
ATTRS{ltm_capable}==”no”
ATTRS{manufacturer}==”SanDisk”
ATTRS{maxchild}==”0″
ATTRS{product}==”Cruzer Blade”
ATTRS{quirks}==”0x0″
ATTRS{removable}==”unknown”
ATTRS{serial}==”200517373009D12387AD”
ATTRS{speed}==”480″
ATTRS{urbnum}==”1610″
ATTRS{version}==” 2.00″

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7/usb5’:
KERNELS==”usb5″
SUBSYSTEMS==”usb”
DRIVERS==”usb”
ATTRS{authorized}==”1″
ATTRS{authorized_default}==”1″
ATTRS{avoid_reset_quirk}==”0″
ATTRS{bConfigurationValue}==”1″
ATTRS{bDeviceClass}==”09″
ATTRS{bDeviceProtocol}==”00″
ATTRS{bDeviceSubClass}==”00″
ATTRS{bMaxPacketSize0}==”64″
ATTRS{bMaxPower}==”0mA”
ATTRS{bNumConfigurations}==”1″
ATTRS{bNumInterfaces}==” 1″
ATTRS{bcdDevice}==”0404″
ATTRS{bmAttributes}==”e0″
ATTRS{busnum}==”5″
ATTRS{configuration}==””
ATTRS{devnum}==”1″
ATTRS{devpath}==”0″
ATTRS{idProduct}==”0002″
ATTRS{idVendor}==”1d6b”
ATTRS{interface_authorized_default}==”1″
ATTRS{ltm_capable}==”no”
ATTRS{manufacturer}==”Linux 4.4.1-2-ARCH ehci_hcd”
ATTRS{maxchild}==”6″
ATTRS{product}==”EHCI Host Controller”
ATTRS{quirks}==”0x0″
ATTRS{removable}==”unknown”
ATTRS{serial}==”0000:00:1d.7″
ATTRS{speed}==”480″
ATTRS{urbnum}==”534″
ATTRS{version}==” 2.00″

looking at parent device ‘/devices/pci0000:00/0000:00:1d.7’:
KERNELS==”0000:00:1d.7″
SUBSYSTEMS==”pci”
DRIVERS==”ehci-pci”
ATTRS{broken_parity_status}==”0″
ATTRS{class}==”0x0c0320″
ATTRS{companion}==””
ATTRS{consistent_dma_mask_bits}==”32″
ATTRS{d3cold_allowed}==”1″
ATTRS{device}==”0x293a”
ATTRS{dma_mask_bits}==”32″
ATTRS{driver_override}==”(null)”
ATTRS{enable}==”1″
ATTRS{irq}==”23″
ATTRS{local_cpulist}==”0-1″
ATTRS{local_cpus}==”3″
ATTRS{msi_bus}==”1″
ATTRS{numa_node}==”-1″
ATTRS{subsystem_device}==”0x02be”
ATTRS{subsystem_vendor}==”0x1028″
ATTRS{uframe_periodic_max}==”100″
ATTRS{vendor}==”0x8086″

looking at parent device ‘/devices/pci0000:00’:
KERNELS==”pci0000:00″
SUBSYSTEMS==””
DRIVERS==””
/div>

 

When I execute the command “udevadm info -a /dev/sdb1” , it displays above information.

based on that, have written a small rule in  “/etc/udev/rules.d/jesh.rules” file and reload the udev daemon using command “sudo udevadm control –reload-rules” to apply the change rules in the same boot. I have added one line mentioned below in my rule file.

ACTION==”add”, SUBSYSTEM==”block”, SUBSYSTEMS==”usb”, KERNEL==”sd[a-z]*”, ATTR{partition}==”[1-4]”,RUN+=”/home/jeshwanth/junk/udev.sh %k”

ACTION – this key is to mention whether adding device or removing device from the system. In above rule I have mentioned “add”, so this rule valid for when the USB is inserted into the system, not when removed.

SUBSYSTEM -Driver subsystem, like block, char etc. Here USB flash drive is a block device.

SUBSYSTEMS – subsystem information like usb, pci etc.

KERNEL – this is the device node which is goinf to create, we can mention in regular expression format to match vast numbr of names. like mentioned above it matches sda to sdz and sda1, sda2 etc.

ATTR{partition} – Here is the interesting thing, for my requirement I don’t want to execute my script for nodes which is not a partition type, so considering sdb, sdb1, sdb2, sdb3 etc. sdb is not a partition node, but sdb1, sdb2, sdb2 are. So, I am executing script only for sdb1, sdb2, sdb3.

RUN+ – path for script  or command to execute.

To run systemd service in udev rules:

ACTION==”add”, SUBSYSTEM==”block”, SUBSYSTEMS==”usb”, KERNEL==”sd[a-z]*”, ATTR{partition}==”[1-4]”, TAG+=”systemd”, ENV{SYSTEMD_WANTS}=”usb_attach.service”

TAG+ – is to tag the udev device to systemd.

ENV{SYSTEMD_WANTS} – mention the service needs to be started for rhis rule.

 

References: 1 , 2

capture screenshots in Linux

I was searching for a commandline tool for capturing screen shot in Linux, and ended up using very nice tool called import (An utility from imagemagic). import is a command line tool, where we can use it for taking screenshot, image manipulation, filtering etc.

In arch Linux you can install imagemagic using command:

$ sudo pacman -S imagemagick

Let me tell you 2 usefull commands of import.

$ import region.jpg

This command will give you mouse prompt to select region in the window to capture. By selecting the region, file with the name region.jpg gets created.

$ sleep 2; import -window root /tmp/MyScreenshot.png

This command sleeps for 2 seconds before capturing the entire screen. The complete screen will get stored in file MyScreenshot.png. The sleep time user can give anything which is necessary.

I haven’t found options to take screenshot along with mouse pointer in import command. There is one more tool called gnome-screenshot, can be used to capture screenshot with mouse pointer.

Installing gnome-screenshot in Arch Linux:

sudo pacman -S gnome-screenshot

Example command to capture screenshot along with mouse pointer using gnome-screenshot:

gnome-screenshot  -p -f /tmp/image.png

Here, option -p is for including mouse pointer, without this option it will ignore the mouse pointer. -f option is for filename to save the screenshot.

python script to fetch rss feeds

I was just thinking about making an rss bot in telegram, and wrote a small python script which can fetch rss feeds from the feed link and prints the result with “Title” and “Link”.

import feedparser
import sys

if len(sys.argv) < 2:
print("USAGE: python feedparse.py <rss feed link>")
exit()

rss_url = sys.argv[1]
print("TITLE","                                                   ","LINK")
print("------------------------------------------------------------------")

feed = feedparser.parse( rss_url )

y = len(feed[ "items" ])

for x in range(0,y):
print('\033[91m'+feed[ "items" ][x][ "title" ] + '\033[0m', "-", feed[ "items" ][x][ "link" ])

Below example shall print the feeds available in Mobilecrunch.

Example:
$ python feedparse.py http://feeds.feedburner.com/Mobilecrunch

Newest code will be available in gist if I forget to update this blog.

systemd stuffs

[In draft stage]

This blog is a notes on systemd which I have noted down while reading a online documnet https://n0where.net/understanding-systemd/ and through man pages.Will keep updating it.

Features:
socket-based activation
bus-based activation
path-based activation
device-based activation
implicit dependency mapping
instances and templates
easy security hardening
drop-ins and snippets – Override the Vanila units.

service file location:

/lib/systemd/system/ – The systemd unit files are stored.

/etc/systemd/system/ – overrides above services if the same service name.

/run/systemd/system/ – runtime units.

Unit file types:

.service – for daemons and applications.

.socket – for socket activation.

.device

.mount

.automount

.swap

.target – system states.

.path – path based activation ‘inotify’.

.timer – manage jobs with time. cron type.

.snapshot – system current state snapshot.

.slice – Resource isolation with cgroups for users.

.scope

[Unit] Section:

Description=:

Documentation=:

Requires=: This directive lists any units upon which this unit essentially depends. If the current unit is activated, the units listed here must successfully activate as well, else this unit will fail. These units are started in parallel with the current unit by default.

Wants=: This directive is similar to Requires=, but less strict. Systemd will attempt to start any units listed here when this unit is activated. If these units are not found or fail to start, the current unit will continue to function.

BindsTo=: This directive is similar to Requires=, but also causes the current unit to stop when the associated unit terminates.

Before=: The units listed in this directive will not be started until the current unit is marked as started if they are activated at the same time.

After=: The units listed in this directive will be started before starting the current unit. This does not imply a dependency relationship and one must be established through the above directives if this is required.

Conflicts=: This can be used to list units that cannot be run at the same time as the current unit.

Condition=:

Assert=:

[Install] Section:

Only units that can be enabled will have this section.

WantedBy=:

RequiredBya=:

Alias=:

Also=:

DefaultInstance=:

[Service] Section:

The [Service] section is used to provide configuration that is only applicable for services.

Type: directive:

simple: exestart is the main process.

forking: exestart is the parent process which might exit by launching child process.

oneshot: wait till comeples this process, its very short term ;).

dbus: wait untill the bus name is created.

notify: notifies systemd after started successfully.

idle: This indicates that the service will not be run until all jobs are dispatched.

Additional Directives in Service:

RemainAfterExit=:

PIDFile=:

BusName=:

NotifyAccess=:

Directives for Managing services:

ExecStart=: full path to the binary which needs to be executed.

ExecStartPre=: path to the app, to run before the main process.

ExecStartPost=: path to the app, to run after the main process created.

ExecReload=: path to the app, to reload the service.

ExecStop=: path to the app, to stop the process.

ExecStopPost=: execute after stop.

RestartSec=: time to wait before restarting the process.

Restart=: restart the process on event.

TimeoutSec=: time of waiting to declare the process is failed to start/stop.

[Socket] Section:

ListenStream=: stream socket address.

ListenDatagram=: datagram socket address.

ListenSequentialPacket=: sequential, reliable communication with max length datagrams that preserves message boundaries

ListenFIFO:

Additional Directives:

Accept=: to control creating instances for each connections.

SocketUser=: root user if  left unset.

SocketGroup=: group owner of the socket,  root if unset.

SocketMode=: permissions

[Mount] Section:

What=: Takes an absolute path of a device node

Where=: The absolute path of the mount point where the resource should be mounted.

Type=: Filesystem type.

Options=: Any mount options that need to be applied. This is a comma-separated list.

SloppyOptions=:

DirectoryMode=:

TimeoutSec=: Configures the amount of time the system will wait until the mount operation is marked as failed.

[Automount] Section:

Where=:

DirectoryMode=:

[Swap] Section:

What=: Absolute path to the location of swap space.

Priority=:

Options=: options sets in /etc/fstab

TimeoutSec=:

[Path] Section:

PathExists=:

PathExistsGlob=:

PathChanged=:

PathModified=:

DirectoryNotEmpty=:

Unit=:

MakeDirectory=:

DirectoryMode=:

[Timer] Section:

onActiveSec=:

OnBootSec=:

OnStartupSec=:

OnUnitActiveSec=:

OnUnitInactiveSec=:

OnCalendar=:

AccuracySec=:

Unit=: This directive is used to specify the unit that should be activated when the timer elapses. If unset, systemd will look for a .service unit with a name that matches this unit.

Persistent=:

[Slice] Section:

Template units:

Template Specifiers:

%n: Full resulting unit name.

%N:

%p: Unit name prefix.

%P:

%i: This references the instance name, which is the identifier following the @ in the instance unit.

%I:

%f:

%c: Control group of the unit.

%u: Name of the user configured to run the unit.

%U: Name of the user, but as UID – numeric.

%H: Hostname of the running system.

%%: To insert the literal percentage.

Systemd commands:

* systemctl start <servicename>

* systemctl stop <servicename>

* systemctl restart <servicename>

* systemctl reload <servicename>

* systemctl enable <servicename>

* systemctl disable <servicename>

* systemctl list-units

* systemctl list-units –all

* systemctl list-unit-files

* journalctl

* journalctl -b #Current boot log.

* journalctl -k #Kernel messages.

* systemctl status <servicename>

* journalctl -u <servicename>

* systemctl cat <servicename>

* systemctl list-unit-files –type=target

* systemctl get-default

* systemctl set-default multi-user.target

* systemctl list-dependencies multi-user.target

* systemctl isolate multi-user.target

* systemctl show sshd.service -p Conflicts

Stopping or Rebooting the Server:

* systemctl poweroff #poweroff the Server

* systemctl reboot #reboot the system.

* systemctl rescue #boot to rescue mode.

Starting and Stopping Services:

* systemctl start application.service

* systemctl start applications

* systemctl stop application.service

Restarting and Reloading:

* systemctl restart application.service

* systemctl reload application.service

* systemctl reload-or-restart application.service

Enabling and Disabling services:

* systemctl enable application.service

* systemctl disable application.service

Checking the Status of services:

* systemctl status application.service

* systemctl is-active application.service

* systemctl is-enabled application.service

* systemctl is-failed application.service

* systemctl list-units –all –state=inactive

Masking and Unmasking units:

* systemctl mask application.service

* systemctl unmask application.service

Logs:

* journalctl –list-boots

* journalctl –since yesterday

* journalctl _PID=<PID_NUMBER>

* man systemd.journal-fields

* journalctl -F _PID

* journalctl /usr/bin/bash

[Priority]

* journalctl -p err -b

0: emerg
1: alert
2: crit
3: err
4: warning
5: notice
6: info
7: debug

* journalclt –no-pager #output to stdout

* journalctl -b -u shhd -o json

* journalctl -n #display last 10 lines.

* journalctl -n 20 #display last 20 lines.

* journalctl -f #following logs.

* journalctl –disk-usage

* journalctl –vacuum-size=1G

* journalctl –vacuum-time=1years

Use serial tty as a user

Normally when we connect any boards like arduino, USB to serial converter we end up running applications with sudo. But sometimes we need to run some applications inside scripts which uses these tty’s or simply people think why always I need to run with sudo (for those who comfortable clicking on Application icons and using the App).

The solution to use these tty’s with user permissions is solved bt adding user to dialout and tty group. As mentioned below.

sudo usermod -a -G tty yourUserName

sudo usermod -a -G dialout yourUserName

Now you can run tty based applications with your username without sudo :).  Reference

 

Extract mp3 from youtube-dl

There is a famous command line tool called youtube-dl to download videos from youtube, and its an opensource project written in python and available for Linux, windows and OSX platforms.

In Linux, you can install the tool using:

$ sudo pip install –upgrade youtube-dl

To download a video from a link:

$ youtube-dl <Your Video link>

Example: youtube-dl https://www.youtube.com/watch?v=pRpeEdMmmQ0&list=RDpRpeEdMmmQ0

It will get donwloaded in $PWD.

To download mp3 from a link:

$ youtube-dl –extract-audio –audio-format mp3 <Your Video Link>

Example: youtube-dl –extract-audio –audio-format mp3 https://www.youtube.com/watch?v=krpm0DaeLnI

It will get downloaded in $PWD.

Do “youtube-dl -h” for more help on formats and other features.

 

Download audio from soundcloud through command line

Like youtube-dl there is a command line tool called scdl, which is written in python based on GPLV2 license and works on Linux, windows and OSX.

To install in linux, execute below command:

$ pip install scdl

To download a single song:

$scdl -l <Sound cloud link to the song>

Example: scdl -l scdl -l https://soundcloud.com/trdp/raghu-dixit-jagchanga-lokada

It will download and store in $PWD

Do “scdl -h” to know other options like download complete album, user liked videos etc.

 

 

Arch Linux: Remove downloaded packages cache and clear memory

My rootfs is very small in size (30 GB), and I am running Arch Linux from past two years and constantly upgrade the new releases and packages. At some point of time my rootfs become full and I couldn’t able to install anything new (not even upgrade the system). When I looked at my rootfs, like which directory is consuming maximum space, found /var/cache/pacman/pkg holds 12 GB of my memory. And it all contains compressed packages which is downloaded when I upgrade my system. All those packages you might not need often, so you can remove all those packages safely using below command.

pacman -Sc

Now I have got my 12 GB free space back. 🙂

For more info Link