mount interview questions
Top mount frequently asked interview questions
I am trying to create bindings to the FUSE library using JNA, but I have hit a snag along the road. I have minimized the code as much as possible to make it digestible here.
The FUSE library comes with a few example filesystems written in C. The simplest of them is hello.c
. The following is a minimized version of its code to simply a few prints in the filesystem functions:
hello.c
:
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU GPL.
See the file COPYING.
gcc -Wall hello.c -o hello `pkg-config fuse --cflags --libs`
*/
#define FUSE_USE_VERSION 26
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
static int hello_getattr(const char *path, struct stat *stbuf)
{
printf("getattr was called\n");
return 0;
}
static int hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi)
{
printf("readdir was called\n");
return 0;
}
static int hello_open(const char *path, struct fuse_file_info *fi)
{
printf("open was called\n");
return 0;
}
static int hello_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi)
{
printf("read was called\n");
return 0;
}
static struct fuse_operations hello_oper = {
.getattr = hello_getattr,
.readdir = hello_readdir,
.open = hello_open,
.read = hello_read,
};
int main(int argc, char *argv[])
{
return fuse_main_real(argc, argv, &hello_oper, sizeof(hello_oper), NULL);
}
This can be compiled using gcc -Wall hello.c -o hello -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse -pthread -lfuse -lrt -ldl
And invoked with ./hello.c -f /some/mount/point
The -f
flag is to make it stay in the foreground so that you can see the printf()
's working.
All of this works well, you can see the printf()
's executing properly. I am trying to replicate the same thing in Java using JNA. Here is what I came up with:
FuseTemp.java
:
import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
public class FuseTemp
{
public static interface Fuse extends Library
{
int fuse_main_real(int argc, String[] argv, StructFuseOperations op, long size, Pointer user_data);
}
@SuppressWarnings("unused")
public static class StructFuseOperations extends Structure
{
public static class ByReference extends StructFuseOperations implements Structure.ByReference
{
}
public Callback getattr = new Callback()
{
public int callback(final String path, final Pointer stat)
{
System.out.println("getattr was called");
return 0;
}
};
public Callback readlink = null;
public Callback mknod = null;
public Callback mkdir = null;
public Callback unlink = null;
public Callback rmdir = null;
public Callback symlink = null;
public Callback rename = null;
public Callback link = null;
public Callback chmod = null;
public Callback chown = null;
public Callback truncate = null;
public Callback utime = null;
public Callback open = new Callback()
{
public int callback(final String path, final Pointer info)
{
System.out.println("open was called");
return 0;
}
};
public Callback read = new Callback()
{
public int callback(final String path, final Pointer buffer, final long size, final long offset, final Pointer fi)
{
System.out.println("read was called");
return 0;
}
};
public Callback write = null;
public Callback statfs = null;
public Callback flush = null;
public Callback release = null;
public Callback fsync = null;
public Callback setxattr = null;
public Callback getxattr = null;
public Callback listxattr = null;
public Callback removexattr = null;
public Callback opendir = null;
public Callback readdir = new Callback()
{
public int callback(final String path, final Pointer buffer, final Pointer filler, final long offset,
final Pointer fi)
{
System.out.println("readdir was called");
return 0;
}
};
public Callback releasedir = null;
public Callback fsyncdir = null;
public Callback init = null;
public Callback destroy = null;
public Callback access = null;
public Callback create = null;
public Callback ftruncate = null;
public Callback fgetattr = null;
public Callback lock = null;
public Callback utimens = null;
public Callback bmap = null;
public int flag_nullpath_ok;
public int flag_reserved;
public Callback ioctl = null;
public Callback poll = null;
}
public static void main(final String[] args)
{
final String[] actualArgs = { "-f", "/some/mount/point" };
final Fuse fuse = (Fuse) Native.loadLibrary("fuse", Fuse.class);
final StructFuseOperations.ByReference operations = new StructFuseOperations.ByReference();
System.out.println("Mounting");
final int result = fuse.fuse_main_real(actualArgs.length, actualArgs, operations, operations.size(), null);
System.out.println("Result: " + result);
System.out.println("Mounted");
}
}
The definition of the the fuse_operations
struct can be found here.
This can be compiled using: javac -cp path/to/jna.jar FuseTemp.java
And invoked using java -cp path/to/jna.jar:. FuseTemp
jna.jar is available here.
The error that comes up is: fusermount: failed to access mountpoint /some/mount/point: Permission denied
.
I am executing both programs as the same user with the same permissions on the same mountpoint folder, and I am in the fuse
group. I am using:
- Linux kernel 3.0.0
- FUSE 2.8.4
- OpenJDK 1.6.0_23
- JNA 3.4.0
So my question is: What exactly is different between these two programs (hello.c
and FuseTemp.java
), and how to make them do the same thing?
Thanks in advance.
Edit: Here is some additional info.
Initial stat
of the mountpoint:
File: `/some/mount/point'
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 803h/2051d Inode: 540652 Links: 2
Access: (0777/drwxrwxrwx) Uid: ( 1000/ myusername) Gid: ( 1000/ myusername)
Output I get from running the Java program as regular user:
Mounting
fusermount: failed to access mountpoint /some/mount/point: Permission denied
Result: 1
Mounted
(program exits with return code 0)
After this, trying to execute stat
gives the following error message:
stat: cannot stat
/some/mount/point': Transport endpoint is not connected`
That is because the Java program isn't running anymore, so fuse cannot call its callbacks. To unmount, if I try fusermount -u /some/mount/point
, I get:
fusermount: entry for /some/mountpoint not found in /etc/mtab
And if I try sudo fusermount -u /some/mount/point
, the mountpoint is successfully unmounted and there is no output from fusermount
. /etc/mtab
is chmod'd 644 (-rw-r--r--
) so my user can read it, but it doesn't contain /some/mount/point
. After a successful unmount, the mountpoint is back to its old permissions (777 directory).
Now, running the java program as root:
Mounting
Result: 1
Mounted
(program exits with return code 0)
After that, stat
ing /some/mount/point
shows that is has not been modified, i.e. it is still a 777 directory.
I have also rewritten FuseTemp.java
to include all Callback
s as Callback
s instead of Pointer
s. The behavior is the same, however.
I looked at fuse's source code and the error code 1 can be returned at multiple points throughout the execution. I will pinpoint where exactly is it failing on the fuse side and report back here.
Now for hello.c
: running it as regular user, starting with the same permissions on /some/mount/point
and passing it the arguments -f
and /some/mount/point
, the program doesn't print any output at first but keeps running. When running stat
on the mountpoint, the program prints
getattr was called
like it should. stat
returns an error, but that's simply because hello.c
's getattr
function doesn't give it any information, so no problems there. After executing fusermount -u /some/mount/point
as regular user, the program exits with return code 0 and the unmount is successful.
Running it as root, starting with the same permissions on /some/mount/point
and passing it the arguments -f
and /some/mount/point
, the program doesn't print any output at first but keeps running. When running stat
on the mountpoint, I get a permission error because I am not root. When running stat
on it as root, the program prints
getattr was called
like it should. Executing fusermount -u /some/mount/point
as regular user yields
fusermount: entry for /some/mount/point not found in /etc/mtab
Executing fusermount
as root, the program exits with return code 0 and the unmount is successful.
Source: (StackOverflow)
How can I format a partition with exFAT format in Ubuntu 11.04?
When I mount a exFAT partition using command 'mount /dev/sdb1 /mnt', it is said that I need to specify the file system, and then I think it needs to add '-t' option to do that, so I modify the command 'mount -t exfat /dev/sdb1 /mnt', but it is said there is no exfat file system, so I want to know how to mount a exFAT partition in Ubuntu 11.04?
Source: (StackOverflow)
I have an NFS-mounted directory on a Linux machine that has hung. I've tried to force an unmount, but it doesn't seem to work:
$ umount -f /mnt/data
$ umount2: Device or resource busy
$ umount: /mnt/data: device is busy
If I type "mount
", it appears that the directory is no longer mounted, but it hangs if I do "ls /mnt/data
", and if I try to remove the mountpoint, I get:
$ rmdir /mnt/data
rmdir: /mnt/data: Device or resource busy
Is there anything I can do other than reboot the machine?
Source: (StackOverflow)
Is it possible to mount a local directory into another one? Using Perforce, I want to do something equivalent to symlinking a directory, but in a way that fools it into thinking it's really just another directory in the project.
I would like to do something like:
mount /foo/bar /home/foo/bar
Is this possible, and if so what options do I need to give it?
Source: (StackOverflow)
I'm just having trouble with getting my emulator SD card work...
I created a new AVD device with a new SD card.
So how to put data onto it? I found the "correct" file to be mounted on Daemon tools, but is corrupt or simply not readable...
It would be great if you have any idea :)
Source: (StackOverflow)
FUSE is constantly(every 2 - 3 days) giving me this Transport endpoint is not connected
error on my mount point and the only thing that seems to fix it is rebooting.
I currently have my mount points setup like this, I'm not sure what other details I should add here so let me know if I missed anything..
/dev/sdc1 /mnt/hdd2 ext4 defaults 0 0
/dev/sdb1 /mnt/hdd1 ext4 defaults 0 0
mhddfs#/mnt/hdd1,/mnt/hdd2 /data fuse defaults,allow_other 0 0
Source: (StackOverflow)
I have a CIFS share from Windows Server 2012 R2 mounted on Ubuntu 14.04.2 LTS (kernel 3.13.0-61-generic) like this
/etc/fstab
//10.1.2.3/Share /Share cifs credentials=/root/.smbcredentials/share_user,user=share_user,dirmode=0770,filemode=0660,uid=4000,gid=5000,forceuid,forcegid,noserverino,cache=none 0 0
The gid=5000
corresponds to group www-data
which runs a PHP process.
The files are mounted correctly when I check via the console logged in as the www-data
user - they are readable and removable (the operations that are used by the PHP script).
The PHP script is processing about 50-70 000 files per day. The files are created on the host Windows machine and some time later the PHP script running on the Linux machine is notified about a new file, checks if the file exists (file_exists
), reads it and deletes. Usually all works fine, but sometimes (a few hundreds to 1-2 000 per day) the PHP script raises an error that the file does not exist. That should never be the case, since it is notified only of actually existing files.
When I manually check those files reported as not existing, they are correctly accessible on the Ubuntu machine and have a creation date from before the PHP script checked their existence.
Then I trigger the PHP script manually to pick up that file and it is picked up without problems.
What I already tried
There are multiple similar questions, but I seem to have exhausted all the advices:
- I added
clearstatcache()
before checking file_exists($f)
- The file and directory permissions are OK (exactly the same file is picked up correctly later on)
- The path used for checking
file_exists($f)
is an absolute path with no special characters - the file paths are always of format /Share/11/222/333.zip
(with various digits)
- I used
noserverino
share mount parameter
- I used
cache=none
share mount parameter
/proc/fs/cifs/Stats/
displays as below, but I don't know if there is anything suspicious here. The share in question is 2) \\10.1.2.3\Share
Resources in use
CIFS Session: 1
Share (unique mount targets): 2
SMB Request/Response Buffer: 1 Pool size: 5
SMB Small Req/Resp Buffer: 1 Pool size: 30
Operations (MIDs): 0
6 session 2 share reconnects
Total vfs operations: 133925492 maximum at one time: 11
1) \\10.1.2.3\Share_Archive
SMBs: 53824700 Oplocks breaks: 12
Reads: 699 Bytes: 42507881
Writes: 49175075 Bytes: 801182924574
Flushes: 0
Locks: 12 HardLinks: 0 Symlinks: 0
Opens: 539845 Closes: 539844 Deletes: 156848
Posix Opens: 0 Posix Mkdirs: 0
Mkdirs: 133 Rmdirs: 0
Renames: 0 T2 Renames 0
FindFirst: 21 FNext 28 FClose 0
2) \\10.1.2.3\Share
SMBs: 50466376 Oplocks breaks: 1082284
Reads: 39430299 Bytes: 2255596161939
Writes: 2602 Bytes: 42507782
Flushes: 0
Locks: 1082284 HardLinks: 0 Symlinks: 0
Opens: 2705841 Closes: 2705841 Deletes: 539832
Posix Opens: 0 Posix Mkdirs: 0
Mkdirs: 0 Rmdirs: 0
Renames: 0 T2 Renames 0
FindFirst: 227401 FNext 1422 FClose 0
One pattern I think I see is that the error is raised only if the file in question has been already processed (read and deleted) earlier by the PHP script. There are many files that have been correctly processed and then processed again later, but I have never seen that error for a file that is processed for the first time. The time between re-processing varies from 1 to about 20 days. For re-processing, the file is simply recreated under the same path on the Windows host with updated content.
What can be the problem? How can I investigate better? How can I determine if the problem lies on the PHP or OS side?
Update
I have moved the software that produces the files to a Ubuntu VM that mounts the same shares the same way. This component is coded in Java. I am not seeing any issues when reading/writing to the files.
Update - PHP details
The exact PHP code is:
$strFile = zipPath($intApplicationNumber);
clearstatcache();
if(!file_exists($strFile)){
return responseInternalError('ZIP file does not exist', $strFile);
}
The intApplicationNumber
is a request parameter (eg. 12345678
) which is simply transformed to a path by the zipPath()
function (eg. \Share\12\345\678.zip
- always a full path).
The script may be invoked concurrently with different application numbers, but will not be invoked concurrently with the same application number.
If the script fails (returns the 'ZIP file does not exist'
error), it will be called again a minute later. If that fails, it will be permanently marked as failed. Then, usually more than an hour later, I can call the script manually with the same invocation (GET request) that it's done on production and it works fine, the file is found and sent in the response:
public static function ResponseRaw($strFile){
ob_end_clean();
self::ReadFileChunked($strFile, false);
exit;
}
protected static function ReadFileChunked($strFile, $blnReturnBytes=true) {
$intChunkSize = 1048576; // 1M
$strBuffer = '';
$intCount = 0;
$fh = fopen($strFile, 'rb');
if($fh === false){
return false;
}
while(!feof($fh)){
$strBuffer = fread($fh, $intChunkSize);
echo $strBuffer;
if($blnReturnBytes){
$intCount += strlen($strBuffer);
}
}
$blnStatus = fclose($fh);
if($blnReturnBytes && $blnStatus){
return $intCount;
}
return $blnStatus;
}
After the client receives the file, he notifies the PHP server that the file can be moved to an archive location (by means of copy()
and unlink()
). That part works fine.
STRACE result
After several days of no errors, the error reappeared. I ran strace
and it reports
access("/Share/11/222/333.zip", F_OK) = -1 ENOENT (No such file or directory)
for some files that do exist when I run ls /Share/11/222/333.zip
from the command line. Therefore the problem is on the OS level, PHP is not to be blamed.
The errors started appearing when the load on the disk on the host increased (due to other processes), so @risyasin's suggestion below seems most likely - it's a matter of busy resources/timeouts.
I'll try @miguel-svq's advice of skipping the existence test and just going for fopen()
right away and handling the error then. I'll see if it changes anything.
Source: (StackOverflow)
I am having trouble trying to get theh permissions for some of my external drives set up.
I believe the probem is due to how I am dealing with spaces in the text such that the commands can be interpreted by the terminal.
I have found this, which seems to indicate that I need to configure my etc/fstab file to show the following:
# UNCONFIGURED FSTAB FOR BASE SYSTEM
/host/ubuntu/disks/swap.disk none swap sw 0 0
LABEL='Expansion Drive' /media/'Expansion Drive' ntfs-3g defaults,umask=0022,fmask=0133 0 0
LABEL='Expansion Drive_' /media/'Expansion Drive_' ntfs-3g defaults,umask=0022,fmask=0133 0 0
However, This is showing an error that the drive Drive_'
is not ready. I realize that this is due to using ""
s or ''
s, but I am not sure how else to do this properly. My 2 drives are called Expansion Drive
and Expansion Drive_
. Anyone know how to solve this problem?
EDIT: Here is what I can see in the media folder:
chasebrown@ubuntu:/media$ ls -al
total 32
drwxr-xr-x 6 root root 1024 Mar 9 16:32 .
drwxr-xr-x 24 root root 1024 Feb 23 23:14 ..
drwx------ 1 chasebrown chasebrown 4096 Mar 8 04:21 Expansion Drive
drwx------ 1 chasebrown chasebrown 4096 Mar 8 04:21 Expansion Drive_
dr-x------ 1 chasebrown chasebrown 2048 May 20 2009 GDRV-25922+VR2
drwx------ 1 chasebrown chasebrown 20480 Mar 8 04:21 WD EXTERNAL
Also sudo lsblk -f
:
chasebrown@ubuntu:/dev/disk/by-uuid$ sudo lsblk -f
[sudo] password for chasebrown:
NAME FSTYPE LABEL MOUNTPOINT
sda
├─sda1 ntfs System Reserved
└─sda2 ntfs
sdb
└─sdb1 ntfs /host
sdc
└─sdc1 ntfs Expansion Drive /media/Expansion Drive_
sdd
└─sdd1 ntfs Expansion Drive /media/Expansion Drive
sde
└─sde1 ntfs WD EXTERNAL /media/WD EXTERNAL
sr0 iso9660 GDRV-25922+VR2 /media/GDRV-25922+VR2
loop0 ext3 /
And sudo blkid
:
chasebrown@ubuntu:/dev/disk/by-uuid$ sudo blkid
/dev/loop0: UUID="87a15942-982f-4edd-bf44-439dc286fd7c" SEC_TYPE="ext2" TYPE="ext3"
/dev/sr0: LABEL="GDRV-25922+VR2" TYPE="iso9660"
/dev/sda1: LABEL="System Reserved" UUID="64CEEA61CEEA2B4E" TYPE="ntfs"
/dev/sda2: UUID="4CA4EBC0A4EBAAA2" TYPE="ntfs"
/dev/sdb1: UUID="00064EEE064EE46E" TYPE="ntfs"
/dev/sdc1: LABEL="Expansion Drive" UUID="C682A8EE82A8E3E1" TYPE="ntfs"
/dev/sdd1: LABEL="Expansion Drive" UUID="D006D78406D769CC" TYPE="ntfs"
/dev/sde1: LABEL="WD EXTERNAL" UUID="D65AFC375AFC15C9" TYPE="ntfs"
Therefore my new fstab file is:
# UNCONFIGURED FSTAB FOR BASE SYSTEM
/host/ubuntu/disks/swap.disk none swap sw 0 0
LABEL=Expansion\040Drive /media/Expansion\040Drive ntfs-3g defaults,umask=0022,fmask=0133 0 0
LABEL=Expansion\040Drive_ /media/Expansion\040Drive_ ntfs-3g defaults,umask=0022,fmask=0133 0 0
SOLUTION:
I ended up changing the LABEL
to UUID
and it worked for some reason.
Here is the resulting /etc/fstab file was :
# UNCONFIGURED FSTAB FOR BASE SYSTEM
/host/ubuntu/disks/swap.disk none swap sw 0 0
UUID=C682A8EE82A8E3E1 /media/Expansion\040Drive ntfs-3g defaults,umask=0022,fmask=0133 0 0
UUID=D006D78406D769CC /media/Expansion\040Drive_ ntfs-3g defaults,umask=0022,fmask=0133 0 0
Source: (StackOverflow)
I'm making a small rails engine which I mount like this:
mount BasicApp::Engine => "/app"
Using this answer I have verified that all the routes in the engine are as the should be:
However - when I (inside the engine) link to a named route (defined inside the engine) I get this error
undefined local variable or method `new_post_path' for #<#<Class:0x000000065e0c08>:0x000000065d71d0>
Running "rake route" clearly verifies that "new_post" should be a named path, so I have no idea why Rails (3.1.0) can't figure it out. Any help is welcome
my config/route.rb (for the engine) look like this
BasicApp::Engine.routes.draw do
resources :posts, :path => '' do
resources :post_comments
resources :post_images
end
end
I should add that it is and isolated engine. However paths like main_app.root_path works fine - while root_path does not
Source: (StackOverflow)
Given a path to a file or directory, how can I determine the mount point for that file? For example, if /tmp
is mounted as a tmpfs
filesystem then given the file name /tmp/foo/bar
I want to know that it's stored on a tmpfs
rooted at /tmp
.
This will be in C++ and I'd like to avoid invoking external commands via system()
. The code should be robust--not necessarily against deliberate tampering but definitely in the face of nested mountpoints, symlinks, etc.
I haven't been able to find a simple system call to do this. It looks like I'll have to write the check myself. Here's a rough outline of what I'm planning.
- Canonicalize the file name a la the
readlink
shell command. How?
- Read
/etc/mtab
with getmntent()
& co.
- Determine the corresponding mount entry for the file. How?
For #1 is there a simple system call or do I need to read each directory component of the path and resolve them with readlink(2)
if they are symlinks? And handle .
and ..
myself? Seems like a pain.
For #3 I've got various ideas on how to do this. Not sure which is best.
open()
the file, its parent, its parent's parent, etc. using openat(fd, "..")
until I reach one of the /etc/mtab
entries. (How do I know when I do? fstat()
them and compare the inode numbers?)
- Find the longest directory name in the mount table which is a substring of my file name.
I'm leaning towards the first option but before I code it all up I want to make sure I'm not overlooking anything--ideally a built-in function that does this already!
Source: (StackOverflow)
In my day-to-day work (I'm using MS Windows), I keep my git bash (actually using console2 for this) open for the whole day. It is also very frequent that I mount new drives that I would like to work with git.
However I noticed that I need to exit the bash and open it again in order to make it recognize new drive letter.
Is there any command that 'registers' already mounted drive in git bash ?
thanks
edit2:
I do not have any option to left a comment under my own question (weird ..?), so I post it here:
$ mount -a
sh.exe": mount: command not found
Source: (StackOverflow)
I've written a small FUSE-based filesystem and now the only part's missing is that I want to register it with fstab(5) to auto-mount it on system startup and/or manually mount it with just mount /srv/virtual-db
. How can I achieve this?
I know, I can just run /usr/bin/vdbfs.py /srv/virtual-db
from some init script, but that's not exactly pretty.
I'm sorry because this may be not exactly a programming question, but it's highly related, as the packaging and deployment is still the programmer's job.
Source: (StackOverflow)
I'm trying to implement the FUSE filesystem. I am receiving this error:
cannot access MountDir: Transport endpoint is not connected
This the relevant parts of the program. There are two directories, MirrorDir
and MountDir
, that exist withing the same directory as all of the code. I am calling the program like this:
./myFS -o nonempty -o allow_other MirrorDir MountDir
Can anyone see what I am doing wrong?
static struct fuse_operations xmp_oper = {
.getattr = xmp_getattr,
.readdir = xmp_readdir,
.open = xmp_open,
.read = xmp_read,
};
int main(int argc, char *argv[]) {
int fuse_stat;
char* mirrorDir;
mirrorDir = malloc(sizeof(strlen(argv[argc-2]+1)));
if (mirrorDir == NULL) {
perror("main calloc");
abort();
}
// Pull the rootdir out of the argument list and save it in my internal data
mirrorDir = realpath(argv[argc-2], NULL);
argv[argc-2] = argv[argc-1];
argv[argc-1] = NULL;
argc--;
// turn over control to fuse
fprintf(stderr, "about to call fuse_main\n");
fuse_stat = fuse_main(argc, argv, &xmp_oper, mirrorDir);
fprintf(stderr, "fuse_main returned %d\n", fuse_stat);
return fuse_stat;
}
Source: (StackOverflow)