Monday, October 18, 2010

Classes inside interface

Normally, you can’t put any code inside an interface, but a nested class can be part of an interface. Any class you put inside an interface is automatically public and static. Since the class is static, it doesn’t violate the rules for interfaces—the nested class is only placed inside the namespace of the interface. You can even implement the surrounding interface in the inner class.

TestBed: Use nested class to hold test code


public class TestBed {
public void f() {
System.out.println("f()");
}
public static class Tester {
public static void main(String[] args) {
TestBed t = new TestBed();
t.f();
}
}
}

Nested classes

If you don’t need a connection between the inner-class object and the outerclass object, then you can make the inner class static. This is commonly called a nested class. To understand the meaning of static when applied to inner classes, you must remember that the object of an ordinary inner class implicitly keeps a reference to the object of the enclosing class that created it. This is not true, however, when you say an inner class is static. A nested class means:
1. You don’t need an outer-class object in order to create an object of a nested class.
2. You can’t access a non-static outer-class object from an object of a nested class.
Nested classes are different from ordinary inner classes in another way, as well. Fields and methods in ordinary inner classes can only be at the outer level of a class, so ordinary inner classes cannot have static data, static fields, or nested classes.

Anonymous inner class

If you’re defining an anonymous inner class and want to use an object that’s defined outside the anonymous inner class, the compiler requires that the argument reference be final.
Anonymous inner classes are somewhat limited compared to regular inheritance, because they can either extend a class or implement an interface, but not both. And if you do implement an interface, you can only implement one.

Thursday, October 14, 2010

Inner vs Nested class

It’s not possible to create an object of the inner class unless you already have an object of the outer class. This is because the object of the inner class is quietly connected to the object of the outer class that it was made from. However, if you make a nested class (a static inner class), then it doesn’t need a reference to the outer-class object.

The link to outer class

When you create an inner class, an object of that inner class has a link to the enclosing object that made it, and so it can access the members of that enclosing object—without any special qualifications. In addition, inner classes have access rights to all the elements in the enclosing class.

Wednesday, October 13, 2010

Asterisk 1.6 change canreinvite to directmedia in sip.conf

Asterisk sip.conf, peer definition: canreinvite option


This peer option in sip.conf is used to tell the Asterisk server to not issue a reinvite to the client unless really necessary. This is used to interoperate with some (buggy) hardware that crashes if we reinvite, such as the common Cisco ATA 186.

When SIP initiates the call, the INVITE message contains the information on where to send the media streams. Asterisk uses itself as the end-points of media streams when setting up the call. Once the call has been accepted, Asterisk sends another (re)INVITE message to the clients with the information necessary to have the two clients send the media streams directly to each other.

  • If one of the clients is configured with canreinvite=NO, Asterisk will not issue a re-invite at all.
  • If the clients use different codecs, Asterisk will not issue a re-invite.
  • If the Dial() command contains ''t'', ''T", "h", "H", "w", "W" or "L" (with multiple arguments) Asterisk will not issue a re-invite.

'canreinvite=no' stops the sending of the (re)INVITEs once the call is established. From messages in the archives and the Asterisk handbook one finds out that the Cisco ATA-186 does not handle the (re)INVITE well. This is necessary if the client and the Asterisk server is on opposite sides of a NAT gateway or firewall.

  • canreinvite = yes "allow RTP media direct"
  • canreinvite = no "deny re-invites"
  • canreinvite = nonat "allow reinvite when local, deny reinvite when NAT"
  • canreinvite = update "use UPDATE instead of INVITE"
  • canreinvite = update,nonat "use UPDATE when local, deny when NAT"

Note: In spite of its name 'canreinvite' being set to 'no' does *NOT* disable all reINVITE operations. It *only* controls Asterisk generating reINVITEs for the specific purpose of setting up a direct media path. If a reINVITE is needed to switch a media stream to inactive (when placed on hold) or to T.38, it will still be done, regardless of this setting!

Migration from Asterisk 1.2 to 1.4: The "canreinvite" option has changed. canreinvite=yes used to disable re-invites if you had NAT=yes. In 1.4, you need to set canreinvite=nonat to disable re-invites when NAT=yes. This is propably what you want. The settings are now: "yes", "no", "nonat", "update". Please consult sip.conf.sample for detailed information.

Notes

  • reinvite=yes/no is plain wrong, even if you see it mentioned in example .conf files. The correct syntax is canreinvite=yes/no
  • Connecting media paths direct to an endpoint behind NAT won't be pretty. Especially if both devices are behind NAT. You might want to try using SER's nathelper in conjunction since nathelper.so can rewrite the SDP so that the private IP addresses are not included in the re-invite.
  • When dtmfmode=rfc2833, asterisk will send the RTP stream through asterisk. With dtmfmode=info canreinvite works properly.

A longer explanation

[Based on a posting to asterisk-users mailing list]

> I've set canreinvite=no on the channel to the SIP provider and it
> immediately worked. O.k., I'm happy about that but I want to
> *understand* what's going on here.
> .
> My setup is:
>
> Asterisk is connected on one side via eth1 to the "outside world" (IP
> adress 81.223.xxx.xxx) and on the other side via eth0 to the internal
> LAN (eth0 has IP 192.168.1.200, SNOM phone has 192.168.1.201, ...).

A good question, for which it's hard to give a short answer :-)

Firstly, you need to understand how SIP itself was designed to set up calls between handsets.

The SIP 'INVITE' message says "I want to set up a call". In the body of this message is a block of SDP (Session Description Protocol) which says "my audio endpoint is IP x.x.x.x port x, and I can use codecs A, B and C".

In the intended architecture of SIP, the INVITE is forwarded via a series of proxies until it reaches the requested destination. The remote end responds with a 200 saying "OK, my audio stream is on IP y.y.y.y port y, and I choose codec B", which is sent back to the first phone. At this point, the first phone starts sending RTP audio packets from x.x.x.x:x to y.y.y.y:y, and the second phone sends them from y.y.y.y:y to x.x.x.x:x. That is, the audio path is direct, whereas the SIP messages went via intervening proxies.

