Archive for the 'Programming' Category

Munin, mysql and semaphore: how to deal with the “identifier removed” error

The following depicts how I “solved” a problem I recently had regarding munin, its mysql plugins and the shared memory cache library used by the plugins (written in perl and using IPC::ShareLite).

First off, let’s begin with a description of the problem. I posted the following on serverfault.com in hope I’d get help from someone more experienced than I am.

I’ve recently setup a munin-node on a CentOS server. All was working fine until I tried to add the apache plugin (which works fine).

For some odd reason, the mysql plugins for munin that used to work ceased to work… I’m now getting a weird error whenever I’m running the plugin with munin-run. For instance

munin-run mysql_files_tables

returns me

[shell]
IPC::ShareLite store() error: Identifier removed at /usr/lib/perl5/vendor_perl/5.8.8/Cache/SharedMemoryBackend.pm line 156
[/shell]

but sometimes it will also return

[shell]
table_open_cache.value 64
Open_files.value 58
Open_tables.value 64
Opened_tables.value 19341
[/shell]

but after a while it will revert to the previous error.

I do not have any knowledge about the IPC or the ShareLite library so I don’t really know were to start looking. Since it is a module related to shared memory, I tried tracking down shared memory segments with ipcs without much success.

I haven’t yet rebooted the machine as it is used for many projects (I’d obviously like to be able to diagnose the problem without requiring a restart if it was possible).

Has anyone faced this problem? (a quick search on google didn’t present any relevant help)

Thanks for the help!

Obviously, one can see quickly that this is a quite specific question that not many may have actually encountered. Thus, I didn’t expect to receive much help out of it (and I didn’t).

I had left this issue on the side for a couple of days hoping to come back to it at some point. Munin and the mysql plugins were installed on two servers and it was working fine on both of them (and a third one as master node). After a minor change, one of two client nodes stopped working correctly while the other was still fine. After a couple of days though the second server also decided to exhibit a similar issue…

Tonight I remembered about strace, which is pretty awesome in circumstances like this one. I went ahead and launched strace munin-run mysql_files_tables which outputted a lot of stuff and then stopped at the following point:

[shell]

ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff13da8e30) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(4, 0, SEEK_CUR) = 0
read(4, "# Carp::Heavy uses some variable"…, 4096) = 4096
brk(0x163e7000) = 0x163e7000
read(4, "\n redo if $Internal{$caller};"…, 4096) = 1737
read(4, "", 4096) = 0
close(4) = 0
write(2, "IPC::ShareLite store() error: Id"…, 123IPC::ShareLite store() error: Identifier removed at /usr/lib/perl5/vendor_perl/5.8.8/Cache/SharedMemoryBackend.pm line 156
) = 123
semop(14581770, 0x2ab08bb67cf0, 3
[/shell]

and when it is actually fixed, the application would end instead (outputting a bunch of stuff such as the following)

[shell]

stat("/usr/lib64/perl5/auto/Storable/_freeze.al", {st_mode=S_IFREG|0644, st_size=706, …}) = 0
stat("/usr/lib64/perl5/auto/Storable/_freeze.al", {st_mode=S_IFREG|0644, st_size=706, …}) = 0
open("/usr/lib64/perl5/auto/Storable/_freeze.al", O_RDONLY) = 4
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffe7223570) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(4, 0, SEEK_CUR) = 0
read(4, "# NOTE: Derived from ../../lib/S"…, 4096) = 706
read(4, "", 4096) = 0
close(4) = 0
semop(917514, {{1, 0, 0}, {2, 0, 0}, {2, 1, SEM_UNDO}}, 3) = 0
semop(917514, {{2, -1, SEM_UNDO|IPC_NOWAIT}}, 1) = 0
semop(917514, {{1, 0, 0}, {2, 0, 0}, {2, 1, SEM_UNDO}}, 3) = 0
shmdt(0x7fc30021f000) = 0
semop(917514, {{2, -1, SEM_UNDO|IPC_NOWAIT}}, 1) = 0

[/shell]

How to “fix” the problem

What you can see in the first output above is pretty interesting. The semop call gives you the semid the process is trying to obtain (the semaphore used to synchronize different processes using the same shared memory). The signature of the semop function is as follow:

[c]
int semop(int semid, struct sembuf *sops, unsigned nsops);
[/c]

