Showing posts with label linux. Show all posts
Showing posts with label linux. Show all posts

Monday, 17 June 2013

Chrome issue - XMLHttpRequest cannot load file: Cross origin requests are only supported for HTTP

Lately I have been developing a very silly webpage with bare HTML and Javascript. I'm not very familiar with websites and web in general, so I just write some code and try it out through a browser, with no HTTP server running.
Everything was working just fine until I decided to use external XML files to get input from; this is the code snippet I used to get XML input (thanks W3schools.com):
...
if (window.XMLHttpRequest) {
   xhttp = new XMLHttpRequest(); // for IE7+, Firefox, Chrome, Opera, Safari
} else {
   xhttp = new ActiveXObject("Microsoft.XMLHTTP"); // for IE6, IE5
}
xhttp.open("GET", "samplexml/externalfile.xml", false);
xhttp.send();
xmlDoc = xhttp.responseXML;
xmlChildren = xmlTree.documentElement.childNodes;
xmlChildren[0].nodeName; // prints the tag of the first node
...
where samplexml/externalfile.xml is the relative path to the XML file.
If you test this code (again, without any HTTP server!) on a browser like Firefox there won't be any problem: the XML file gets loaded as a charm. The problem is when you try to make it work with Chrome. The console will display a message like the following:
XMLHttpRequest cannot load file:///path/to/project/folder/samplexml/externalfile.xml. Cross origin requests are only supported for HTTP.
Basically the problem is that Chrome has strict permissions for reading files out of the local file system. The best thing to do is to use a simple HTTP server, as suggested here.
This could sound like a lot of stuff and a lot of steps to so, as well as a lot of bad words to shout throughout several days trying to make things work properly. Actually this is not the case: Python comes in handy with its SimpleHTTPServer class, a simple HTTP server which provides standard GET and HEAD request handlers; the cool thing is that it's actually super easy to set up a HTTP server with this class.
[lillo@pc-lillo ~]$ cd /path/to/project/folder
[lillo@pc-lillo project]$ python -m SimpleHTTPServer 8888
Serving HTTP on 0.0.0.0 port 8888 ...
where project is your project folder. Now just open the application from Chrome (localhost):
http://localhost:8888
That's it; now Chrome will not complain anymore, and you're free to read as many XML files as you wish. When you're done just Ctrl-C to exit Python.
Sweet.

Friday, 10 May 2013

High CPU usage due to kworker

I recently solved a problem with a kworker process taking up more than 60% of one of my eight CPUs. What is kworker? Here is a simple yet good explanation. I forgot to take snapshots, but the scenario was more or less as shown in figure (source).
Before starting, please note that this is not a OS-specific issue. Read this stuff again if you're not fully convinced about it; the above links could suggest this is only a Ubuntu issue, but it's not (I'm using Fedora for example).
 $ uname -a  
 Linux pc-lillo 3.8.11-100.fc17.x86_64 #1 SMP Wed May 1 19:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux  
I don't really like to say I "solved" the problem as I see the following as a workaround, but it actually works good. I just followed what I could find here and here. So, here is what you should do if you see that something is taking up too much CPU.
Make sure the offender is indeed a kworker process. Use top, or ps aux | grep kworker if you prefer.
Find out the gpe (general purpose event) that is causing all of this:
 $ grep . -r /sys/firmware/acpi/interrupts  
Normally you should get a list of this kind:
 /sys/firmware/acpi/interrupts/sci:   162  
 /sys/firmware/acpi/interrupts/error:    0  
 /sys/firmware/acpi/interrupts/gpe00:    0  invalid  
 /sys/firmware/acpi/interrupts/gpe01:    0  invalid  
 /sys/firmware/acpi/interrupts/gpe02:    0  disabled  
 /sys/firmware/acpi/interrupts/gpe03:    0  enabled  
 /sys/firmware/acpi/interrupts/gpe04:    0  disabled  
 ........  
 /sys/firmware/acpi/interrupts/gpe_all:   162  
 /sys/firmware/acpi/interrupts/ff_gbl_lock:    0  enabled  
 /sys/firmware/acpi/interrupts/ff_pwr_btn:    0  enabled  
 /sys/firmware/acpi/interrupts/ff_slp_btn:    0  invalid  
You should see a gpe with a very high value. In my case the value of gpe1B was 162, which is ok; gpe06 had instead a value of (approximately) 170.000. This is definitely NOT ok: that's the proof the problem is with ACPI interrupts.
Let's say the offender gpe is called gpe[XX] (replace the "[XX]" accordingly). Now:
 $ su  
 Password:  
 # cp /sys/firmware/acpi/interrupts/gpe[XX] /pathtobackup  
Note that some commands will be executed even without administrator rights, but the trick will not work (or at least not completely). So it's good to keep the admin rights until the end.
Now we should schedule a task through crontab. Such task should disable the offender gpe, and it must be performed every startup or reboot. To open crontab with vi:
 # crontab -e  
If you want to use another editor (e.g., gedit), just specify it:
 # env EDITOR=gedit crontab -e  
Add the following line to the crontab file:
 @reboot echo "disable" > /sys/firmware/acpi/interrupts/gpe[XX]  
Save, close.
To make it work even after suspend (optional):
 # touch /etc/pm/sleep.d/30_disable_gpe[XX]  
 # chmod +x /etc/pm/sleep.d/30_disable_gpe[XX]  
 # gedit /etc/pm/sleep.d/30_disable_gpe[XX]  
Copy this script in 30_disable_gpe[XX]:
 #!/bin/bash  
 case "$1" in  
   thaw|resume)  
     echo disable > /sys/firmware/acpi/interrupts/gpe[XX] 2>/dev/null  
     ;;  
   *)  
     ;;  
 esac  
 exit $?  
Save, close, and we're done. Sweet.

Note: no luck with the cron job? Have a look at Myk's comments below...