[This is horrendously over-simplified, but it's enough to make the point]

Now, the second thing to understand is that Asterisk is not a SIP proxy, and its default behaviour is to set up the two legs as two separate audio streams: phone X to Asterisk and Asterisk to phone Y. The way this works is:

  • Phone sends INVITE saying "I am on IP x.x.x.x:x, I can use codecs A,B,C"

  • Asterisk decides where the next leg is. If it is another SIP device, it sends a fresh SIP INVITE (with a different Call-Id) to the second phone saying "I am on IP z.z.z.z:z1, I can use codecs C and D" where z.z.z.z is Asterisk's own IP address and :z1 is a port it has chosen.

  • This arrives at the second phone, which says "OK, I am on IP y.y.y.y:y, I choose codec C", and sends it back to Asterisk

  • Asterisk is happy, so it completes the first leg by replying to the first phone "OK, I am on IP z.z.z.z:z2, I choose codec C"

So now the first phone is sending packets between x.x.x.x:x and z.z.z.z:z2, and the second phone is sending packets between y.y.y.y:y and z.z.z.z:z1

This means that Asterisk is in the media path - each RTP packet has to be received and resent, in both directions. On the minus side, this means more workload on the Asterisk server. On the plus side, being in the media stream means that Asterisk can perform a whole bunch of useful voice services - recording, conferencing, call parking, music on hold, even codec conversion (i.e. the stream from phone X to Asterisk can be using one codec, and phone Y to Asterisk a different one)

With me so far?

The third thing to realise is that Asterisk can optimise this out so that the media path is set up directly between the endpoints. This is what it means by "native bridging" - connecting two compatible endpoints directly together, instead of relaying the audio via Asterisk.

So, under the right conditions, the SIP message Asterisk sends to the second phone will contain the IP address of the first phone, and vice versa. This means it looks and smells almost like a SIP proxy.


Note: Asterisk is still really not a SIP proxy in this case. The two legs have different Call-Ids, and so are different SIP calls. However the SDP descriptors for the audio of the two calls point directly at each other.

This short-circuit way of setting up calls was introduced in 1.4; for earlier versions, I believe the call is set up initially as two legs, and then Asterisk reconnects the endpoints directly using a re-INVITE
--> try directrtpsetup=yes


What do I mean by "the right conditions"? Well I'm not sure what the complete set is, but one of those conditions is that both SIP channels must be marked "canreinvite=yes". If either has "canreinvite=no", then Asterisk falls back to the default behaviour of setting up two separate legs.

In your case, you need the default behaviour when calling the provider, because the SIP phone is on a private IP 192.168.1.201, whilst the provider is on a public IP P.P.P.P. If the SIP messages were to try to set up a direct media path between the two it wouldn't work [*]; in particular, there's no point the public SIP provider trying to send an RTP packet to 192.168.1.201, because it won't be able to route to it.

[*] To be fair, if you have a NAT firewall between your internal network and the Internet, then some packets will be able to go directly between your network and the outside world, with the firewall modifying the source IP address and/or port in the process. There are a whole bunch of nasty tricks which can be done, both on the phone and at the provider, which mean that if you are really lucky you can make VoIP work this way. However I recommend you avoid this. You are in the fortunate situation that your Asterisk box has a real public IP address, so make use of it.


The last thing, which took me a while to figure out, is why the option which means "I prefer to use a direct RTP media path" is called "canreinvite=yes".

Even if the normal audio path for a call can be set up with native bridging, Asterisk sometimes needs to be able to re-insert itself into the media path in the middle of a call - to provide services such as music on hold, transfer, parking and so on when they are requested.

The SIP mechanism for this is called re-INVITE. Two phones which are happily talking to each other can have the media stream changed mid-call using this mechanism, so Asterisk can unstitch the direct link and re-connect the two legs to itself.

However, not all phones support this mechanism. If you set canreinvite=no on a SIP channel, it's saying "this phone doesn't support the re-INVITE mechanism for reconnecting the audio mid-call". Asterisk therefore decides that it must insert itself into the media stream for the whole duration of the call, so that it is already there if later on one of the parties requests one of these in-call features.

Hopefully that's enough to answer your question :-) The best way to see what's going on is to look at the SIP/SDP packets themselves, which you can do either using 'sip debug' in Asterisk, or using tcpdump:

   # tcpdump -i eth0 -n -s0 -v udp port 5060
   # tcpdump -i eth1 -n -s0 -v udp port 5060

With a recent version of tcpdump, the -v option will show you the SIP/SDP payload. If it doesn't, use -X instead (capital X) which will show you hex and ASCII. -s0 means capture the whole packet, and -n means don't try to do reverse DNS lookups on every packet's IP address.

Monday, October 11, 2010

Interfaces and factories

An interface is intended to be a gateway to multiple implementations, and a typical way to produce objects that fit the interface is the Factory Method design pattern. Instead of calling a constructor directly, you call a creation method on a factory object which produces an implementation of the interface—this way, in theory, your code is completely isolated from the implementation of the interface, thus making it possible to transparently swap one implementation for another.

Saturday, October 9, 2010

Multiple inheritance

In a derived class, you aren’t forced to have a base class that is either abstract or "concrete" (one with no abstract methods). If you do inherit from a non-interface, you can inherit from only one. All the rest of the base elements must be interfaces. You place all the interface names after the implements keyword and separate them with commas. You can have as many interfaces as you want. You can upcast to each interface, because each interface is an independent type.

When you combine a concrete class with interfaces this way, the concrete class must come first, then the interfaces. (The compiler gives an error otherwise.)

Keep in mind that one of the core reasons for interfaces is to upcast to more than one base type (and the flexibility that this provides). However, a second reason for using interfaces is the same as using an abstract base class: to prevent the client programmer from making an object of this class and to establish that it is only an interface.

This brings up a question: Should you use an interface or an abstract class? If it’s possible to create your base class without any method definitions or member variables, you should always prefer interfaces to abstract classes. In fact, if you know something is going to be a base class, you can consider making it an interface

Strategy design patern

Creating a method that behaves differently depending on the argument object that you pass it is called the Strategy design pattern. The method contains the fixed part of the algorithm to be performed, and the Strategy contains the part that varies. The Strategy is the object that you pass in, and it contains code to be executed.

Covariant return types

Java SE5 adds covariant return types, which means that an overridden method in a derived class can return a type derived from the type returned by the base-class method.

Friday, October 8, 2010

Interfaces method is public

To create an interface, use the interface keyword instead of the class keyword. As with a class, you can add the public keyword before the interface keyword (but only if that interface is defined in a file of the same name). If you leave off the public keyword, you get package access, so the interface is only usable within the same package. An interface can also contain fields, but these are implicitly static and final.
You can choose to explicitly declare the methods in an interface as public, but they are public even if you don’t say it. So when you implement an interface, the methods from the interface must be defined as public. Otherwise, they would default to package access, and you’d be reducing the accessibility of a method during inheritance, which is not allowed by the Java compiler.

Monday, October 4, 2010

Dynamic binding

All method binding in Java uses late binding unless the method is static or final (private methods are implicitly final). This means that ordinarily you don’t need to make any decisions about whether late binding will occur — it happens automatically.

Why would you declare a method final? It prevents anyone from overriding that method. Perhaps more important, it effectively "turns off" dynamic binding, or rather it tells the compiler that dynamic binding isn’t necessary. This allows the compiler to generate slightly more efficient code for final method calls. However, in most cases it won’t make any overall performance difference in your program, so it’s best to only use final as a design decision, and not as an attempt to improve performance.

Sunday, October 3, 2010

Overriding final method

"Overriding" can only occur if something is part of the base-class interface. That is, you must be able to upcast an object to its base type and call the same method. If a method is private, it isn’t part of the base-class interface. It is just some code that’s hidden away inside the class, and it just happens to have that name, but if you create a public, protected, or package-access method with the same name in the derived class, there’s no connection to the method that might happen to have that name in the base class. You haven’t overridden the method; you’ve just created a new method. Since a private method is unreachable and effectively invisible, it doesn’t factor into anything except for the code organization of the class for which it was defined.

final keyword

With a primitive, final makes the value a constant, but with an object reference, final makes the reference a constant. Once the reference is initialized to an object, it can never be changed to point to another object. However, the object itself can be modified; Java does not provide a way to make any arbitrary object a constant. (You can, however, write your class so that objects have the effect of being constant.) This restriction includes arrays, which are also objects.

A field that is both static and final has only one piece of storage that cannot be changed. (that is, compile-time constants)

Composition vs. inheritance

In object-oriented programming, the most likely way that you’ll create and use code is by simply packaging data and methods together into a class, and using objects of that class. You’ll also use existing classes to build new classes with composition. Less frequently, you’ll use inheritance. So although inheritance gets a lot of emphasis while learning OOP, it doesn’t mean that you should use it everywhere you possibly can. On the contrary, you should use it sparingly, only when it’s clear that inheritance is useful. One of the clearest ways to determine whether you should use composition or inheritance is to ask whether you’ll ever need to upcast from your new class to the base class. If you must upcast, then inheritance is necessary, but if you don’t need to upcast, then you should look closely at whether you need inheritance.

Thursday, September 30, 2010

access specifier for class

1. There can be only one public class per compilation unit (file). The idea is that each compilation unit has a single public interface represented by that public class. It can have as many supporting package-access classes as you want. If you have more than one public class inside a compilation unit, the compiler will give you an error message.

2. The name of the public class must exactly match the name of the file containing the compilation unit, including capitalization. So for Widget, the name of the file must be Widget.java, not widget.java or WIDGET.java. Again, you’ll get a compile-time error if they don’t agree.

3. It is possible, though not typical, to have a compilation unit with no public class at all. In this case, you can name the file whatever you like (although naming it arbitrarily will be confusing to people reading and maintaining the code).

Note that a class cannot be private (that would make it inaccessible to anyone but the class) or protected So you have only two choices for class access: package access or public. If you don’t want anyone else to have access to that class, you can make all the constructors private, thereby preventing anyone but you, inside a static member of the class, from creating an object of that class.

import static single class declaration

SingleStaticImportDeclaration:
import static TypeName . Identifier;

The TypeName must be the canonical name of a class or interface type. The Identifier must name at least one static member of the named type.

StaticImportOnDemandDeclaration:
import static TypeName . * ;

Wednesday, September 29, 2010

Integer compare with ''

There is a tricky bug if you compare a number with empty string and if the number = 0:
                                                                                                    
#!/usr/bin/perl
#use warnings;
use strict;

my $v;

undef $v;

if (!defined($v)) {
print "Oops! \$v is not defined\n";
}

$v = 0;

if ($v == '') {
print "Oops! \$v == \'\'\n";
}

__END__

Result:
Oops! $v is not defined
Oops! $v == ''


You can see that if $v = 0, the condition:

$v == ''

will get TRUE!

Of course if you turn on warnings, you will not ignore this bug because compiler will give you this:

Argument "" isn't numeric in numeric eq (==) at ...

SUM(A + B) vs SUM(A) + SUM(B)

In PostgreSQL, a integer plus a null get null, so these two expressions is different not only in result but also in logic:

SELECT SUM(A + B) FROM youtable;
SELECT SUM(A) + SUM(B) FROM youtable;

You can verify this if your A or B has null value.

Compilation unit

When you create a source-code file for Java, it’s commonly called a compilation unit (sometimes a translation unit). Each compilation unit must have a name ending in .java, and inside the compilation unit there can be a public class that must have the same name as the file (including capitalization, but excluding the .java file name extension). There can be only one public class in each compilation unit; otherwise, the compiler will complain. If there are additional classes in that compilation unit, they are hidden from the world outside that package because they’re not public, and they comprise "support" classes for the main public class.

Monday, September 27, 2010

How an object is created

To summarize the process of creating an object, consider a class called Dog:
1. Even though it doesn’t explicitly use the static keyword, the constructor is actually a static method. So the first time an object of type Dog is created, or the first time a static method or static field of class Dog is accessed, the Java interpreter must locate Dog.class, which it does by searching through the classpath.
2. As Dog.class is loaded (creating a Class object, which you’ll learn about later), all of its static initializers are run. Thus, static initialization takes place only once, as the Class object is loaded for the first time.
3. When you create a new Dog( ), the construction process for a Dog object first allocates enough storage for a Dog object on the heap.
4. This storage is wiped to zero, automatically setting all the primitives in that Dog object to their default values (zero for numbers and the equivalent for boolean and char) and the references to null.
5. Any initializations that occur at the point of field definition are executed.
6. Constructors are executed. this might actually involve a fair amount of activity, especially when inheritance is involved.

Order of initialization

Within a class, the order of initialization is determined by the order that the variables are defined within the class. The variable definitions may be scattered throughout and in between method definitions, but the variables are initialized before any methods can be called—even the constructor.

Sunday, September 26, 2010

Cleanup: finalization and garbage collection

The garbage collector only knows how to release memory allocated with new.
To handle this case, Java provides a method called finalize( ) that you can define for your class. Here’s how it’s supposed to work. When the garbage collector is ready to release the storage used for your object, it will first call finalize( ), and only on the next garbage-collection pass will it reclaim the object’s memory. So if you choose to use finalize( ), it gives you the ability to perform some important cleanup at the time of garbage collection.

1.Your objects might not get garbage collected.
2.Garbage collection is not destruction.

What it means is that if there is some activity that must be performed before you no longer need an object, you must perform that activity yourself. Java has no destructor or similar concept, so you must create an ordinary method to perform this cleanup.

3.Garbage collection is only about memory.

The meaning of static

With the this keyword in mind, you can more fully understand what it means to make a method static. It means that there is no this for that particular method. You cannot call non-static methods from inside static methods (although the reverse is possible), and you can call a static method for the class itself, without any object. In fact, that’s primarily what a static method is for. It's as if you're creating the equivalent of a global method. However, global methods are not permitted in Java, and putting the static method inside a class allows it access to other static methods and to static fields.
Some people argue that static methods are not object-oriented, since they do have the semantics of a global method; with a static method, you don’t send a message to an object, since there’s no this. This is probably a fair argument, and if you find yourself using a lot of static methods, you should probably rethink your strategy. However, statics are pragmatic, and there are times when you genuinely need them, so whether or not they are "proper OOP" should be left to the theoreticians.

The use of "this"

The this keyword is used only for those special cases in which you need to explicitly use the reference to the current object.

  • It’s often used in return statements when you want to return the reference to the current object.

  • It is also useful for passing the current object to another method.

  • When you write several constructors for a class, there are times when you’d like to call one constructor from another to avoid duplicating code. You can make such a call by using the this keyword.
    While you can call one constructor using this, you cannot call two. In addition, the constructor call must be the first thing you do, or you’ll get a compiler error message.

  • Avoid conflict with member variable from method auto variable
    this.s = s;

    Where the first s is member, the second is a auto variable in a method.

Saturday, September 25, 2010

Default constructor

A default constructor (a.k.a. a "no-arg" constructor) is one without arguments that is used to create a "default object." If you create a class that has no constructors, the compiler will automatically create a default constructor for you.

However, if you define any constructors (with or without arguments), the compiler will not synthesize one for you!

When you don’t put in any constructors, it’s as if the compiler says, "You are bound to need some constructor, so let me make one for you." But if you write a constructor, the compiler says, "You’ve written a constructor so you know what you’re doing; if you didn’t put in a default it’s because you meant to leave it out."

Friday, September 24, 2010

"goto" in Java

The only place a label is useful in Java is right before an iteration statement. And that means right before — it does no good to put any other statement between the label and the iteration. And the sole reason to put a label before an iteration is if you’re going to nest another iteration or a switch inside it. That’s because the break and continue keywords will normally interrupt only the current loop, but when used with a label, they’ll interrupt the loops up to where the label exists:

label1:
outer-iteration {
inner-iteration {
//...
break; // (1)
//...
continue; // (2)
//...
continue label1; // (3)
//...
break label1; // (4)
}
}

In (1), the break breaks out of the inner iteration and you end up in the outer iteration. In (2), the continue moves back to the beginning of the inner iteration. But in (3), the continue label1 breaks out of the inner iteration and the outer iteration, all the way back to label1. Then it does in fact continue the iteration, but starting at the outer iteration. In (4), the break label1 also breaks all the way out to label1, but it does not reenter the iteration. It actually does break out of both iterations.

Foreach Syntax

Java SE5 introduces a new and more succinct for syntax, for use with arrays and containers. This is often called the foreach syntax, and it means that you don’t have to create an int to count through a sequence of items—the foreach produces each item for you, automatically.

foreach will also work with any object that is Iterable

The foreach syntax not only saves time when typing in code. More importantly, it is far easier to read and says what you are trying to do (get each element of the array) rather than giving the details of how you are doing it ("I’m creating this index so I can use it to select each of the array elements.").
Example:

control/ForEachFloat.java

The comma operator

Earlier in this chapter I stated that the comma operator (not the comma separator, which is used to separate definitions and method arguments) has only one use in Java: in the control expression of a for loop. In both the initialization and step portions of the control expression, you can have a number of statements separated by commas, and those statements will be evaluated sequentially.

Using the comma operator, you can define multiple variables within a for statement, but they must be of the same type.

Thursday, September 23, 2010

Casting

Java allows you to cast any primitive type to any other primitive type, except for boolean, which doesn’t allow any casting at all. Class types do not allow casting. To convert one to the other, there must be special methods.

Casting from a float or double to an integral value always truncates the number. If instead you want the result to be rounded, use the round( ) methods in java.lang.Math

Wednesday, September 22, 2010

Unsigned right shift operator

The signed right shift >> uses sign extension: If the value is positive, zeroes are inserted at the higher-order bits; if the value is negative, ones are inserted at the higher-order bits. Java has also added the unsigned right shift >>>, which uses zero extension: Regardless of the sign, zeroes are inserted at the higher-order bits. This operator does not exist in C or C++.

If you shift a char, byte, or short, it will be promoted to int before the shift takes place, and the result will be an int. Only the five low-order bits of the right-hand side will be used. This prevents you from shifting more than the number of bits in an int. If you’re operating on a long, you’ll get a long result. Only the six low-order bits of the right-hand side will be used, so you can’t shift more than the number of bits in a long.

For example:

int i = -1;
i >>>= 123; // For int, only low-order 5 bits of 123 will be used: 27
// So it is actually i >>>= 27
// Result is 31
System.out.println(i);


Refer to Page 43 for primitive type in Java

Tuesday, September 21, 2010

Shell Tips - Would be growing continuously

Every time looking for a small useful but seldom used tips all over the internet I hate it.


How to output backslash escapes useing echo?


From echo(1):

-e enable interpretation of backslash escapes
-E disable interpretation of backslash escapes (default)

So by default there is no backslash escapes! If you want, you have to do like this:

echo -e "\b\c"


What does exec do?


From bash(1):

exec [-cl] [-a name] [command [arguments]]
If command is specified, it replaces the shell. No new process is created. The
arguments become the arguments to command. If the -l option is supplied, the
shell places a dash at the beginning of the zeroth arg passed to command.
This is what login(1) does. The -c option causes command to be executed with
an empty environment. If -a is supplied, the shell passes name as the zeroth
argument to the executed command. If command cannot be executed for some reason,
a non-interactive shell exits, unless the shell option execfail is en-
abled, in which case it returns failure. An interactive shell returns failure
if the file can not be executed. If command is not specified, any redirections
take effect in the current shell, and the return status is 0. If there is a
redirection error, the return status is 1.

exec is useful when you want to set script redirection for all your scripts in current shell, otherwise you will have to set redirection for each.

exec 1>STDOUT_GOES_TO_HERE 2>STDERR_GOES_TO_THERE

After this, all following scripts running from this shell will redirect their STDOUT to STDOUT_GOES_TO_HERE and STDERR to STDERR_GOES_TO_THERE


Where to find ASCII?



man ascii


Using a Control Character in a Script


From UNIX POWER TOOLS
There are times when you need to use non-printing control characters in a script file. If you type them directly into the file, they can be invisible to printers and on your screen - or, worse, they can cause trouble when you print or display the file.

One time you might need to store control characters in a script is when you're writing sed substitution commands; you don't know what delimiters to use because the strings you're substituting could contain almost any text:

sed "s/$something/$whoknows/"

Because sed can use almost any character as the delimiter, you can use a control character like CTRL-A instead of the slash (/). Another time you might also need to use non-printable strings of characters is for controlling a terminal; you won't want to type an Escape character directly into the file.

The answer is to use a command that will create the control characters as the script runs - and store them in shell variables.

If your version of echo interprets an octal number in a string like \001 as its ASCII value, the job is easy. An octal-to-ASCII chart shows you that 001 is CTRL-A. You can store the output of echo in a shell variable, and use the variable wherever you need a CTRL-A character:

ca=`echo '\001'` # control-A character
...
sed "s${ca}$something${ca}$whoknows${ca}"


Remove ^M characters at end of lines in vi


UNIX treats the end of line differently than other operating systems. Sometimes when editing files in both Windows and UNIX environments, a CTRL-M character is visibly displayed at the end of each line as ^M in vi.

To remove the ^M characters at the end of all lines in vi, use:

:%s/^V^M//g


The ^v is a CONTROL-V character and ^m is a CONTROL-M. When you type this, it will look like this:

:%s/^M//g


In UNIX, you can escape a control character by preceeding it with a CONTROL-V. The :%s is a basic search and replace command in vi. It tells vi to replace the regular expression between the first and second slashes (^M) with the text between the second and third slashes (nothing in this case). The g at the end directs vi to search and replace globally (all occurrences).

__CONTINUED__

Wednesday, September 15, 2010

COPY support of PostgreSQL

For details refer to DBD::Pg document and

http://www.postgresql.org/docs/current/static/sql-copy.html


$dbh->do("COPY mytable FROM STDIN");
$dbh->pg_putline("123\tPepperoni\t3\n");
$dbh->pg_putline("314\tMushroom\t8\n");
$dbh->pg_putline("6\tAnchovies\t100\n");
$dbh->pg_endcopy;

Thursday, September 2, 2010

DBIx::Class primary key if underlying RDBMS table lack one

The Significance and Importance of Primary Keys

The concept of a primary key in DBIx::Class warrants special discussion. The formal definition (which somewhat resembles that of a classic RDBMS) is a unique constraint that is least likely to change after initial row creation. However this is where the similarity ends. Any time you call a CRUD operation on a row (e.g. delete, update, discard_changes, etc.) DBIx::Class will use the values of of the primary key columns to populate the WHERE clause necessary to accomplish the operation. This is why it is important to declare a primary key on all your result sources even if the underlying RDBMS does not have one. In a pinch one can always declare each row identifiable by all its columns:


__PACKAGE__->set_primary_keys (__PACKAGE__->columns);

Tuesday, August 31, 2010

Using tar to Perform Incremental Dumps

Incremental backup is a special form of GNU tar archive that
stores additional metadata so that exact state of the file system
can be restored when extracting the archive.


GNU tar currently offers two options for handling incremental
backups: ‘--listed-incremental=snapshot-file’ (‘-g

snapshot-file
’) and ‘--incremental’ (‘-G’).



The option ‘--listed-incremental’ instructs tar to operate on
an incremental archive with additional metadata stored in a standalone
file, called a snapshot file. The purpose of this file is to help
determine which files have been changed, added or deleted since the
last backup, so that the next incremental backup will contain only
modified files. The name of the snapshot file is given as an argument
to the option:




--listed-incremental=file

-g file

Handle incremental backups with snapshot data in file.




To create an incremental backup, you would use
--listed-incremental’ together with ‘--create

(see section How to Create Archives). For example:


 
$ tar --create \
--file=archive.1.tar \
--listed-incremental=/var/log/usr.snar \
/usr



This will create in ‘archive.1.tar’ an incremental backup of
the ‘/usr’ file system, storing additional metadata in the file
/var/log/usr.snar’. If this file does not exist, it will be
created. The created archive will then be a level 0 backup;
please see the next section for more on backup levels.


Otherwise, if the file ‘/var/log/usr.snar’ exists, it
determines which files are modified. In this case only these files will be
stored in the archive. Suppose, for example, that after running the
above command, you delete file ‘/usr/doc/old’ and create
directory ‘/usr/local/db’ with the following contents:


 
$ ls /usr/local/db
/usr/local/db/data
/usr/local/db/index


Some time later you create another incremental backup. You will
then see:


 
$ tar --create \
--file=archive.2.tar \
--listed-incremental=/var/log/usr.snar \
/usr

tar: usr/local/db: Directory is new
usr/local/db/
usr/local/db/data
usr/local/db/index


The created archive ‘archive.2.tar’ will contain only these
three members. This archive is called a level 1 backup. Notice
that ‘/var/log/usr.snar’ will be updated with the new data, so if
you plan to create more ‘level 1’ backups, it is necessary to
create a working copy of the snapshot file before running

tar. The above example will then be modified as follows:


 
$ cp /var/log/usr.snar /var/log/usr.snar-1
$ tar --create \
--file=archive.2.tar \
--listed-incremental=/var/log/usr.snar-1 \
/usr





You can force ‘level 0’ backups either by removing the snapshot
file before running tar, or by supplying the

--level=0’ option, e.g.:


 
$ tar --create \
--file=archive.2.tar \
--listed-incremental=/var/log/usr.snar-0 \
--level=0 \
/usr



Incremental dumps depend crucially on time stamps, so the results are
unreliable if you modify a file's time stamps during dumping (e.g.,
with the ‘--atime-preserve=replace’ option), or if you set the clock
backwards.




