Sunday, August 30, 2015

Arch Linux Brightness Button Problem in Kernel 4.X

Ever since I updated my Arch Linux installation to version using kernel 4.X series, the brightness button in my Lenovo laptop (Ideapad Flex 14) is not working properly anymore. At first, I thought it's merely a configuration problem, but it turns out there's more to it than that. Let's break it down..
  • First and foremost, the laptop uses Nvidia Optimus configuration, i.e. Intel integrated graphics + NVidia discrete GPU. However, this doesn't preclude the (ACPI) brightness buttons from working just fine under Linux kernel 3.X. 
  • Upon boot, only intel_backlight is loaded. In kernel 3.X both intel_backlight and acpi_backlight "modules" are loaded. However, after trying this workaround, it's still not working as expected. Note: I used this to modify the kernel boot parameter. 
  • The symptoms of the brightness button malfunction as follows: The button is not exactly not working, it's merely the response time for a button press to be registered in the kernel takes a few seconds. As for the brightness-level setting in /sys/class/backlight/intel_backlight is just fine. 
This bug is not entirely a bad thing, but it's irritating. For the time being, I stay away from using bleeding-edge Arch Linux with kernel 4.X and uses LTS kernel instead (https://www.archlinux.org/packages/core/x86_64/linux-lts/). However, Greg KH mentioned that the LTS kernel will ceases support next year. We'll see what option I have by then. Maybe, I'll just remap other Laptop keys or find some other work around.

------UPDATE-----

Arch Linux LTS Kernel has moved to kernel 4.1.X over the weekend. I tried to use this recommended kernel version. But it turns out the ACPI-related problem I mentioned above also exists in this kernel version. I've been thinking to use one of the kernels from from AUR, but then ultimately decided to just downgrade the kernel. It turns out that it's much easier than what I thought before. This is what I did (in chronological order):
  1. I have upgraded my Arch Linux to kernel 4.1.X LTS. Therefore, I boot into this LTS kernel version. 
  2. Log in as root and then carry-out the downgrade procedure as explained at https://wiki.archlinux.org/index.php/Downgrading_packages#Downgrading_the_kernel. There are only two packages that I need to downgrade, i.e. the Linux kernel and the Linux kernel headers. Therefore, I use this command:
    pacman -U linux-lts-3.14.52-1-x86_64.pkg.tar.xz linux-lts-headers-3.14.52-1-x86_64.pkg.tar.xz
    
    and everything went without a hitch. The machine works just like before the upgrade. The ACPI hot-keys which were not functioning properly in kernel 4.X are now working like it used to be. I'm a bit worried about systemd compatibility at this point but it seems that everything works as they should.
------UPDATE 2-----
I finally decided to use one of the custom kernel from AUR because it's a stable release that will go through maintenance period at least up-to 2017. See: Compiling and Using Custom Arch Linux Kernel

Friday, August 14, 2015

Very Simple Libmemcached Sample Code

Libmemcached documentation can be a bit overwhelming for those new to memcached client library. The sample code below shows a very simple libmemcached usage sample. It assumes that you have libmemcached >= v1.0 in your machine installed. The code comes with no warranty whatsoever, use it a your own risk. Here comes the code:
#include < stdio.h >
#include < stdint.h >
#include <libmemcached-1.0/memcached.h >
#include < stdlib.h >

#define DEFAULT_PORT 7500

int main (int argc, char *argv[])
{
  memcached_return_t rc;
  char * value; 
  char buffer[1024];
  int length= snprintf(buffer, sizeof(buffer), "--server=localhost:%d", DEFAULT_PORT);
  char key[] = "my_key";
  char obj_value[] = "my value";
  size_t obj_val_len;

  memcached_st *memc= memcached(buffer, length);
  if (memc == NULL) {
     printf("Error: Failed to allocate memcached_st object\n");
  }

  rc = memcached_set(memc, key, strlen(key), obj_value, strlen(obj_value) + 1, 0, 0);
  if (rc != MEMCACHED_SUCCESS) {
     printf("Error: Failed to set memcached object value\n");
  }

  value = memcached_get(memc, key, strlen(key), &obj_val_len, 0, &rc);
  if (value == NULL) {
     printf("Error: Failed to read object value\n");
  }
  
  if (MEMCACHED_SUCCESS == rc) {
     printf("Object contents = %s\n", value);
  } else {
     printf("Error: Failed to read object value correctly\n");
  } 

  if (value != NULL) {
     free(value);
  }

  memcached_free(memc);

  return 0;
}
The sample codes simply stores a value ("my value" string) into memcached server running in localhost at port 7500 and read it back to make sure the value stored correctly. This sample code assumes you're running memcached server in your local machine and make it listen at port 7500. This is how I do that:
me@darkstar $ ./memcached -l 127.0.0.1 -p 7500
If you want to change the port, simply change the DEFAULT_PORT definition.

Anyway, the purpose of this post is as a very gentle introduction to libmemcahed. Head over to http://docs.libmemcached.org/index.html for more details.