How to find the format of a disk volume - macos

I am updating a backup utility I have written and have on the Mac App store.
In a Macintosh Cocoa application, how do I find how a disk volume is formatted? The only official thing I find, is doing a GetResourceValue: for 'NSURLVolumeLocalizedFormatDescriptionKey', but that is language dependent.
My utility does not support volumes formatted for FAT32. My utility needs to do special handling for XSan drives.

statfs(2) will give you a non-localized name:
struct statfs volinfo;
if(statfs("/path/to/your/volume", &volinfo) != 0)
{
perror("statfs");
return -1;
}
fprintf(stderr, "%s\n", volinfo.f_fstypename);
See /System/Library/Filesystems for the names that will be returned in f_fstypename.

This question has been answered but I'll throw my 2 cents in...
/sbin/mount | grep acfs | awk '{print $3}'
This outputs
/Volumes/XsanVolumeName1
/Volumes/XsanVolumeName2

Related

Disconnecting and reconnecting nvme

Is there capacity within amazon/centos/linux to switch the ordering round of nitro disks?
I have an ami which consistently has devices in the incorrect order, by this I mean nvme1n1 and nvme2n1 should be switched round. If I run nvme id-ctrl -v /dev/nvme1n1 | grep sn I get a different serial number back following a reboot. I know they're "wrong" as the serial numbers are not reflective of their capacity... Hope that makes sense (I appreciate it's a bit confusing). This only ever occurs on servers with two or more disks; upon a reboot the disks are "correct"
My question is, is there a method of forcing the nvme device to disconnect and reconnect (in the hope that the mapping works as expected in the correct order).
Thanks guys
Amazon Linux version 2017.09.01 and later contains scripts and a udev rule that automatically maps NVMe devices to /dev/xvd?. It is very briefly mentioned in the documentation, but there is not much information there.
You can obtain a copy by launching the Amazon Linux AMI, but there are also other places on the web where they have been posted. For example, I found this gist.
Very simple in the end:
echo 1 > /sys/bus/pci/devices/$(readlink -f /sys/class/nvme/nvme1 | awk -F "/" '{print $5}')/remove
echo 1 > /sys/bus/pci/devices/$(readlink -f /sys/class/nvme/nvme2 | awk -F "/" '{print $5}')/remove
echo 1 > /sys/bus/pci/rescan

Get physical keyboard layout

Is there a way through command line to know what keyboard physical layout a macbook has? I cannot find that specific information in system_profiler. I want to know if the computer has a US, UK, ES, etc keyboard layout.
The aim is to script it, upload it to my MDM so I can run it in all the company's laptops and find out that information.
Thanks!
running the terminal command system_profiler SPSPIDataType
it shows this:
SPI:
Apple Internal Keyboard / Trackpad:
Product ID: 0x0278
Vendor ID: 0x05ac (Apple Inc.)
ST Version: 8.96
MT Version: 4.69
Serial Number: FM7741701QVGN41A5+RNZ
Manufacturer: Apple Inc.
Location ID: 0x01000000
I run it in two different macbooks, one UK, one ES. I was hoping that the Location ID would show something different but that was not the case.
If I do this in Terminal:
defaults read ~/Library/Preferences/com.apple.HIToolbox.plist AppleSelectedInputSources | egrep -w 'KeyboardLayout Name'
I get this:
"KeyboardLayout Name" = *name of my keyboard in readable form*
I think I just found the solution, like this:
ioreg -l | grep KeyboardLanguage | awk '{print substr( $0, 56, 20)}' | tr -d "\" =|"
Thanks,
Federico.

How to open USB device in OSX

I'm finally able to get the device path ("/dev/rdisk1") - called devname here - after a search but POSIX open() fails with -1. Is this a permission issue? The camera is mounted and can be read normally via /Volumes but I need to access via /dev to control the camera via USB tether.
/* Found PENTAX DIGITAL_CAMERA */
snprintf(pslr.devname, sizeof(pslr.devname), "%s", devpath);
pslr.devname[sizeof(pslr.devname)-1] = '\0';
printf("pslr.devname %s\n", pslr.devname);
pslr.fd = open(pslr.devname, O_RDWR);
if (pslr.fd == -1) {
return NULL;
}
PS: after the discussion below I changed the permissions with sudo chmod command and then tried open but it still fails. I must be missing a step.
I checked with apple support and they say I cannot use posix functions to control a USB device in OS X.

Use AWK to extract just the MAC addresses from a show mac address-table from a cisco switch