Metadata stored in snapshot files include device numbers, which,
obviously are supposed to be non-volatile values. However, it turns
out that NFS devices have undependable values when an automounter
gets in the picture. This can lead to a great deal of spurious
redumping in incremental dumps, so it is somewhat useless to compare
two NFS devices numbers over time. The solution implemented
currently is to consider all NFS devices as being equal
when it comes to comparing directories; this is fairly gross, but
there does not seem to be a better way to go.


Apart from using NFS, there are a number of cases where
relying on device numbers can cause spurious redumping of unmodified
files. For example, this occurs when archiving LVM snapshot
volumes. To avoid this, use ‘--no-check-device’ option:





--no-check-device


Do not rely on device numbers when preparing a list of changed files
for an incremental dump.




--check-device

Use device numbers when preparing a list of changed files
for an incremental dump. This is the default behavior. The purpose
of this option is to undo the effect of the ‘--no-check-device
if it was given in TAR_OPTIONS environment variable
(see TAR_OPTIONS).





There is also another way to cope with changing device numbers. It is
described in detail in Fixing Snapshot Files.


Note that incremental archives use tar extensions and may
not be readable by non-GNU versions of the tar program.





To extract from the incremental dumps, use
--listed-incremental’ together with ‘--extract
option (see section Extracting Specific Files). In this case, tar does
not need to access snapshot file, since all the data necessary for
extraction are stored in the archive itself. So, when extracting, you
can give whatever argument to ‘--listed-incremental’, the usual
practice is to use ‘--listed-incremental=/dev/null’.
Alternatively, you can use ‘--incremental’, which needs no
arguments. In general, ‘--incremental’ (‘-G’) can be
used as a shortcut for ‘--listed-incremental’ when listing or
extracting incremental backups (for more information regarding this
option, see incremental-op).


