Mapping 2 USB devices to defined path - linux

I've listed my USB devices to their serial ports by searching for them.
ls -l /dev/ttyACM*
However as I plug and unplug the USB devices (Conbee II & Z-Stick Gen 5+) they swap ports causing my containers to crash as I restart.
Any way to map these to a specific path?
I tried to set the variables inside the container to be mapped to the specific devices as I list them with the ls command. After I do so, they tend to swap around however.

Instead of using /dev/ttyACM*, use the symbolic links that the kernel creates for you in /dev/serial/by-id.

Related

lm75 kernel module available in userspace

I'm using the lm75 kernel module to interact with a sensor on a custom board. Every things works fine, I have my device mounted in /sys/bus/i2c/devices/5-0048. But I would like to let the user set the max temp hysteresis so in other words let the user write into the temp_max_hyst file. The permission for this file is read only except for root
My question is, is there any way to mount my device in /dev?
Mounting isn't the right term here so you won't find anything searching for that. Block devices with file systems are mounted on directories, which then become mount points.
Here the device 5-0048 is bound to the driver lm75. You'd find the device is there, assuming it appears in the device tree or board info, whether or not the lm75 driver exists. If and when the lm75 driver binds to the device, it creates a new device of class hwmon. It is that device which has attributes, like temp_max_hyst, that you are interested in.
What you see in /dev are known as device nodes. While many devices, once bound to a driver, will have a device node created to interact with the device, this doesn't have to happen. There are probably a bunch of devices that appear in /sys/class/regulator or /sys/class/net that have no nodes in /dev associated with them.
Drivers of type hwmon, like lm75, don't normally create any device nodes to provide a char device or block device userspace interface to the hardware. So there is nothing to appear in dev for this device. The attributes of the hwmon device are all you get.
But your problem has a simple solution. As root, just chmod a+w temp_max_hyst or chown user_account temp_max_hyst or (this is probably best) chmod g+w temp_max_hyst ; chgrp hw_access_group temp_max_hyst and add the user to a group hw_access_group. You could use an existing group, there might be one named wheel or adm that would be used for something like this, or make a new one just for hwmon access.
Of course this won't persist across a reboot, as sysfs is not a real file system on disk. To make the change persistent, the best way is to create a udev rule that automatically effects the chmod/chown when it detects the hwmon device. It's the hwmon device you care about here, not the i2c device. Try running udevadm info -a /sys/class/hwmon/hwmon0.

udev usb everytime different path

I have following problem with my Linux board:
My USB media device every time mounted as different device in /dev/ folder:
First time I attach the USB, it appears as
/dev/sdb1
Then, I remove usb and plug it in again and it gets different name:
/dev/sdc1
And so on and so forth.
I want it to have constant name always, so I wrote following udev rule:
SUBSYSTEM=="block",ENV{ID_SERIAL}==" serial id ",NAME="myusbmedia"
This rule doesn't work. I could have symbolic name with following rule:
SUBSYSTEM=="block",ENV{ID_SERIAL}==" serial id ",SYMLINK="myusbmedia"
This rule works, but it doesn't solve the problem, because usb still gets /dev/sd[b,c,d, ...] names...
Does anyone have an idea how to make USB appear in /dev/ under the same device node with the same name?
When you connect your device, i assume you use mount in order to approach its files.
You should unmount the drive (using the umount command) before you disconnect it, and then it should stay as the same device at the /dev folder.
For example:
umount /dev/sdc1
The problem is unsolvable, at least using udev. The device node is created by the kernel, not by udev. So you need to modify the kernel.
From man page udev(7):
The following keys can get values assigned:
NAME
The name to use for a network interface. The name of a device
node cannot be changed by udev, only additional symlinks
can be created.
See also http://lists.kernelnewbies.org/pipermail/kernelnewbies/2015-April/013889.html
Something in that direction has been proposed to the kernel, but it has not been accepted into mainline Linux http://thread.gmane.org/gmane.linux.scsi/70947

Open physical drive from Linux

