I'm trying to write an ansible playbook to automaticly scan new disks and put it into an existing VG and than extend it.
Unfortunately I can't figure out how Linux knows the next device mapper for example (/dev/sdc), to create a perfect ansible playbook to execute this task for me.
Scanning new disk online:
echo 0 0 0 | tee /sys/class/scsi_host/host*/scan
Someone have any idea about this?
Thanks.
You are using confusing terminology. Device mapper is framework which is used by LVM, occasionally one may use device mapper as name for devices created by applications which use device mapper. They are usually can be found in /dev/mapper.
/dev/sdc (and allo other /dev/sd[a-z][a-z]?) are just block devices. They CAN be used by LVM to create PV (physical volume), but they aren't "device mapper".
Now to the answer:
Linux uses 'next available in alphabet letter' for new device. Unfortunately, 'next available' for kernel and for user may be a different thing. If device has been unplugged (or died, or rescanned with reset) and underlying device is marked as been still used, Linux will use 'next letter', so replugged /dev/sdc may appear as /dev/sdd, or, if /dev/sdd is busy, /dev/sde, down to /dev/sdja (I'm not sure where it ends, but there is no such thing as /dev/sdzz AFAIK).
If you want to identify your devices you may use symlinks provided by udev. They are present in /dev/disk and reflects different way to identify devices:
- by-id - device ID is used (usually name and vendor)
- by-partuuid - by UUID of existing partition on disk
- by-uuid - by generated UUID unique for each drive
- by-path - by it's logical location.
I thing last one is the best: If you plug your device in the same slot it would have same name in /dev/disk/by-path regardless of vendor, id, existing filesystems and state of other block devices.
Here few examples of name you may find there:
pci-0000:00:1f.2-ata-3 - ATA disk #3 attached to a specific controller at PCI.
pci-0000:08:00.0-sas-0x50030480013afa6c-lun-0 - SAS drive with WWN 0x50030480013afa6c attached to a specific PCI controller.
pci-0000:01:00.0-scsi-0:2:1:0 - 'strange' scsi device #2 attached to a specific PCI controller. In my case it is a hardware RAID by LSI.
If you really want to handle new devices regardless of their names, please look at Udev scripts, which allows to reacts on new devices. Dealing with udev may be tricky, here example of such scripts in Ceph project: They process all disks with specific paritions ID automatically by udev rules: https://github.com/ceph/ceph/tree/master/udev
What about this?
- name: Find /sys/class/scsi_host hostX softlinks
find:
path: '/sys/class/scsi_host'
file_type: link
pattern: 'host*'
register: _scsi_hosts
- name: Rescanning for new disks
command: 'echo "- - -" > {{ item }}/scan'
changed_when: false
with_items: _scsi_hosts.files.path
Related
I know that the Raspberry Pi Zero supports OTG and USB Peripheral protocols, and there's a lot of cool built in peripherals shown here: https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget?view=all#other-modules
The problem is that I need to emulate a USB Peripheral device that does not appear on this list. I have a vendor ID and product ID for the device, and I'm trying to figure out how exactly to go about doing this. Do I need to modify the OTG USB drivers in the Raspbian kernel? Do I have to completely build my own kernel? Or is there a better option I don't even realize?
Thanks in advance!!
Do I need to modify the OTG USB drivers in the Raspbian kernel?
The answer to your first question is "it depends", but if your device
doesn't do anything too unusual this could be a No: you need not
modify source code for kernel modules nor the kernel.
You're fortunate that Raspbian supports a modern kernel with ConfigFS support. Once you are set up with dtoverlay=dwc2, you can open up a FunctionFS bulk endpoint as root like so:
modprobe libcomposite
modprobe usb_f_fs
cd /sys/kernel/config/usb_gadget
mkdir -p myperipheral; cd myperipheral
echo 0x1234 > idVendor # put actual vendor ID here
echo 0xabcd > idProduct # put actual product ID here
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "My Peripheral" > configs/c.1/strings/0x409/configuration
mkdir functions/ffs.my_func_name
ln -s functions/ffs.my_func_name configs/c.1/
mkdir -p /tmp/mount_point
mount my_func_name -t functionfs /tmp/mount_point
# compile ffs-test from source, then copy and run it from /tmp/mount_point
ls /sys/class/udc > UDC
If you need to emulate the other device more closely, it's up to you to set bcdDevice, bcdUSB, serial number, manufacturer, product string, max power, os_desc, and possibly other fields.
AFAIK FunctionFS does not support isochronous endpoints, interrupt transfers, nor out-of-the-ordinary control transfers. If you require this, you may need to start looking into extending existing gadget modules, with source code here.
Update: When I got home to test this, I encountered a severe caveat with Raspbian. It'll initially fail to create ffs.my_func_name because usb_f_fs is not enabled by default. Although you need not modify any kernel modules, you must recompile with an alternate configuration. make menuconfig -> Device Drivers -> USB support -> USB Gadget Support -> USB functions configurable through configfs / Function filesystem (FunctionFS) + some other modules to test. After uploading a new kernel/modules, I tested the above script on Raspbian 8. I would also recommend setting USB Gadget Drivers / Function Filesystem to (M) in case you resort to the simpler g_ffs legacy module in lieu of ConfigFS.
So, the question is, is the content of /dev/serial/by-id unique?
Essentially the issue is I want to connect several (two or more) arduinos (potentially of different types, but they may all end up being leonardos) to the Raspberry Pi for the purposes of an automation system.
I'll be using the serial interfaces to communicate between the Raspberry Pi in Python and the Arduinos. I've run this on one of the leonardos (at present I only have one):
udevadm info -a -n /dev/ttyACM0| grep serial
0000:00:1d.0
Is this a unique serial for my serial connection to the Pi? Can I rely on this to create a UDEV rule to assign a particular mount point, or does a unique and reliable mount point get already created in /dev/serial/by-id/, which I can use instead of hacked-udev rules?
It's NOT ALWAYS unique. In my experience, if you bought a cheap arduino clone from China, they mostly didn't bother to generate unique ID for every devices. The same applies for every devices. If the manufacturer didn't bother, then the devices will be identical. I ended up just using the by-path and symlink it.
In my experience using /dev/serial/by-id with USB devices has been unique. That is true as long as the manufacturer follows "the rules" about giving each device a unique serial number.
I just make symlinks to those long names in /dev/serial/by-id and use my symlinks as the handles for my serial devices in scripts. No muss, no fuss, NO UDEV.
The rules for the naming are in
/lib/udev/rules.d/60-persistent-serial.rules
The primary video card usually can be set in the BIOS (option Primary VGA card), and it will be the first card used by the system.
My question is how can I programmatically identify (using a shell script and utilities is preferable) which of my two video cards is the primary card?
Edit: I was hoping that I wouldn't have to elaborate why I need this, because it is a bit complex, but I will explain the problem below.
I have a configuration wizard which allows the dynamic configuration of a multiseat system in a LiveCD, with two independent displays, keyboards and mice, my wizard works in this way:
Start one Xorg server per video card (after generating xorg.conf with the correct PCI bus ID).
Start a ui in each of Xorgs with messages for configuration (press key and press mouse). One seat can be configured each time.
After the first seat is configured, the wizard closes the first Xorg and start the definitive Xorg in this seat with the desktop environment (already with the correct keyboard and mouse set).
The second seat now is able to be configured (press key and mouse), after this pass 3 is repeated for seat two.
The problem is: If I start the first Xorg in the primary video card, everything works, but if I start the first Xorg in the secondary card this is what happens:
The passes 1, 2, and 3 works, but at the end of pass 3, when the Xorg of the first seat is closed, the Xorg of the second seat blinks and doesn't come back, just show a blank screen with a _ cursor at top, the desktop of the first seat loads, but I don't see the wizard screen in the second seat, the first Xorg just comes back if I execute a kill -HUP , and I need to start the ui from it again.
So, it is why I need to identify the primary video card before I can start Xorg (sorry I didn't mention this before). I tested this system in different computers, with different video cards and the behavior is the same. I also tested with the lasted packages of the kernel and Xorg in Ubuntu 12.04 (packages of the raring release).
Assuming X11 is running, you could suppose that primary card is the one used by Xorg... then you might try
ls -l /proc/$(pidof X)/fd |grep /dev/dri
on my system Debian/Sid/x86-64 with Linux 3.12 kernel (which has an Nvidia card on a Intel3770K which also has its VGA) I'm getting /dev/dri/card0 etc...
But you should explain really why you are asking and what problem do you want to solve.... Why does that matter to you?
I am not at all sure that Linux has a notion of primary graphic card like the BIOS knows it.
And probably hwinfo is telling you everything about your graphical cards.
There are several command line tools in Linux that give you human readable information from the BIOS. Maybe you can find your Video boards in there and see which one is made primary. From what I see in my output, it does not look like something says "this is the primary video", but I do see quite a lot of information. You could output that information to a file when video card A is primary, again when B is primary, then compare those two files and see whether there is a difference.
The command I used, which gives me a lot of information, is dmidecode:
sudo dmidecode | less
If you look at the manual page:
man dmidecode
You will notice that the programmers offer a few other similar tools such as biosdecode and vpddecode.
From those you learn that the BIOS information is available from the /dev/mem device. Although you need to be root to read it, if you know the address (I don't) then you could go in there and peek and poke as required to find out where that one information of which video card is defined as the primary video card.
Running dmidecode, there are some details about my motherboard:
Handle 0x0002, DMI type 2, 15 bytes
Base Board Information
Manufacturer: Supermicro
Product Name: X9SCI/X9SCA
Version: 1.01
Serial Number: ZM25U44192
Asset Tag: To be filled by O.E.M.
Features:
Board is a hosting board
Board is replaceable
Location In Chassis: To be filled by O.E.M.
Chassis Handle: 0x0003
Type: Motherboard
Contained Object Handles: 0
Here I have one video entry:
Handle 0x000E, DMI type 10, 6 bytes
On Board Device Information
Type: Video
Status: Enabled
Description: To Be Filled By O.E.M.
Then the other entry looks like this:
Handle 0x0036, DMI type 41, 11 bytes
Onboard Device
Reference Designation: Onboard IGD
Type: Video
Status: Enabled
Type Instance: 1
Bus Address: 0000:00:02.0
It could also be something you need to read from the Flash memory your BIOS uses. This is done with flashrom (that you may need to install):
sudo flashrom --programmer internal --read my-flash.bin
In my case the ROM on my computer is 2Gb of data. So quite large. However, you can be sure that the information you are looking for exists within that data block since that is the only mean for the BIOS to save data that will stay around when the computer gets turned off.
I have found a way how to check the primary GPU when they are from different vendors or at least have different names.
In KDE go to Info Center, then open Graphics -> OpenGL. In Direct Rendering (GLX) and Direct Rendering (EGL) you can see a Driver block. You can see the Vendor and Device there. It will name the GPU which is primary.
At this screenshot you can see that AMD gpu is primary:
Also, you can get that Vendor value programmatically by running
glxinfo | grep "OpenGL vendor string" | cut -f2 -d":" | xargs.
I guess this method will stop working when kde will switch to vulkan for rendering (in kde 6). But for now I do not know another method of determining primary gpu.
I'm trying to adapt an existing SD/MMC card driver to our SD controller hardware. I'm using Synopsys' dw_mmc code (in linux3.3) as a reference. I have a long way to go but at least it's compiled ok and the platform device and platform driver seems to have been registered. My question is how to make the /dev/mmcblk0 file appear in the system? I named our new device ald_sd and I can see ald_sd.0 under /sys/devices/platform. under /dev, I tried 'mknod mmcblk0 179 0' and I see mmcblk0 under /dev. Then I tried 'mount /dev/mmcblk0 /mnt/sd' (after making /mnt/sd) and it gives me message 'mount: mounting /dev/mmcblk0 on /mnt/sd failed: No such device or address'.
Please help. Thank you!
Chan
It's been several months since I sloved this problem. long story short, when the kernel reads the super block of the SD card, then the block access is ok. usually we make /dev/sd0 using mknod command.(not mmcblock0). (mmcblock0 file is made somewhere different maybe /sys.. I don't remember). Also beware, you can mis-type mknod like mkdir or mkdev, then you can have 'No such device or address' message too. Just for your information.
I have several USB mass storage flash drives connected to a Ubuntu Linux computer (Ubuntu 10.04.1, kernel 2.6.32-25-386), and I need to tell them apart programatically (from bash if possible, but I'm not afraid of compiling either) - I need to find which block device corresponds to which physical device (e.g. /dev/sdb1 -> device in USB port 1; in my case, one device ~ one volume).
In other words, I know that I have three hardware devices plugged into USB ports; each of them shows up in the system as a USB mass storage device (as seen with lsusb), is created as a block device (/dev/sdb1) and automounted by UUID (/media/1234-5678).
USB device block device mountpoint
USB device in port 2.2 <-> /dev/sdb1 <-> /media/1234-5678
I'm not trying to find the relationship between block device and mountpoint; I'm trying to find the relationship between block device and USB device, is there a way?
Why? There will be some writes on the disks, with unpredictable time of completion. I need to give the operator some indication like "you can now remove the disk in port 2 (which is second from the left)". I have found which physical port corresponds to which port number on that specific machine, and finding block devices from mountpoints is simple; now I'm stuck mapping the logical USB ports to block devices.
I can see the disks with lsusb :
Bus 001 Device 058: ID 067b:2517 Prolific Technology, Inc. Mass Storage Device
Bus 001 Device 060: ID 067b:2517 Prolific Technology, Inc. Mass Storage Device
Bus 001 Device 061: ID 067b:2517 Prolific Technology, Inc. Mass Storage Device
and I can see them mounted (by their UUID):
/dev/sdb1 on /media/BC88-15C4 type vfat
/dev/sdc1 on /media/AE54-65AA type vfat
/dev/sdd1 on /media/58D2-FED1 type vfat
Now, all the drives are the same model from the same manufacturer, so I can't distinguish them by that, and I can't guarantee they'll be plugged in a particular order.
I have found /sys/bus/usb/devices (a list of USB devices), but it seems to be the same data that I get from lsusb - I don't see a mapping to disks there.
There's also /sys/block/sdb and /sys/block/sdb/sdb1 (the block device and its first partition; similarly for sdc and sdd), but again, I see no mapping to devices.
I'm not sure in which kernel version this was implemented, but the /sys/block/* entries are symlinks to the devices.
In other words, /sys/block/sdb symlinks to a different directory, and its name contains the USB device ID.
$ file /sys/block/sdb
/sys/block/sdb: symbolic link to `../devices/pci0000:00/0000:00:02.1/usb1/1-1/1-1.1/1-1.1:1.0/host31/target31:0:0/31:0:0:0/block/sdb'
USB version and port here---^^^^^
The 1-1.1 is the interesting part, denoting usb1-port 1.device 1. When plugged into a hub, another level is added: 1-2.3.1, denoting usb1-port 2.port 3.device 1.
Pseudocode:
get partition name # e.g. /dev/sdb1
get disk name # that would be /dev/sdb
get your basename # sdb
see where /sys/block/$your_basename points to # e.g. ../devices/blah/blah/1-2.1/blah
get the longest substring matching "\d-\d+(.\d+)*" # e.g. 1-2.1
that is the device id you want
/sys/bus/usb/devices/$device_id/ has all kinds of information about it
the ID corresponds to hardware USB ports
Working example script in bash.
I use the path:
/sys/bus/usb/drivers/usb-storage/4-1:1.0/host4/target4:0:0/4:0:0:0/block/sda
so you can see usb bus 4, port 1 is connected with a usb storage /dev/sda
Can't you use disk labels?
http://ubuntuforums.org/showthread.php?t=322973
Here is how I do it.
lsusb -v shows all the devices disks get an iserial number take note of them
ls -l /dev/disk | grep [iserial]
Everything in /dev/disk is a symlink so follow the symlink to see the device.