When extracting from the incremental backup GNU tar attempts to
restore the exact state the file system had when the archive was
created. In particular, it will delete those files in the file
system that did not exist in their directories when the archive was
created. If you have created several levels of incremental files,
then in order to restore the exact contents the file system had when
the last level was created, you will need to restore from all backups
in turn. Continuing our example, to restore the state of ‘/usr
file system, one would do(12):


 
$ tar --extract \
--listed-incremental=/dev/null \
--file archive.1.tar


$ tar --extract \
--listed-incremental=/dev/null \
--file archive.2.tar



To list the contents of an incremental archive, use ‘--list
(see section How to List Archives), as usual. To obtain more information about the
archive, use ‘--listed-incremental’ or ‘--incremental
combined with two ‘--verbose’ options(13):


 
tar --list --incremental --verbose --verbose archive.tar


This command will print, for each directory in the archive, the list
of files in that directory at the time the archive was created. This
information is put out in a format which is both human-readable and
unambiguous for a program: each file name is printed as


 
x file


where x is a letter describing the status of the file: ‘Y

if the file is present in the archive, ‘N’ if the file is not
included in the archive, or a ‘D’ if the file is a directory (and
is included in the archive). See section Dumpdir, for the detailed
description of dumpdirs and status codes. Each such
line is terminated by a newline character. The last line is followed
by an additional newline to indicate the end of the data.