I'd like to open SD card as physical drive on Linux.
Somethink like:
CreateFile("PHYSICALDRIVE0",...)
On MS Windows.
How can I do it?
All devices are represented as files under the /dev directory. These files can be opened exactly like regular files, e.g. open(/dev/sdb, ...).
Disk-like devices are also symlinked in the directories /dev/disk/by-id/, /dev/disk/by-path, and /dev/disk/by-uuid, which makes it much easier to find to matching device file.
Type df, to list all your filesystems mounted or unmounted. Once you know its address(everything in Linux is a file, so it will look like /dev/sda# or something like that) you can mount it with the mount command:
mount /path/to/drive /folder/to/mount/to
You open the block device special file (typically something like /dev/sdb) and then you can read/write blocks from it.
The interface is not clearly documented, it is a bug that there is no block(4) man page.
The sd(4) man page does help a bit though. The ioctls described there are probably valid for (some) other block devices as well.
Nowadays nearly all block devices appear as a "scsi drive" regardless of whether they are actually attached by scsi or not. This includes USB and (most) ATA drives.
Finding the right device to open may be a big part of the problem though, particularly if you have hotplug devices. You might be able to interrogate some things in /sys to find out what devices there are.

Linux: How to map a blockdevice to a USB-device?

if I plugin a USB memory stick, I see a new folder in /sys/bus/usb/devices ... thus a new USB-device.
Also I see a new folder in /sys/block ... thus a new block-device.
My question is: How can I get a waterproof mapping between those two devices? Means:
If I get a new device in /sys/bus/usb/devices, how can I programatically (f.i. by checking /sys/...) find out which block device is mapped/related to this usb-device and vice-versa?!
The information in /sys is organized in multiple ways (by driver, by bus, etc.), and there are many symbolic links to go from one hierarchy to another.
Case in point (example seen on kernel 2.6.26): starting from the block device in /sys/block/sdc, the symbolic link /sys/block/sdc/device points inside the per-device-type hierarchy. You can see that it's an USB device because the target of the link is something like
../../devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2:1.0/host9/target9:0:0/9:0:0:0
Conversely, USB devices are listed in /sys/bus/usb/devices, and we can see that 8-2:1.0 is a disk-like device because /sys/bus/usb/devices/8-2:1.0/driver links to usb-storage. To find out what the associated block device is, it seems we need to go down to the directory /sys/bus/usb/devices/8-2:1.0/host9/target9:0:0/9:0:0:0 which contains a symbolic link block:sdc whose target is /sys/block/sdc.
ADDED: Caution: the exact structure of /sys changes from kernel version to kernel version. For example, with kernel 2.6.32, /sys/block/sdc/device points directly into the /dev/bus/scsi without going through the USB hop.
A different approach is to call the udevadm info command. udevadm info -p /sys/block/sdc --query=… gives information on a device based on its /sys entry, while udevadm info -n sdc --query=… gives information on the device /dev/sdc.
The information includes bus information, for example udevadm info -p /sys/block/sdc --query=env shows
ID_BUS=usb
ID_PATH=pci-0000:00:1d.7-usb-0:2:1.0-scsi-0:0:0:0
The udev documentation may have more information of interest to you.
A final word of caution: there are all kinds of complex cases that may make whatever you do not so waterproof. How will your program deal with a single USB device that is an array of disks that are assigned multiple block devices? Conversely, how will your program deal with a RAID array assembled from multiple devices (perhaps some of them USB and some of them not)? Do you care about other removable media types such as Firewire and e-SATA? etc. You won't be able to predict all corner cases, so make sure to fail gracefully.
As far as I found out, it's possible to access udev information via "libudev" library. There's also a good sample on the net available: http://www.signal11.us/oss/udev/
I was able to modify it to read out all "/dev/sd*" devices and get their Vendor-ID, Product-ID as well as Serial number. I think this solution is kernel/linux distribution independant enough. But I still have to verify this.

Is there a way to check if an USB drive is stopped?

I've written a script to backup my server's HD every night. At the end of the script, I sync, wait a couple of minutes, sync and then I issue sg_start --stop to stop the device. The idea is to extend the lifetime of the device by switching the HD off after ten minutes of incremental backup (desktop disks will survive several thousand on/off cycles but only a few hundred hours of continuous running).
This doesn't always work; I often find the drive still spinning the next morning. Is there a shell command which I can use to check that the drive has stopped (so I can issue the stop command again [EDIT2]or write a script to create a process list when the drive is running so I can debug this[/EDIT2])?
[EDIT] I've tried sg_inq (as suggested by the sg_start man page) but this command always returns 0.
I've tried hdparm but it always returns "drive state is: unknown" for USB drives (attached via /dev/sdX) and when trying to spin down the drive, I get "HDIO_DRIVE_CMD(setidle1) failed: Input/output error".
sdparm seems to support to set the idle timer on the drive (see "Power mode condition page") but the IDLE option has "Changeable: n" and I haven't found an option which tells me the drive power state.
[EDIT2] Note: I can stop the drive with sg_start --stop from the console. That always works; it just doesn't always stay down until midnight. The sever is in the basement (where it's nice and cool) and I'd rather have a way to check whether the drive is up or not from the warm living room :) If I had a command which told me the status of the drive, I could write a script to alert me when it spins up (check every minute) and then I could try to figure out what might be causing this.
If that matters: I'm using openSUSE 11.1.
When you say you've tried hdparm, you haven't said what you have tried. I have some usb hard drives in an enclosure, and some of the commands work for it and others don't, but I guess it all depends on all facets of the transport mechanism.
hdparm -S 120 /dev/sda
Should tell the drive to sleep itself after ~10 minutes of inactivity.
I'm guessing you have already tried this, but its not obvious, and writing this as an answer may help a future reader.
Nothing accesses the drive but the backup script.
This is nice in theory, but I have found on odd occasions this is not enough. There are lots of processes and tasks that if they even look at the drive a spin up may occur if the lookup is for some reason out of the disk-cache.
Common culprits are tools like updatedb scanning all mounts for files, and fam or gamin doing funky stuff to monitor disks for changes.
If in doubt, add a layer of certainty by mounting the device before executing the script, and unmounting it when you are done.
Seeing things that could cause a wakeup
lsof +D /mountpoint
You should probably parse the output of this as well before attempting to unmount to be sure that nothing is still trying to use it.
You should probably also be doing a lazy umount,
umount -l /mountpoint
so if anything accesses it between you doing lsof| grep and calling umount, it will still unmount the drive and stop things being able to read it.
HAL and friends
Its also possible that HAL and friends are doing wakeups to the drive probing for connect/removal state. I really hope it isn't, but it does that on some device types. It seems an unlikely cause, but I'll consider anything possible.
Try fun stuff like
lsof /dev/devicehere
and
lsof /dev/devicehere1
Which appears to get a comprehensive list of all things that would be accessing the handle either directly or indirectly.
You also need to check the mount options and use "noatime" as a mount option, otherwise the kernel still updates the access times periodically. So this may be the cause of your problem too.
If hdparm returns this:
drive state is: unknown
And smartctl returns this:
CHECK POWER MODE: incomplete response, ATA output registers missing
CHECK POWER MODE not implemented, ignoring -n option
Then it is not possible to obtain the usb drive sleep status. I tried multiple creative things like the USB power consumption or monitoring file access, but I found nothing to verify the drive's state.
The only solution is to replace the USB SATA adapter (or enclosure) against one with a different USB bridge chip. The one that did not work for me, used the JMicron JMS567 (152d:0578 / 0x152d 0x0578) which could be perhaps updated, but I was not able to test it as the update tool needs an ARM CPU. Now I'm using two different adapters which both use the Asmedia ASM1051E / ASM1053E / ASM1153 / ASM1153E and they passthrough all commands.
You can check the bridge chip of your USB SATA adapter / enclosure as follows:
lsusb -v | grep -E ': ID |idVendor|idProduct'
Which returns something like:
Bus 002 Device 003: ID 174c:55aa ASMedia Technology Inc. ASM1051E SATA 6Gb/s bridge, ASM1053E SATA 6Gb/s bridge, ASM1153 SATA 3Gb/s bridge
idVendor 0x174c ASMedia Technology Inc.
idProduct 0x55aa ASM1051E SATA 6Gb/s bridge, ASM1053E SATA 6Gb/s bridge, ASM1153 SATA 3Gb/s bridge
I often find the drive still spinning the next morning.
Couldn't this just be because it was spun up again when the server eg. wrote to a log file or something during the night? You might try sdparm, which can return status information on a drive. But I think it's better to just set the option in your BIOS that lets your HD automatically spin down after an amount of inactivity, it's easier.
Have you tried stopping the drive with the following command:
eject -t /dev/yourHD
This works quite good for my USB hard drives.
If hdparm -C /dev/sda said drive state is: unknown than it's not supported for your drive and there is no way to tell
Your additional questions (answered by others already)
what's using a drive?
lsof
fuser
triggers
how to force a drive to stay sleeping?
hdparm
umount
your device can still be woken when unmounted but likely only by something you do (smartctl, blkid, etc)
Related: you can also automatically pause backup or whatever for an hour if your drives get to hot.

Resources