I'd need to take the output from a show mac address-table on a Cisco switch and extract only the Mac addresses and put them in a CSV file.
The output looks like this
vlan Mac Address Type Ports
----- ----------- ----- -----
All 0011.2233.4455 STATIC CPU
All 0011.2233.4466 STATIC CPU
All 0011.2233.4477 STATIC CPU
All 0011.2233.4488 STATIC CPU
Macs are displayed in groups of 4 as seen above. I need to grab each MAC address and output it to a csv file.
This works but it also grabs unwanted output.
awk '{print $2}' macTable.log > macTable.csv
Just add a condition that the field only contains digits and dots:
awk '$2~/^[0-9.]+$/{print $2}' macTable.log
You can test for the two types of mac-address STATIC and DYNAMIC
awk 'tolower($3)~/static|dynamic/ {print $2}' log
0011.2233.4455
0011.2233.4466
0011.2233.4477
0011.2233.4488
PS you need to use tolower since switch may use uppercase and routers uses lowercase.
You could also do it with grep:
egrep -o '([0-9]{4}\.){2}[0-9]{4}'
Output:
0011.2233.4455
0011.2233.4466
0011.2233.4477
0011.2233.4488

How can I determine the build/version of Linux kernel 'uImage'?

I'm trying to track down a kernel binary; is there a way to determine the version (build string) of a Linux 'uImage' binary?
Running
strings uImage
piped into various trailing grep statements leads me to think I'm dealing with a compressed image...
According to kernel's format specification, here's C code:
kver.c
#include <stdio.h>
int main(int argc, char** argv){
if (argc > 1){
FILE* f = fopen(argv[1], "r");
short offset = 0;
char str[128];
if(f){
fseek(f, 0x20E, SEEK_SET);
fread(&offset, 2, 1, f);
fseek(f, offset + 0x200, SEEK_SET);
fread(str, 128, 1, f);
str[127] = '\0';
printf("%s\n", str);
fclose(f);
return 0;
}else {
return 2;
}
} else {
printf("use: kver [kernel image file]\n");
return 1;
}
}
compile and run:
gcc -o kver kver.c
./kver /boot/vmlinux-something
To find out what version of Linux is compiled, use the strings utility on the uncompressed vmlinux image.
For example:
strings linux-src/build/build-generic/vmlinux|grep "Linux version"
Sample output:
Linux version 3.2.0-56-generic (root#puerto-cayo) (gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) ) #86 SMP Fri Nov 1 10:24:18 EDT 2013 (Ubuntu 3.2.0-56.86-generic 3.2.51)
I just realized, the kernels I have immediate access to do have the version string stored uncompressed amongst the headers. strings uImage | grep 2.6 ought to be good enough for any 2.6 kernel which covers pretty much everything in the last 5+ years).
(original answer follows)
It's theoretically possible, but not entirely trivial.
Modern Linux kernel versions use a format called bzImage (for x86/x86_64, YMMV on other platforms). It actually consists of an ELF header and some other minutia (like a bit of decompression code) followed by, yes, a compressed image of the actual kernel.
Traditionally, the compression algorithm was zlib (contrary to popular misconception, 'bzImage' did not stand for "bzipped image", but for "big zImage" -- the original zImage format not being able to handle large kernels), though versions after 2.6.30 also support bzip2 and LZMA.
What you'll probably have to do is determine exactly where the compressed data starts (sorry, can't help you there, but trial and error might work), and write a bit of code to run it through the library for whichever compression algorithm is in use.
Try file uImage. It might identify the file format if it is a commonly known compression format. Other than that, the strings utility is probably the best one for this task.
This will output the kernel version and the localversion string (if any was set at build time) on a bzimage:
strings bzimage |grep -E "^[1-4]\.[0-9][0-9]*\.[0-9][0-9]*" |awk '{print $1}' |head -1
I've tested it on kernel versions 3 and 4 ... but it should also work on previous versions too.
strings vmlinuz |grep -E "^[1-4]\.[0-9][0-9]*\.[0-9][0-9]*" |awk '{print $1}' |head -1
4.4.5
strings vmlinux |grep -E "^[1-4]\.[0-9][0-9]*\.[0-9][0-9]*" |awk '{print $1}' |head -1
3.2.45-smp
If you have uImage you will haveto remove the "^" or it will not match anything
strings uImage |grep -E "[1-4]\.[0-9][0-9]*\.[0-9][0-9]*" |head -1
Linux-3.0.76
I am not sure however you might try uname -a may be this is what you want.
If it is a kernel for x86, it has the version in the header. See Documentation/x86/boot.txt (look at the kernel_version field).
I do not know if the same is true for other architectures (that header is x86-specific).

Resources