The option ‘--incremental’ (‘-G’)
gives the same behavior as ‘--listed-incremental’ when used
with ‘--list’ and ‘--extract’ options. When used with

--create’ option, it creates an incremental archive without
creating snapshot file. Thus, it is impossible to create several
levels of incremental backups with ‘--incremental’ option.

Tuesday, August 24, 2010

15 Advanced PostgreSQL Commands with Examples

1. How to find the largest table in the postgreSQL database?



$ /usr/local/pgsql/bin/psql test
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.

Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit

test=# SELECT relname, relpages FROM pg_class ORDER BY relpages DESC;
relname | relpages
-----------------------------------+----------
pg_proc | 50
pg_proc_proname_args_nsp_index | 40
pg_depend | 37
pg_attribute | 30


If you want only the first biggest table in the postgres database then append the above query with limit as:



# SELECT relname, relpages FROM pg_class ORDER BY relpages DESC limit 1;
relname | relpages
---------+----------
pg_proc | 50
(1 row)


  • relname – name of the relation/table.

  • relpages - relation pages ( number of pages, by default a page is 8kb )


  • pg_class – system table, which maintains the details of relations

  • limit 1 – limits the output to display only one row.



2. How to calculate postgreSQL database size in disk ?


pg_database_size is the function which gives the size of mentioned database. It shows the size in bytes.



# SELECT pg_database_size('geekdb');
pg_database_size
------------------
63287944
(1 row)


If you want it to be shown pretty, then use pg_size_pretty function which converts the size in bytes to human understandable format.



# SELECT pg_size_pretty(pg_database_size('geekdb'));
pg_size_pretty
----------------
60 MB
(1 row)


3. How to calculate postgreSQL table size in disk ?


This is the total disk space size used by the mentioned table including index and toasted data. You may be interested in knowing only the size of the table excluding the index then use the following command.



# SELECT pg_size_pretty(pg_total_relation_size('big_table'));
pg_size_pretty
----------------
55 MB
(1 row)

How to find size of the postgreSQL table ( not including index ) ?


Use pg_relation_size instead of pg_total_relation_size as shown below.



# SELECT pg_size_pretty(pg_relation_size('big_table'));
pg_size_pretty
----------------
38 MB
(1 row)


4. How to view the indexes of an existing postgreSQL table ?



Syntax: # \d table_name

As shown in the example below, at the end of the output you will have a section titled as indexes, if you have index in that table. In the example below, table pg_attribute has two btree indexes. By default postgres uses btree index as it good for most common situations.



test=# \d pg_attribute
Table "pg_catalog.pg_attribute"
Column | Type | Modifiers
---------------+----------+-----------
attrelid | oid | not null
attname | name | not null
atttypid | oid | not null
attstattarget | integer | not null
attlen | smallint | not null
attnum | smallint | not null
attndims | integer | not null
attcacheoff | integer | not null
atttypmod | integer | not null
attbyval | boolean | not null
attstorage | "char" | not null
attalign | "char" | not null
attnotnull | boolean | not null
atthasdef | boolean | not null
attisdropped | boolean | not null
attislocal | boolean | not null
attinhcount | integer | not null
Indexes:
"pg_attribute_relid_attnam_index" UNIQUE, btree (attrelid, attname)
"pg_attribute_relid_attnum_index" UNIQUE, btree (attrelid, attnum)


5. How to specify postgreSQL index type while creating a new index on a table ?


By default the indexes are created as btree. You can also specify the type of index during the create index statement as shown below.



Syntax: CREATE INDEX name ON table USING index_type (column);
# CREATE INDEX test_index ON numbers using hash (num);


6. How to work with postgreSQL transactions ?


How to start a transaction ?


# BEGIN -- start the transaction.

How to rollback or commit a postgreSQL transaction ?


All the operations performed after the BEGIN command will be committed to the postgreSQL database only you execute the commit command. Use rollback command to undo all the transactions before it is committed.



# ROLLBACK -- rollbacks the transaction.
# COMMIT -- commits the transaction.


7. How to view execution plan used by the postgreSQL for a SQL query ?


# EXPLAIN query;


8. How to display the plan by executing the query on the server side ?


This executes the query in the server side, thus does not shows the output to the user. But shows the plan in which it got executed.


# EXPLAIN ANALYZE query;


9. How to generate a series of numbers and insert it into a table ?


This inserts 1,2,3 to 1000 as thousand rows in the table numbers.


# INSERT INTO numbers (num) VALUES ( generate_series(1,1000));


10. How to count total number of rows in a postgreSQL table ?


This shows the total number of rows in the table.


# select count(*) from table;

Following example gives the total number of rows with a specific column value is not null.


# select count(col_name) from table;

Following example displays the distinct number of rows for the specified column value.


# select count(distinct col_name) from table;


11. How can I get the second maximum value of a column in the table ?


First maximum value of a column


# select max(col_name) from table;

Second maximum value of a column



# SELECT MAX(num) from number_table where num < ( select MAX(num) from number_table );


12. How can I get the second minimum value of a column in the table ?


First minimum value of a column


# select min(col_name) from table;

Second minimum value of a column



# SELECT MIN(num) from number_table where num > ( select MIN(num) from number_table );


13. How to view the basic available datatypes in postgreSQL ?


Below is the partial output that displays available basic datatypes and it’s size.



test=# SELECT typname,typlen from pg_type where typtype='b';
typname | typlen
----------------+--------
bool | 1
bytea | -1
char | 1
name | 64
int8 | 8
int2 | 2
int2vector | -1


  • typname – name of the datatype

  • typlen – length of the datatype



14. How to redirect the output of postgreSQL query to a file?



# \o output_file
# SELECT * FROM pg_class;

The output of the query will be redirected to the “output_file”. After the redirection is enabled, the select command will not display the output in the stdout. To enable the output to the stdout again, execute the \o without any argument as mentioned below.


# \o


As explained in our earlier article, you can also backup and restore postgreSQL database using pg_dump and psql.



15. Storing the password after encryption.


PostgreSQL database can encrypt the data using the crypt command as shown below. This can be used to store your custom application username and password in a custom table.


# SELECT crypt ( 'sathiya', gen_salt('md5') );

PostgreSQL crypt function Issue:


The postgreSQL crypt command may not work on your environment and display the following error message.



ERROR: function gen_salt("unknown") does not exist
HINT: No function matches the given name and argument types.
You may need to add explicit type casts.

PostgreSQL crypt function Solution:


To solve this problem, installl the postgresql-contrib-your-version package and execute the following command in the postgreSQL prompt.


# \i /usr/share/postgresql/8.1/contrib/pgcrypto.sql

Wednesday, August 11, 2010

A self-contained perl and cpan for Catalyst applications deployment

Build a local perl and cpan for catalyst applications. Keep it simple and consistent for product releases. All the run-time environment will go to /opt/nmetrics.

1. Build a latest local perl

# tar xzvf perl-5.12.1.tar.gz
# cd perl-5.12.1
# sh Configure -de -Dprefix=/opt/nmetrics
# make
# make test
# make install


2. Local cpan
Nothing special for cpan, just run it from /opt/nmetrics/bin, that's it! All modules installed from CPAN will go into local perl library directory.
For modules released not from CPAN(3rd party modules, licensed modules), just put them into local perl library.
As long as you invoke perl from local, not from system, all the dependencies should self-contained.
Then you can ship /opt/nmetrics as a whole product.

3. Perl 5.12.x deprecated warnings
Perl 5.12.x will warn deprecated features even if you are not using warnings. So if you want to disable this:

use 5.012;
no warnings 'deprecated';
temp_warning();

sub temp_warning {
# needs to be one level lower than the warnings setting
warn "Hey Evel Knievel! Deprecation warnings are disabled!" unless
warnings::enabled( 'deprecated' );
}


