Cygwin: open a character device - cygwin

I need to open a kernel module created in Windows with a userland program
compiled in Cygwin; from Windows I can open it by using
CreateFile("\\\\.\\deviceName",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL)
but in Cygwin if I try to use the
open("//deviceName", O_RDWR);
nothing happens; I've tried to use "\DosDevices\deviceName", //deviceName,
//DosDevices/deviceName etc.... but I'm unable to open the device.
There is a way to do this in Cygwin or I must use the CreateFile in the
userland application?
EDIT:
FYI in the kernel module the link is created this way after calling correctly a IoCreateDevice(....)
#define DOS_DEVICE_NAME L"\\DosDevices\\deviceName"
...
RtlInitUnicodeString( &ntWin32NameString, DOS_DEVICE_NAME );
ntStatus = IoCreateSymbolicLink(&ntWin32NameString, &ntUnicodeString );
....
EDIT2:
Using Sysinternals WinObj I can correctly see my device under
\GLOBAL?? with the symlink \Device\deviceName

Ok, it seems that I've been able to find it: it is specified under
"/proc/sys/DosDevices/Global/deviceName"
and can be opened with
fd = open("/proc/sys/DosDevices/Global/deviceName", O_RDWR);

Related

How to do file inputs via node.js using emscripten?

I have a C++ project that I have converted into javascript using emscripten. I need help with implementing file input into the program via node. As I understand it the default file system in emscripten uses preloaded data that can only be done on a web page or web worker. I need mine to work with node.js on the command line.
Looking at the documentation I see that there's a way to use NODEFS instead of the default MEMFS which should allow me to do this. However, I'm unsure how I'm supposed to go about this. I don't really understand the test code that's provided.
Here's how the file handling is being done in the original C++ project:
void InputFile(std::string &fileName)
{
std::ifstream in(fileName);
if (in.fail())
{
std::cerr << "ERROR, Could not open " << fileName << std::endl;
exit(1);
}
}
But when I attempt to run the converted program with a file, node project.js -f test.file I get the error message: ERROR, Could not open test.file meaning that opening the file failed. The original C++ project was able to open the file without any issues, so I know there's not problem with the file itself.
I'm not sure what I have to do to make the converted project work with file inputs, any help would very much appreciated.
Explanation
WebAssembly module, built using emscripten, has no information about files in your physical file system. Instead, it uses a virtual file system. All you have to do is to create a link between files on your physical system to the files on the module's virtual system. NODEFS gives you this opportunity.
Quick solution
We will start at modifying your C++ code by adding the aforementioned link between physical and virtual file systems using embedded JS code (with EM_ASM). First (1), we create a directory '/temp' on the virtual file system where all referenced files will be located in. Then (2), we link this new virtual directory with a real physical location (the current working directory '.') where all the referenced files are already.
#include <emscripten.h>
#include <emscripten/bind.h>
#include <iostream>
#include <fstream>
void InputFile(const std::string &fileName)
{
EM_ASM(
FS.mkdir('/temp'); // (1)
FS.mount(NODEFS, {root : '.'}, '/temp');); // (2)
std::ifstream in(std::string("/temp/") + fileName);
if (in.fail())
{
std::cerr << "ERROR, Could not open " << fileName << std::endl;
exit(1);
}
}
EMSCRIPTEN_BINDINGS(Module)
{
emscripten::function("InputFile", &InputFile);
}
Now, because in the WebAssembly module, we are working with the virtual file systems, and not the physical one, each referenced file from the current directory (the root '.') is actually in the virtual directory previously linked ('/temp'). Hence, '/temp' directory precedes the name to the referenced file: std::ifstream in(std::string("/temp/") + fileName);.
Finally, we can compile this file. We force the synchronized compilation (to make sure the require loads the WASM module on time). Moreover, the option -s EXIT_RUNTIME=1 makes sure that the C++ command exit(1); finishes the execution. Also, we need to link Embind (--bind) and NODEFS (-lnodefs.js):
emcc project.cpp -o project.js -s WASM_ASYNC_COMPILATION=0 -s EXIT_RUNTIME=1 --bind -lnodefs.js
Testing
To test the WebAssembly module with the same calling convention as you have mentioned, we can use the following test.js script:
var Module = require('./project.js');
if (process.argv[3] && process.argv[2] === '-f') {
const filename = process.argv[3];
Module.InputFile(filename);
} else {
console.log('Pass the file with -f flag!');
}
To run the file, all you have to do is this: node test.js -f test.file
Comment
This approach works well if the referenced files are in the current working directory. In the case they are not, you could modify the code of the InputFile to extract the directory in which the fileName is, and then, mount the real-to-virtual directory accordingly.

