pucek has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks. I developped a simple script in Perl that let's me verify if USB key is mounted or not and eventually unmount it.

I am not sure if problem is related to programming or configuration...

Basic issue is: When I execute those scripts in terminal using `Perl` it works perfectly fine, althou when I do it in the browser using `mod_perl` it shows some pretty odd behaviour.

Sources

panelmin.pl

This program simply outputs a message that indicates if the system device `/dev/sda1` is mounted in the system.

#!/usr/bin/perl use strict; use warnings; print "Content-type:text/html\n\n"; print "<html><head><title>USB test</title>"; print "</head><body>"; my $mounted = `df -h | grep /dev/sda1`; if ($mounted eq '') { print '<h1>USB device not connected</h1>'; print $mounted; } else { print '<h1>Device is connected</h1>'; } print '</body></html>';

umount.pl

This program umounts the `/dev/sda1` device from the system.

#!/usr/bin/perl print "Content-type:text/html\n\n"; print "<html><head><title>Umount</title></head><body>"; system("sudo", "umount", "/dev/sda1"); print "</body></html>";

Test scenario

1. Manually mounting the device `/dev/sda1`, (it is declared in `fstab`):

$ mount -a

Making sure the device is mounted in the system:

$ mount /dev/sda1 on /mnt/usbstick type vfat (rw,relatime,uid=1000,gid=100 +0,fmask=0137,dmask=0027,codepage=437,iocharset=ascii,shortname=mixed, +utf8,errors=remount-ro)

2. Executing `panelmin.pl` in the web browser (I will use curl for the purpose of clean output):

$ curl http://localhost/cgi-bin/admin/Q/panel/panelmin.pl <html><head><title>USB test</title></head><body><h1>Device is conn +ected</h1></body></html>

As we can see, the output is correct. It detected the through linux command `df -h` that the device `/dev/sda1` is mounted in the system.

2. Executing `umount.pl` in the web browser in order to umount the device:

$ curl http://localhost/cgi-bin/admin/Q/panel/umount.pl <html><head><title>Umount</title></head><body></body></html>

3. Verifying if the device is umounted using both `panelmin.pl` script in the web browser and linux command line.

$ curl http://localhost/cgi-bin/admin/Q/panel/panelmin.pl <html><head><title>USB test</title></head><body><h1>USB device not + connected</h1></body></html>

Seems to be correct, but let's verify it manually with `df -h` command:

$ df -h | grep /dev/sda1 /dev/sda1 15G 366M 15G 3% /mnt/usbstick

As we can see the device is still mounted in the system.

4. Let's retry the whole process but this time instead of executing scripts in the browser we will launch them manually with `Perl` in the terminal. First lets umount the device. This will also show that the user is in sudoers and script can umount it.

$ sudo umount /dev/sda1 $ df -h | grep /dev/sda1

Let's repeat the process.

$ mount -a (as superuser) $ df -h | grep /dev/sda1 /dev/sda1 15G 366M 15G 3% /mnt/usbstick

And finally the test:

$ perl panelmin.pl Content-type:text/html <html><head><title>USB test</title></head><body><h1>Device is conn +ected</h1></body>
$ perl umount.pl Content-type:text/html <html><head><title>Umount</title></head><body></body></html>
$ perl panelmin.pl Content-type:text/html <html><head><title>USB test</title></head><body><h1>USB device not + connected</h1></body></html>
$ df -h | grep /dev/sda1
Now `df -h | grep /dev/sda1` returned empty string, it has proven that `umount.pl` managed to umount the device from the system, but only if executed in the shell with `Perl`.

Attempts to solve the issue

Interpretation

The fact it works with `Perl` and not with `mod_perl` is not that surprising, what I find the most strange is with `mod_perl` the script `panelmin.pl` seems to works fine with it's `system()` launch and suddenly after executing `umount.pl` it does not work correctly anymore. For now I am out of ideas, I find this behaviour odd and I count on you guys. I hope someone knows what should I do. Thanks.

Replies are listed 'Best First'.
Re: mod_perl odd behaviour with system() or exec() call or backticks
by perlfan (Parson) on Jul 10, 2014 at 11:22 UTC
    mod_perl is "persistent" meaning processes hang around for a while, and unless properly managed variables are not going to be reassigned like you think they are; it's not unlike a "stale cache" problem.

    I believe that what you are seeing is due to this persistence, so you need a handler that will recompile the script each time a requests is handled by Apache. This PerlResponseHandler is ModPerl::PerlRun.

    See Re: mod-perl configuration under Apache2.

    Last note, mod_perl is really nice once you understand that it a way to hook deeply into Apache's requesting life cycle to facilitate an application, but it'd be easier for you to port it to a pure CGI environment that doesn't try to be smart with persistence. CGI is much more akin to running it at the command line - just be careful of %ENV not being what you expect it to be.

      Thank you for your feedback. Unfortunately my virtual host was already using ModPerl::PerlRun as PerlResponseHandler.
        Is traditional CGI an option? It's been mentioned that in this situation it is your best bet since you're literally running the script once per request. The only difference is going to be that you will have to ensure that your shebang and environmentals are as expected, namely @INC and %ENV.
Re: mod_perl odd behaviour with system() or exec() call or backticks
by Anonymous Monk on Jul 10, 2014 at 09:25 UTC

    For now I am out of ideas,

    The list of things to check is: perms/user, paths/shebang, %ENV, chroot, firewall, AppArmor/SELinux

    There, now you have more ideas :)

      Thank you for quick response. I already verified permissions, paths and shebang are correct too. Concerning environmental variables, should I look for something particular? I don't know how to verify AppArmor/SELinux, I never changed anything concerning that. Could firewall influence execution of a command by the script? I thougth it could block the script itself, but not a particular operation in that script.
Re: mod_perl odd behaviour with system() or exec() call or backticks
by Anonymous Monk on Jul 10, 2014 at 11:36 UTC
    In this case, "pure dumb CGI" is exactly what you need ... get rid of mod_perl altogether and simply run the damm thing each time.
      Thanks. I think I managed to config simple dumb CGI and mod_perl both on my virtual host (but on seperate locations). Unfortunately, it doesn't seem to do the job. It still won't umount the device. Maybe I configured it wrong? Should I post my virtual host configuration? Or maybe it wasn't that the issue?