4. Applications
All the applications and scripts must use /opt/nmetrics/bin/perl for product release

5. Use pure perl implementations
As much as possible. Keep product clean in self-contained style.

6. Subversion
__ALL__

Wednesday, July 14, 2010

Catalyst $c->req->params sucks

Catalyst has added parameters() to its Catalyst::Request object and it allows you to get values in an array ref if there are multiple.



my $form = $c->request->parameters;

# ?a=b&b=c
# $form = { a => 'b', b => 'c' }
# ?a=b&a=c&b=c
# $form = { a => [ 'b', 'c' ], b => 'c' };



This might look intuitive but wait a minute. The data structure gets different per user input rather than how you code it, and that sucks. This means you have to always check if the value is an array ref or not, since:



my $v = $c->request->parameters;
my $query = $v->{query};
my @names = @{$v->{name}};



$query might become ARRAY(0xabcdef) if there are multiple query= parameters in the query. @names line might cause Can't use string as an ARRAY ref error if there's only one (or zero) name parameter. This causes horrible issues when using standard HTML elements like option or checkbox forms, or tools like jQuery's serialize().

The correct way to write that would be:



my $v = $c->request->parameters;
my $query = ref $v->{query} eq 'ARRAY' ? $v->{query}->[0] : $v->{query};
my @names = ref $v->{name} eq 'ARRAY' ? @{$v->{name}} : ($v->{name});



and it is tedious and gross.

Thursday, July 8, 2010

Real private method in Perl

For a truly private method, you would usually write the following:


my $_private_method = sub { my ($self, ...) = @_; ... };
...
$self->$_private_method($some, $arguments);
...


which makes the method scoped to the block it was defined in, or the file if it’s not within braces.

This is Perl.

The reason is $_private_method is not special, it's just a "my" variable. So it will be "invisible" outside block or file scope.

Wednesday, June 23, 2010

perlipc in CGI

Sometimes we need start a background process from CGI. When leave that CGI by closing page or window we wish to clean up what we have put in the background. This is perlipc get into role.

There is an example. I have a page displaying a list of network interfaces. I want to get a real time throughput(I/O) chart window when I click on one of these interfaces. Certainly it should be "UP". My solution is forking a poller in background. Poller keeps polling, calculating, and writing data to a shared memory segment. CGI reads from shared memory segment then draws chart for user.



+----------+ fork +------+
|chart page| ----------------> |poller|
+----------+ +------+
| ^
| |
|request |Shared Memory
| |
| +--------+ |
+------> | charter| <------+
+--------+


When click "Close" button on chart page, I need to clean up shared memory and kill the poller. This works fine.

This is the chart page:


...
...

defined (my $pid = fork) or die "Can't fork: $!";

if (!$pid) {
setsid;
open STDIN, '>/dev/null' or die "Can't read from /dev/null: $!";
open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
exec '/usr/local/NPMS/bin/if_poller.pl', $val->{ip}, $val->{commstring}, $val->{if};
}
...
...

print <<ENDOFFORM;
<script type="text/javascript">
function clean_up() {
document.getElementById('form1').submit();
window.close();
}
</script>
<form id="form1" method="post" action="clean_poller.cgi">
<input name="pid" value="$pid" type="hidden">
<input name="close" value="Close" onclick="clean_up();" type="button">
</form>
ENDOFFORM



This is the clean_poller.cgi:


...
...
kill 'INT' => $in{'pid'};
...
...


This is the poller which trap SIGINT to gracefully exit after clean up resources:


...
...
my $EXIT = 0;
$SIG{INT} = sub {
$EXIT = 1;
};
...
...
while (1) {
...
...
do polling stuff
do {
IPC::Shareable->clean_up_all;
exit;
} if $EXIT;
...
...
}



Let me explain this whole thing:
1. User click one of the active interfaces("UP" state)
2. Open a new window
3. Before display chart, fork a poller
4. poller start to work in background
5. poller write data sample to shared memory segment
6. chart page request charter to draw a chart
7. charter read data sample from shared memory segment and draw
8. User click "Close" button
9. chart page request clean_poller.cgi before closing
10. clean_poller.cgi get pid and send a INT to it
11. clean_poller.cgi close window
12. poller get INT signal, clean up shared memory segment he created
13. poller exit
14. all resources get cleaned up

That's it!

Detail information refer to perlipc, IPC::Shareable, signal, fork, ...

Monday, June 21, 2010

SNMP read IfInOctets => great trend But what about the absolute throughput value?

Original Link

If you have ever tried to read the throughput value of an ethernet interface in and out using SNMP you may notice that it’s quite easy to get a nice trend graph using your favorite plotting tool (MRTG, zabbix,…) but when you try to get the actual throughput value the amount just never seems to be correct.

During this article I’ll try to explain how the Cisco IfInOctets and IfOutOctets work and what you need to do to get the right value.


1) What is the IfInOctets and IfOutOctets value:

The first thing you need to know is that a Cisco router holds it’s interface value in two tables IfTable and IfXTable, these are fully described in RFC1213/RFC2233.

- ifTable defines 32-bit counters for inbound and outbound octets

-ifXTable provides similar 64-bit counters, also called high capacity (HC) counters

The values we are interested in are IfInOctest, IfHCInOctest, IfOutOctest and IfHCOutOctests. For the sake of this article we will focus on the In values but know that the exact same logic also holds for the Out counters. So lets have a look at the two in Counters. Let’s have a look at what the Cisco documentation tell’s us about these two counters:

- IfInOctets: "The total number of octets received on the interface,
including framing characters. The reference OID is: 1.3.6.1.2.1.2.2.1.10

Lets query this value of interface eth0 of a CentOS Linux Server and see the result:

[root@buildbox55-64bit Perl]# snmpwalk -Os -c public -v2c 192.168.1.230 .1.3.6.1.2.1.2.2.1.10.2
ifInOctets.2 = Counter32: 77043026


- IfHCInOctets: "The total number of octets received on the interface,
including framing characters. This object is a 64-bit
version of ifInOctets. The reference OID is: 1.3.6.1.2.1.31.1.1.1.6

Lets query this value of interface eth0 of a CentOS Linux Server and see the result:

[root@buildbox55-64bit Perl]# snmpwalk -Os -c public -v2c localhost 1.3.6.1.2.1.31.1.1.1.6.2
ifHCInOctets.2 = Counter64: 78219248


As you can read, both values actually return the same data “Total number of octest received”, but we are faced with a first dilemma, you have two counters to poll, each returning a different absolute value and in some bizarre way both are giving you the Total number of octets received.

- IfInOctets 1.3.6.1.2.1.2.2.1.10

For us to understand this we need to know what the value is that is being returned. SNMP is a very basic protocol that runs on just about any network device,… The core idea behind SNMP is simplicity, generic usable and low footprint. To ensure the low footprint SNMP has very little to no intelligence built in. It just returns values you would like to monitor and relies on your toolset to harvest this data en make it usable for you.

The counter we are reading returns the amount of octets received since

- the boot of the device

- since the last rollover period

There are two concepts here that we need to explain be for the puzzle will start to fall together for you:

1) # of octets received => that means if you want to know the data throughput you will have to read the counter twice at time_slot1_value and then lets say 1 second later at time_slot2_value. To know the throughput of octets now subtract

time_slot2_value – time_slot1_value = total # of octets send

2) since the last rollover => as you can imagine the amount of octet bytes sent is just an increasing value and this number can grow really really fast. And this is where the 32bit / 64bit values come into play. In the old days with slow speed networks a 32bit value was used to store the # of octets send, once this 32bit value fill’s to it’s maximum the counter resets to Null and restarts it’s count until it reaches the maximum value again. As you can imagine on a slow speed network this 32bit value fill’s up quite gradually and rollover does not occur all that often. However on a high speed gigabit network a lot of packets are passing through the interface and a 32bit value in memory fill’s up much faster. The net problem with roll over is that at a certain point in time you will subtract time_slot1_value from time_slot2_value but time_slot2_value will be smaller than time_slot1_value thus giving you a negative net value. This is alright for trend,… analysis as long as it does not happen to often.

To give you an idea of how fast this rollover occurs:

- a 10 Mbps stream of back-to-back, full-size packets causes ifInOctets to wrap in just over 57 minutes.

- At 100 Mbps, the minimum wrap time is 5.7 minutes

- At 1 Gbps, the minimum is 34 seconds.

=> this means the 32bit value is just not good enough for modern high speed networks and you will almost always ant to resort back to the 64bit ifHCInOctets counter value.

To follow Cisco documenation: “