where
semid: semaphore id
sops: pointer to a sembuf struct
[c]
struct sembuf {
u_short sem_num; /* semaphore # */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
[/c]
nsops: the length of sops

Upon first inspection, you can see that the sembuf in the first case seems to be invalid if you compare it with the working version where it is actually resolved (strace displays something such as
{{2, -1, SEM_UNDO|IPC_NOWAIT}} instead of 0x2ab08bb67cf0. But that is not helping me much.

With that semid you can do two things: first, you can check if it is still alive by calling ipcs, second, you can remove it with ipcrm -s semid.

In my case the “fix” itself was to remove the semaphore that the plugin wasn’t able to obtain (the reason of this still elude me though). After the removal of the semaphore, it is possible again to run munin correctly and the identifier removed error is gone.

I will have to do more research as to how/why this issue occurs as I’ve seen it happen only on CentOS machines so far (the master server is a Debian machine).

Accepting self-signed (or unknown) certificates with TortoiseGit

For some odd reason it seems that the system designed into TortoiseGit doesn’t allow the user to interact with git when it requires user interaction. For instance, accepting self-signed certificated is not possible, which gives you the known Issue 318.

As of TortoiseGit 1.8.5.0, it is still not possible to accept certificates through the GUI. But it is possible to get your git repository to work with TortoiseGit (and work with the required certificate).

You will need to have msysgit installed and available in your PATH for the following to work.

The first step is to run some git command, for instance git clone https://myserver.com/depot via a command line so that git may auto-accept (or ask you to accept) the certificate. This step is crucial to get the certificate details saved onto your machine.

What you will want to do next is go to C:\Program Files (x86)\Git\.subversion and copy everything into %USERPROFILE%\.subversion. Basically, this should copy the certicates that were accepted by msysgit so they can be used by TortoiseGit.

Another, and possibly better solution, is to create a symbolic link so that those 2 folders are in fact a single one. For instance, you could do something such as

[shell]
move %USERPROFILE%\.subversion %USERPROFILE%\.subversion_backup
mklink /D %USERPROFILE%\.subversion "C:\Program Files (x86)\Git\.subversion"
[/shell]

which will make %USERPROFILE%\.subversion point to your C:\Program Files (x86)\Git\.subversion folder. This has the benefit that any future certificate will work both for msysgit and TortoiseGit.

Thanks to Mexx’ C# Corner for pointing out the solution.

PHPUnit – No coverage report

I was trying to get PHPUnit to give me some coverage report for a project I had not worked on for a long time. I had received a github pull request from someone and I wanted to see what the coverage was on the project to see if the submitter had done a good job of covering his code, but I couldn’t get PHPUnit to generate a report that contained any data. All I would get was a couple of empty directory folders pages, which was useless.

I had code coverage work on another project in the same environment I was in, so I was pretty sure that my problem had to do either with how I had setup PHPUnit for that particular project, or that something else was interfering with the report generation.

I tried a couple of things, starting by calling phpunit from the command line using different arguments:

  • –coverage-html report test\symbol_test.php
    • Would generate some report with data in it, good!
  • -c test\phpunit.xml (logging set in phpunit.xml)
    • Would generate an empty report, not good…
  • –coverage-html report -c test\phpunit.xml
    • Would generate an empty report, not good…

So at that point I saw that it was working correctly and that something was definitely wrong with my phpunit.xml configuration file. I went back to the phpunit.de manual, specifically on the configuration page, and tried to figure out my problem.

For code coverage to be included in your report, you have to add a filter, be it a blacklist or a whitelist, but you have to have a filter.

So I quickly added a filter such as

[xml]
<filter>
<whitelist>
<directory>../</directory>
</whitelist>
</filter>
[/xml]

which would whitelist everything that is in the project (my project root is one level above test). Ran phpunit in the test folder and I finally got a report with data!

PHPUnit – PHP Fatal error: require_once(): Failed opening required ‘PHPUnit/Util/Filter.php’

A friend of mine was trying to install PHPUnit on his mac (OS X Lion), but unfortunately, he got stuck during the process.

At some point, he was faced with this error being displayed. We both looked at the problem and first made sure that said file existed. It was the case, weird…

A bit of googling will reveal that this is frequently fixed by appending the path to the pear folder to your php include_path (defined in your php.ini). But in his case, that was already done and it still wasn’t working.

Next up was to check permissions problem. Not having read permissions on the file would of been an easy one to fix, but again, this was not the cause of the problem.

At this point you might be asking yourself, how come the file exists, you have permission to read it, but yet, you can’t…

Well, the actual problem was that his OS was set up such that the maxfiles was set to 256 and PHPUnit had already reached that amount of open files.

To check if you have the same problem, try running phpunit using sudo dtruss -f -t open phpunit (Linux users will want to use strace -e open phpunit). In your output, you should see the files being opened. At some point, you’ll find Err#24, which indicates “To many file descriptors opened”. If you have this problem, then the following should help you fix it.

The solution to this problem is quite easy. What you’ll want to do is increase the maximum number of descriptors that can be used by a process. You can do it temporarily with ulimit -S -n 1024 (to use 1024 instead of 256). Another way is to edit it and keep those settings (until you change them again) is to use launchctl limit maxfiles 1024 unlimited.

PHPUnit not outputting coverage-html

I’ve been using PHPUnit recently to test a Kohana application I’m developing as my last semester project for my bachelor’s degree.

At some point during the development, code coverage generation decided to stop working on my desktop (my remote CI still had no problem).

I started diagnosing the problem, being on Windows, I thought it could be due to the “poor job” I had done on installing php, pear and phpunit. I didn’t want to go through the trouble or reinstalling everything though and just did the minimum: uninstall and reinstall phpunit. No success at that point.

I decided to go back a week or two in my SVN revisions, have it generate code coverage and get to the point were code coverage generation would fail. Took around 2 SVN “update to” to get to that point. After that, I tried updating the tests, but the new tests were using new features. So I updated the code first, then started updating the test files one by one. After a couple of files, I hit an interesting message:

ErrorException [ 1 ]: Allowed memory size of 134217728 bytes exhausted (tried to allocate 543278 bytes) ~ C:\php\pear\Text\Template.php [ 134 ]

I never had that message show up before, which is kind of strange. I would have expected PHP to tell me that same message everytime it tried to generate the documentation but couldn’t…

So, quick fix was for me to edit my php.ini so that the memory_limit = 256M instead of 128M.

Categories