docker, openmpi and unexpected end of /proc/mounts line

I have build environment to run code in a Docker container. One of the components is OpenMPI, which I think is the source of problem or manifest it.
When I run code using MPI I getting message,
Unexpected end of /proc/mounts line `overlay / overlay rw,relatime,lowerdir=/var/lib/docker/overlay2/l/NHW6L2TB73FPMK4A52XDP6SO2V:/var/lib/docker/overlay2/l/MKAGUDHZZTJF4KNSUM73QGVRUD:/var/lib/docker/overlay2/l/4PFRG6M47TX5TYVHKQQO2KCG7Q:/var/lib/docker/overlay2/l/4UR3OEP3IW5ZTADZ6OKT77ZBEU:/var/lib/docker/overlay2/l/LGBMK7HFUCHRTM2MMITMD6ILMG:/var/lib/docker/overlay2/l/ODJ2DJIGYGWRXEJZ6ECSLG7VDJ:/var/lib/docker/overlay2/l/JYQIR5JVEUVQPHEF452BRDVC23:/var/lib/docker/overlay2/l/AUDTRIBKXDZX62ANXO75LD3DW5:/var/lib/docker/overlay2/l/RFFN2MQPDHS2Z'
Unexpected end of /proc/mounts line `KNEJCAQH6YG5S:/var/lib/docker/overlay2/l/7LZSAIYKPQ56QB6GEIB2KZTDQA:/var/lib/docker/overlay2/l/CP2WSFS5347GXQZMXFTPWU4F3J:/var/lib/docker/overlay2/l/SJHIWRVQO5IENQFYDG6R5VF7EB:/var/lib/docker/overlay2/l/ICNNZZ4KB64VEFSKEQZUF7XI63:/var/lib/docker/overlay2/l/SOHRMEBEIIP4MRKRRUWMFTXMU2:/var/lib/docker/overlay2/l/DL4GM7DYQUV4RQE4Z6H5XWU2AB:/var/lib/docker/overlay2/l/JNEAR5ISUKIBKQKKZ6GEH6T6NP:/var/lib/docker/overlay2/l/LIAK7F7Q4SSOJBKBFY4R66J2C3:/var/lib/docker/overlay2/l/MYL6XNGBKKZO5CR3PG3HIB475X:/var/lib/do'
That message is printed for code line
MPI_Init(&argc,&argv);
To make the problem more complex to understand, a warning message is printed only when the host machine is mac os x, for linux host all is ok.
Except for warning message all works fine. I do not know how OpenMPI and docker well enough how this can be fixed.
This is likely due to your /proc/mount file having a line in it greater than 512 characters, causing the hwloc module of OpenMPI to fail to parse it correctly. Docker has a tendency to put very long lines into /proc/mounts. You can see the bug in openmpi-1.10.7/opal/mca/hwloc/hwloc191/hwloc/src/topology-linux.c:1677:
static void
hwloc_find_linux_cpuset_mntpnt(char **cgroup_mntpnt, char **cpuset_mntpnt, int fsroot_fd)
{
#define PROC_MOUNT_LINE_LEN 512
char line[PROC_MOUNT_LINE_LEN];
FILE *fd;
*cgroup_mntpnt = NULL;
*cpuset_mntpnt = NULL;
/* ideally we should use setmntent, getmntent, hasmntopt and endmntent,
* but they do not support fsroot_fd.
*/
fd = hwloc_fopen("/proc/mounts", "r", fsroot_fd);
if (!fd)
return;
This can be fixed by increasing the value of PROC_MOUNT_LINE_LEN, although that should be considered a temporary workaround.
This issue should be fixed in hwloc since 1.11.3 (released 2 years ago). You can either upgrade to OpenMPI 3.0 which contains a hwloc 1.11.7 >= 1.11.3. Or recompile OpenMPI to use an external hwloc instead of the old embedded one.

How to get NReco.PdfGenerator.LT working with Linux binaries?

I'm using NReco.PdfGenerator.LT to create a PDF document from a HTML page. This works fine on windows if I just point it at the wkhtmltopdf.exe executable, but this does not have the same effect on Linux.
HtmlToPdfConverter cvt = new HtmlToPdfConverter();
cvt.PdfToolPath = GetPdfToolPath();
// Windows: <current-dir>\wkhtmltopdf\win32\bin
// Linux: <current-dir>/wkhtmltopdf/linux/bin
cvt.WkHtmlToPdfExeName = GetPdfToolName();
// Windows: wkhtmltopdf.exe
// Linux: wkhtmltopdf
I just get this error:
Cannot generate PDF: Permission denied
Possible reasons of this error:
linux user who starts .net core program has no permissions to run "wkhtmltopdf". Also ensure that "wkhtmltopdf" file is marked as "executable" (x).
sometimes temp folder returned by Path.GetTempPath() is not accessible; another location for temp files may be specified with HtmlToPdfConverter.TempFilesPath property

initramfs init has generated signal 11 but has no handler for it

I built an embedded Linux kernel 2.6.19 on powerpc MPC860 CPU. I created a initramfs.cpio with only one "init" file in the / directory(no other files and no other directories). The init is cross-compiled to an elf format file. The init only set int i=0 and return 0.
All I want to do is to make sure the kernel can successfully call this init. Then I will add more stuff in the file system later.
But the serial port output error message "init has generated signal 11 but has no handler for it".
I have BDM interface connected to the board. The serial port is OK. gdb is OK. I cannot set breakpoint to the kernel_execve() because I use u-boot "bootm " command to boot the kernel.
Is there any method to debug it?

Reserving physical memory space as early as possible in Linux boot-time

I am trying to find a way to reserve physical memory for a proprietary memory type hardware as early as possible after system boots up (Linux CentOs with Intel Xeon server platform).
I did the following at setup_arch() in arch/x86/kernel/setup.c and it works, but found out that I am not allowed to patch the kernel. The requirement is no BIOS and kernel mod.
setup_arch()
{
....
// Calls a proprietary function that returns custom proprietary memory module's starting address and size.
memblock_reserve(mem_start_addr, mem_size);
.....
}
I cannot use memmap=xx/xx either at Grub, because the start and size of the device is unknown (it has to be "discovered" by software)
Is there any way to do this?
One idea is to write a custom grub module and set memmap=xx using it.
The following is how to do it.
Note that following method only works above CentOS 7 since CentOS 6.x or below uses grub 0.9x .
In that case, you may have to modify code of grub 0.9x and replace /boot/grub/stage1 or /boot/grub/stage2
$ git clone git://git.savannah.gnu.org/grub.git
$ cd grub
$ git checkout grub-2.02-beta2 # CentOS 7 currently uses grub-2.02-beta
$ vim grub-core/Makefile.core.def # add following row
module = {
name = my_custom_module;
common = lib/my_custom_module.c;
};
$ vim grub-core/lib/my_custom_module.c # create following file
#include <grub/dl.h>
#include <grub/env.h>
GRUB_MOD_LICENSE ("GPLv3+");
GRUB_MOD_INIT(my_custom_module){
// Calls a proprietary function that returns custom proprietary memory module's starting address and size.
const char *mem_size = "123";
grub_env_set("my_memsize",mem_size);
}
GRUB_MOD_FINI(my_custom_module){
}
$ ./autogen.sh
$ ./configure
$ make
Now you can find that grub-core/my_custom_module.mod is created.
so copy it to /boot/grub2/i386-pc/ (or whatever your *.mod file exists)
Edit the grub.conf and add something like
insmod my_custom_module
linux /boot/vmlinuz-3.10.el7.x86_64 root=UUID=1a3b5c7d9 ro memmap=${my_memsize}

Resources