For interfaces that operate at 20,000,000 (20 million) bits per second or less, you must use 32-bit byte and packet counters. For interfaces that operate faster than 20 million bits per second, and slower than 650,000,000 bits per second, you must use 32-bit packet counters and 64-bit octet counters. For interfaces that operate at 650,000,000 bits/second or faster, 64-bit packet and octet counters must be used.

Correspondingly, Cisco IOS® Software does not support 64-bit counters for interface speeds of less than 20 Mbps. This means that 64-bit counters are not supported on 10 Mb Ethernet ports, only 100 Mb Fast-Ethernet and other high speed ports support 64-bit counters. “

3) Converting Octets to bits is the last part we need to understand if we want to know the bits per tick that pass through our network interface. To convert the amount of transmitted octets on the Ethernet network to bits we must multiply by 8.

The ending formula to know the #of bits being transferred between two ticks would thus be:

Value2-Value1 * 8 = # bits transferred

Sunday, June 20, 2010

Permission denied of shmget

When using IPC::Shareable as a non-root user, sometimes got this:


IPC::Shareable::SharedMem: shmget: Permission denied


Just because shared memory is same as regular file. If someone has already created this "file", you can not create it with the same name ($glue) unless your are root.

So, whoever your are, please clean up this shm after you done with it.

(tied VARIABLE)->remove;
IPC::Shareable->clean_up;
IPC::Shareable->clean_up_all;


Refer to: perldoc IPC::Shareable

find tips - about the last char

Packaging Moose binary need some CPAN source. I am using cpan2rpm. On my build box, I just use cpan to install Moose, then I knew that all the dependcies are ready. :)

Next I need to convert Moose to binary RPM, for all the source, I want to just get from ~/.cpan, but I always can not remember the -exec syntax for find. Here:

# find ~/.cpan/sources/authors/id -regex '.*\.tar\.gz$' -exec cp {} . \;

Thursday, June 17, 2010

Change IF-MIB ifTable update frequency

CentOS 5.5 x86_64
net-snmp-5.3.2.2-9

When I run this command to try to get the updated data for InOctets:

[root@buildbox55-64bit SPECS]# while [ 1 ]; do snmpwalk -Os -c MYCOMMUNITY -v2c localhost .1.3.6.1.2.1.2.2.1.10.2; sleep 1; done


It seems that the data does not change in a 30 seconds interval:

ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7925145
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505
ifInOctets.2 = Counter32: 7927505


That's ok for "Standard" SNMP poller with a minimum polling interval > 60 seconds. Now if I need a very short interval, say 3 seconds or even 1 seconds. This does not work well.

The solution is to change the IFTABLE_CACHE_TIMEOUT in net-snmp source, here is mine:

/usr/src/redhat/SOURCES/net-snmp-5.3.2.2/agent/mibgroup/if-mib/ifTable/ifTable_data_access.h

Change:

#define IFTABLE_CACHE_TIMEOUT 30

to:

#define IFTABLE_CACHE_TIMEOUT 1


then rebuild net-snmp and upgrade it. now it's working as expected:

[root@buildbox55-64bit SPECS]# while [ 1 ]; do snmpwalk -Os -c MYCOMMUNITY -v2c localhost .1.3.6.1.2.1.2.2.1.10.2; sleep 1; done
ifInOctets.2 = Counter32: 8087029
ifInOctets.2 = Counter32: 8087421
ifInOctets.2 = Counter32: 8087519
ifInOctets.2 = Counter32: 8087911
ifInOctets.2 = Counter32: 8088219
ifInOctets.2 = Counter32: 8088475
ifInOctets.2 = Counter32: 8088633
ifInOctets.2 = Counter32: 8088731
ifInOctets.2 = Counter32: 8088889
ifInOctets.2 = Counter32: 8088987
ifInOctets.2 = Counter32: 8089145
ifInOctets.2 = Counter32: 8089243
ifInOctets.2 = Counter32: 8089401
ifInOctets.2 = Counter32: 8089499
ifInOctets.2 = Counter32: 8089657
ifInOctets.2 = Counter32: 8090085
ifInOctets.2 = Counter32: 8090670
ifInOctets.2 = Counter32: 8090768
ifInOctets.2 = Counter32: 8091268
ifInOctets.2 = Counter32: 8091426
ifInOctets.2 = Counter32: 8091524
ifInOctets.2 = Counter32: 8091682
ifInOctets.2 = Counter32: 8091780
ifInOctets.2 = Counter32: 8091938
ifInOctets.2 = Counter32: 8092036
ifInOctets.2 = Counter32: 8092194
ifInOctets.2 = Counter32: 8092382
ifInOctets.2 = Counter32: 8092604
ifInOctets.2 = Counter32: 8092702
ifInOctets.2 = Counter32: 8092924
ifInOctets.2 = Counter32: 8093022
ifInOctets.2 = Counter32: 8093180
ifInOctets.2 = Counter32: 8093278
ifInOctets.2 = Counter32: 8093436
ifInOctets.2 = Counter32: 8093692
ifInOctets.2 = Counter32: 8093790
ifInOctets.2 = Counter32: 8093948
ifInOctets.2 = Counter32: 8094046
ifInOctets.2 = Counter32: 8094452
ifInOctets.2 = Counter32: 8094550
ifInOctets.2 = Counter32: 8094708
ifInOctets.2 = Counter32: 8094806
ifInOctets.2 = Counter32: 8094964
ifInOctets.2 = Counter32: 8095062
ifInOctets.2 = Counter32: 8095220
ifInOctets.2 = Counter32: 8095318
ifInOctets.2 = Counter32: 8095476
ifInOctets.2 = Counter32: 8095818
ifInOctets.2 = Counter32: 8095976

Tuesday, June 15, 2010

Emacs: Replace the standard perl-mode with cperl-mode

CPerlMode is a more advanced mode for programming Perl than the default PerlMode. To replace the standard perl-mode with cperl-mode in all cases you need the following in your ~/.emacs file (or your InitFile):

;;; cperl-mode is preferred to perl-mode
;;; "Brevity is the soul of wit"
(defalias 'perl-mode 'cperl-mode)


Alternatively, use:

(add-to-list 'auto-mode-alist '("\\.\\([pP][Llm]\\|al\\)\\'" . cperl-mode))
(add-to-list 'auto-mode-alist '("\\.\\([tT]\\)\\'" . cperl-mode))
(add-to-list 'interpreter-mode-alist '("perl" . cperl-mode))
(add-to-list 'interpreter-mode-alist '("perl5" . cperl-mode))
(add-to-list 'interpreter-mode-alist '("miniperl" . cperl-mode))


Or the more robust equivalent:

(mapc
(lambda (pair)
(if (eq (cdr pair) 'perl-mode)
(setcdr pair 'cperl-mode)))
(append auto-mode-alist interpreter-mode-alist))

Monday, June 14, 2010

Asterisk quick start guide

10-minute guide to Asterisk

Easy tips if you want to get Asterisk up and running on your Linux system within minutes:

* Download the tarball: Download the Asterisk stable distribution tarball from http://www.voip-info.org/wiki-Asterisk-mirrors.


* Build Asterisk: Unpack the tarball and run make to build it. After that, run make install.


* Install sample configuration: Run make samples after make install. This will install the standard sample configuration in the directory /etc/asterisk. Go there.


* Start Asterisk: The first time, start Asterisk in console mode with some debugging applied. If it does not start, check the hardware requirements.

# asterisk -vvvvc

* Don't change anything yet: Try to start Asterisk with NO changes to the config files. If it doesn't start then the problem is probably with your system hardware.


* Create a SIP account: Copy one of the device configs in the SIP configuration file sip.conf and change for one of your phones. You should only have to change the device id. Don't get fancy with authentication or NAT. Make sure the phone (see Asterisk phones) and your Asterisk server is on the same network, with no firewall and NAT device between them. If you want to learn more on how to get this configured, read the introdcution articles referenced to on the Asterisk page, the bottom half. (If you have a physical card, you can configure a card like an X100P instead of configuring SIP by making 2 small changes, see: http://www.digium.com/downloads/hw_article)


* Restart Asterisk: Either issue the RELOAD command at the command line interface or completly shutdown and restart Asterisk. (RELOAD should be sufficient but one of the 2 is required)


* Call the demo: test that phone by calling extension 1000 (assuming you have the sample extensions.conf). You should get the demo greeting and be able to do such things as ECHO test, leave voicemail for a sample mailbox. Instructions are in the demo greeting you will hear. How this works is explained in the extensions.conf demo file installed for you in the /etc/asterisk directory.


* Add another phone: If all of the above works then add your 2nd phone into sip.conf and add a dialplan for those 2 devices to extensions.conf so that they can call each other. (don't forget to RELOAD or restart)


* Choose a voice: Once things are working, you should decide if you want to use the default voice distributed with Asterisk, or install a professional third-party sound file collection made to replace the default voice. Voice Vector Media and others offer complete replacement sound file collections for free. In addition, inexpensive custom recording services are typically offered to allow you to customize the collection for your needs using the same voice.


* Start exploring Asterisk: If all of that works then start making fancy config files and using additional features. Maybe add a hardware card to connect your PSTN connection to your Asterisk or start experimenting with free SIP accounts on the Internet, like Free World Dialup.


Welcome to the growing Asterisk user base!

If you need more in-depth directions, see Asterisk Step-by-step Installation.

Sunday, June 13, 2010

Tell CPAN use wget only

vi /usr/lib/perl5/5.8.8/CPAN/Config.pm, add:
'dontload_hash' => {"Net::FTP" => 1, "LWP" =>1 },

then o conf:

ftp ""
links ""
ncftp ""
ncftpget ""
wget /usr/bin/wget

o conf commit

have fun!

Building RPMs from CPAN Distributions

This entry was written by Dave Cross, posted on February 8, 2010 at 1:01 PM , filed under CPAN. Bookmark the permalink.

This is the original link.

Regular readers will know that in the past I've shown some interest in building RPMs from CPAN distributions. It's been a while since I did much work in this area (although I do still release the occasional module to my RPM repository.

Over the weekend I was at FOSDEM and I attended Gabor's talk on packaging CPAN modules for Linux distributions. This has rekindled my interest in this area and I spent most of the train journey back from Brussels hacking around the area.

There's one thing that has been bothering me in particular recently. The standard RPM building mechanism (or, at least, the way it's configured in Fedora and Centos) does something incredible brain dead when trying to work out what other modules the current module depends on. It does it by parsing the source code and looking for "use" statements. This means that a module that might only be used in really obscure cases is going to be listed as a mandatory requirement for your module.

Gabor and I actually saw an example of this over the weekend when the Fedora packaging team raised a bug against Padre because it requires Win32::API. Padre, of course, only uses Win32::API when being used on Windows. And for that reason Win32::API is not listed as a dependency in its META.yml.

And that's, of course, where the RPM builders should be going to get a list of dependencies. META.yml contains the list of other modules that the author wants the module to depend on. This should be seen as the definitive list. Of course, there might be errors in that list - but that should be addressed by raising a bug against the module.

I've poked at this problem a few times, trying to work out how the RPM system parses the code and trying to replace that with code that looks at META.yml instead. But the RPM system uses a baroque system of interdependent macros and eventually they all lead to a piece of rather clunky Perl code. So each time I've approached this problem, I've backed off again.

The problem became more urgent when I wanted to package Plack for Fedora. Plack supports all sorts of hosting environments and therefore includes "use" statements loading a number of modules that most people will never use. Fedora includes Apache2, so Apache::Request (which is for Apache1) will never be available. It's not listed in META.YML, but it is used by one of the modules. The RPM build system was therefore insisting that it should be present. An impasse was reached.

Then I decided to turn the problem on its head. RPM building has two steps. You create a spec file for the RPM and then you build the RPM using the spec file and your original tarball. I started wondering if I could ensure that the spec had all of the requirements (from the META.yml). Once I'd done that I would only need to find some way to turn off the RPM build system's default behaviour.

People packaging CPAN modules for Fedora (and Centos) use a program called 'cpanspec' to generate spec files. I started digging into the code there in order to find out how to insert the list of correct dependencies.

Only to find that it has already been done. cpanspec is already doing the right thing and generating a list of 'Requires' statements from the data in META.yml.

Then all I needed to do was to see if I could turn off the (broken) default RPM build behaviour which was adding spurious extra dependencies. That proved to be easy too. It's just a case of adding %__perl_requires %{nil} to your .rpmmacros files.

So now all of my RPMs will have only the correct dependencies listed. This makes me very happy.

I suppose I should go back and rebuild all of the older ones too.

Oh, and because I've worked out a really easy way to generate this - here's a spreadsheet listing which CPAN modules are available as RPMs for Fedora. I plan to keep this list up to date (and make it much longer). [Link now fixed]

Comment for a customized spec file

Recently I need to build .rpm for ming-0.4.2. There is a perl-ext in the source tree and I need include it in .rpm:


[sean@Build-64bit SPECS]$ ./configure --prefix=/usr/local --enable-perl --disable-cpp


For C part, the original spec file is just fine, but for Perl part, I got "Installed but not packaged" error. After added missing files to spec %files section, I got working version. This is final version of ming.spec:


1 # Some distributions name their Freetype 2 package "freetype", while others
2 # name it "freetype2". You can define the name your distribution uses here.
3 %define freetype2 freetype
4
5 Summary: A SWF output library
6 Name: nMetrics-ming
7 Version: 0.4.2
8 Release: 1
9 License: LGPL
10 Group: System Environment/Libraries
11 Source: http://prdownloads.sourceforge.net/ming/nMetrics-ming-%{version}.tar.gz
12 URL: http://ming.sourceforge.net/
13 BuildRoot: %{_tmppath}/%{name}-%{version}-root
14 BuildRequires: %{freetype2}-devel zlib-devel giflib-devel libpng-devel
15 Requires: %{freetype2} zlib giflib libpng
16
17 %description
18 Ming is a C library for generating SWF ("Flash") format movies, plus a set of wrappers for using the library from C++ and popular script ing languages like PHP, Perl, Python, and Ruby.
19
20 %package devel
21 Summary: A SWF output library
22 Group: Development/Libraries
23 Requires: %{name} = %{version}
24 Requires: %{freetype2}-devel zlib-devel giflib-devel libpng-devel
25
26 %description devel
27 The ming-devel package includes the static libraries,
28 header files, and developer docs for the ming package.
29
30 Install ming-devel if you want to develop programs which
31 will use ming.
32
33 %prep
34 %setup -q
35
36 %build
37 %configure --enable-perl --disable-cpp
38 %__make %{?_smp_mflags}
39
40 %install
41 [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
42 %__make %{?_smp_mflags} \
43 DESTDIR=$RPM_BUILD_ROOT \
44 docdir=$RPM_BUILD_ROOT%{_docdir}/%{name} \
45 pkgconfigdir=%{_libdir}/pkgconfig \
46 install
47
48 %clean
49 [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
50
51 %post -p /sbin/ldconfig
52
53 %postun -p /sbin/ldconfig
54
55 %files
56 %defattr(-, root, root)
57 %doc README AUTHORS COPYING ChangeLog
58 %{_libdir}/libming*.so.*
59 %{_bindir}/*
60 %{_mandir}/man1/*
61 /usr/local/lib64/perl5/5.8.8/x86_64-linux-thread-multi/perllocal.pod
62 /usr/local/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/SWF.pm
63 /usr/local/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/SWF
64 /usr/local/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/SWF
65 /usr/local/share/man/man3/SWF*
66
67 %files devel
68 %defattr(-, root, root)
69 %{_includedir}/*
70 %{_libdir}/*.a
71 %{_libdir}/*.la
72 %{_libdir}/libming.so
73 %{_libdir}/pkgconfig
74 %{_mandir}/man3/*
75
76 %changelog
77 * Tue Sep 02 2006 John Ellson
78 - Initial changelog entry


This is the diff output between this version and original version:


6c6
< Name: nMetrics-ming
---
> Name: ming
11c11
< Source: http://prdownloads.sourceforge.net/ming/nMetrics-ming-%{version}.tar.gz
---
> Source: http://prdownloads.sourceforge.net/ming/ming-%{version}.tar.gz
37c37
< %configure --enable-perl --disable-cpp
---
> %configure
61,65d60
< /usr/local/lib64/perl5/5.8.8/x86_64-linux-thread-multi/perllocal.pod
< /usr/local/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/SWF.pm
< /usr/local/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/SWF
< /usr/local/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/SWF
< /usr/local/share/man/man3/SWF*


Comments:
1. I changed "Name:" tag(Line 6). And of course I changed tarball from ming-0.4.2.tar.gz to nMetrics-ming-0.4.2.tar.gz as you can see in the "Source:" tag(Line 11)
2. Add build options to "%configure" macro
3. Add files to "%files" section
4. The last thing not in spec file is that I changed "%{_prefix}" from default(/usr) to (/usr/local) by type this:


[sean@Build-64bit SPECS]$ rpmbuild -bb ming.spec --define '_prefix /usr/local'