Play with libgfapi and its python bindings..

What is libgfapi ?


User-space library for accessing data in GlusterFS
Filesystem-like API
Runs in application process
no FUSE, no copies, no context switches
…but same volfiles, translators, etc.
Could be used for Apache/nginx modules, MPI I/O
(maybe), Ganesha, etc. ad infinitum
BTW it’s usable from Python too :)

Yes, I copied it from rhsummit.files.wordpress.com/2013/06/darcy_th_1040_glusterfs.pdf

libgfapi improves gluster performance by avoiding “fuse” layer. Its a different route to access glusterfs data. Imagine that, libgfapi sits in the application layer. Different bindings are available to access libgfapi.

www.gluster.org/community/documentation/index.php/Language_Bindings

In this article, I will introduce the python bindings of libgfapi.

The libgfapi python binding is available on GitHub, with a mirror on the Gluster Forge:

github.com/gluster/libgfapi-python

1) First of all, clone the git repo:

    $ git clone github.com/gluster/libgfapi-python.git
    $ cd libgfapi-python
    

2) Then run the setup script:

    $ sudo python setup.py install
    

Once its done, you are almost done with the dev environment :)

Now its really easy to use the functions provided by libgfapi. Let me mention some of the gluster functions available through the python bindings:


glfs_discard(self.fd, offset, len)
glfs_dup(self.fd)
glfs_fallocate(self.fd, mode, offset, len)
glfs_fchown(self.fd, uid, gid)
glfs_fdatasync(self.fd)
glfs_fstat(self.fd, ctypes.byref(s))
glfs_fsync(self.fd)
glfs_read(self.fd, rbuf, buflen, flags)
glfs_write(self.fd, buf, len(buf))
glfs_closedir(self.fd)
glfs_close(self.fd)
glfs_readdir_r(self.fd, ctypes.byref(entry),
glfs_new(volid)
gfs_set_volfile_server(self.fs, proto, host, port)
glfs_fini(self.fs)
glfs_set_logging(self.fs, path, level)
glfs_chown(self.fs, path, uid, gid)
glfs_getxattr(self.fs, path, key, buf, maxlen)
glfs_listxattr(self.fs, path, buf, 512)
glfs_lstat(self.fs, path, ctypes.byref(s))
glfs_mkdir(self.fs, path, mode)
glfs_creat(self.fs, path, flags, mode)
glfs_open(self.fs, path, flags)
glfs_opendir(self.fs, path)
glfs_removexattr(self.fs, path, key)
glfs_rename(self.fs, opath, npath)
glfs_rmdir(self.fs, path)
glfs_setxattr(self.fs, path, key, value, vlen, 0)
glfs_stat(self.fs, path, ctypes.byref(s))
glfs_statvfs(self.fs, path, ctypes.byref(s))  --------------> [1]
glfs_symlink(self.fs, source, link_name)
glfs_unlink(self.fs, path)

The Libgfapi functions available through the bindings are:

    def close(self):
    def discard(self, offset, len):
    def dup(self):
    def fallocate(self, mode, offset, len):
    def fchown(self, uid, gid):
    def fdatasync(self):
    def fstat(self):
    def fsync(self):
    def lseek(self, pos, how):
    def read(self, buflen, flags=0):
    def write(self, data):
    def next(self):
    def set_logging(self, path, level):
    def mount(self):
    def chown(self, path, uid, gid):
    def exists(self, path):
    def getatime(self, path):
    def getctime(self, path):
    def getmtime(self, path):
    def getsize(self, filename):
    def getxattr(self, path, key, maxlen):
    def isdir(self, path):
    def isfile(self, path):
    def islink(self, path):
    def listdir(self, path):
    def listxattr(self, path):
    def lstat(self, path):
    def makedirs(self, name, mode):
    def mkdir(self, path, mode):
    def open(self, path, flags, mode=0777):
    def opendir(self, path):
    def removexattr(self, path, key):
    def rename(self, opath, npath):
    def rmdir(self, path):
    def rmtree(self, path, ignore_errors=False, onerror=None):
    def setxattr(self, path, key, value, vlen):
    def stat(self, path):
    def statvfs(self, path): -------------------------------->[1]
    def symlink(self, source, link_name):
    def unlink(self, path):
    def walk(self, top, topdown=True, onerror=None, followlinks=False):

[1] The patch (review.gluster.org/#/c/7430/ ) for “statvfs” is not merged as of now , :)

I have a gluster setup where I created a distributed volume called “vol2″ :


Volume Name: vol2
Type: Distribute
Volume ID: d355c575-d345-4e54-a7f1-d77b1bfebaf9
Status: Stopped
Number of Bricks: 1
Transport-type: tcp
Bricks:
Brick1: 10.70.43.152:/home/rhs2-1
Options Reconfigured:
server.allow-insecure: on

Lets start accessing this volume using Python. To use the gfapi binding, you need to import gfapi as shown below:

>>> from glusterfs import gfapi

Once it’s done, you access the volume with the mount() method like this:


>>> myVol = gfapi.Volume("10.X.X.152","vol2")
>>> myVol_init = myVol.mount()
>>> myVol_init
0
>>> 

“10.X.X.152″ is my gluster server and “vol2″ is the volume name:

The mount() method basically initialises the connection to the volume.

These are the methods available for the Volume object:

>>> dir(myVol)
['__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_api', 'chown', 'exists', 'fs', 'getsize', 'getxattr', 'isdir', 'isfile', 'islink', 'listdir', 'listxattr', 'lstat', 'makedirs', 'mkdir', 'mount', 'open', 'opendir', 'removexattr', 'rename', 'rmdir', 'rmtree', 'set_logging', 'setxattr', 'stat', 'statvfs', 'symlink', 'unlink', 'walk']
>>> 

Lets create some entries in this volume and check further:


[root@ ~]# mount -t glusterfs XX.XX.humblec.com:/vol2 /hum
[root@ ~]# cd /hum/
[root@ hum]# dd if=/dev/random of=file1 bs=1M count=5
0+5 records in
0+5 records out
54 bytes (54 B) copied, 11.6826 s, 0.0 kB/s
[root@n hum]# 

This created a 5M file called “file1″ inside “vol2″ volume.

To list the files and directories inside the volume, we use the listdir() method:

>>> myVol.listdir("/")
['file1']

Running a “stat” on the file, from the server, shows this information:


[root@ hum]# stat file1
  File: `file1'
  Size: 54        	Blocks: 1          IO Block: 131072 regular file
Device: 1fh/31d	Inode: 9316719741945628140  Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2014-04-09 19:16:10.209995591 +0530
Modify: 2014-04-09 18:05:00.719006150 +0530
Change: 2014-04-09 18:05:00.719006150 +0530
[root@ hum]# 

Lets prove the python binding works :)

>>> myVol.stat("file1").st_ino
9316719741945628140L
>>> myVol.stat("file1").st_size
54L

If I want to list the extended attributes, I can try something like:

>>> myVol.listxattr("/")
['trusted.glusterfs.volume-id']
>>> 

Lets create a directory called “humble”:

>>> myVol.mkdir("humble/", 0775)
0
>>> 

Checking on the server using ls, it should be there:

[root@ hum]# ls
file1  humble
[root@ hum]# 

Success! For fun, some ‘stat’ information can be displayed using these methods:

>>> myVol.statvfs("/").f_bavail
1060674L

>>> myVol.statvfs("/").f_bfree
1133685L
>>> myVol.statvfs("/").f_files
365760L
>>> 

If you want to mount a gluster volume as a non-root user, you need to follow the steps below.
By default, gluster allows client connections only from privileged ports. To enable connections from unprivileged ports you have to follow below steps.

1. Turn on the allow-insecure option for the volume:

       gluster volume set <volume_name> allow-insecure on

2. Edit /etc/glusterfs/glusterd.vol, adding the line:

       option rpc-auth-allow-insecure on

3. Obviously you should have the permissions on the directory you are accessing for non-root access

4. Start and stop volume

C Implementation of Red Black Tree

#include <stdio.h>

#include <stdlib.h>

#include<mpi.h>

struct rbtNode

{          int key;

char color;

struct rbtNode *left, *right,*parent;

};         struct rbtNode* root = NULL;

void leftRotate(struct rbtNode *x)

{          struct rbtNode *y;

y = x->right;  x->right = y->left;

if( y->left != NULL)

{          y->left->parent = x;

}

y->parent = x->parent;

if( x->parent == NULL)

{          root = y;

}

else if( (x->parent->left!=NULL) && (x->key == x->parent->left->key))

{          x->parent->left = y;

}

else x->parent->right = y;

y->left = x; x->parent = y; return;

}

void rightRotate(struct rbtNode *y)

{          struct rbtNode *x;

x = y->left; y->left = x->right;

if ( x->right != NULL)

{          x->right->parent = y;

}

x->parent = y->parent;

if( y->parent == NULL)

{          root = x;

}

else if((y->parent->left!=NULL)&& (y->key == y->parent->left->key))

{          y->parent->left = x;

}

else

y->parent->right = x;

x->right = y; y->parent = x;

return;

}

void color-insert(struct rbtNode *z)

{          struct rbtNode *y=NULL;

while ((z->parent != NULL) && (z->parent->color == 'r'))

{

if ( (z->parent->parent->left != NULL) && (z->parent->key == z->parent->parent->left->key))

{          if(z->parent->parent->right!=NULL)

y = z->parent->parent->right;

if ((y!=NULL) && (y->color == 'r'))

{          z->parent->color = 'b';

y->color = 'b';

z->parent->parent->color = 'r';

if(z->parent->parent!=NULL)

z = z->parent->parent;

}

else

{

if ((z->parent->right != NULL) && (z->key == z->parent->right->key))

{          z = z->parent;

leftRotate(z);

}

z->parent->color = 'b';

z->parent->parent->color = 'r';

rightRotate(z->parent->parent);

}

}

else

{

if(z->parent->parent->left!=NULL)

y = z->parent->parent->left;

if ((y!=NULL) && (y->color == 'r'))

{          z->parent->color = 'b';

y->color = 'b';

z->parent->parent->color = 'r';

if(z->parent->parent!=NULL)

z = z->parent->parent;

}

else

{

if ((z->parent->left != NULL) && (z->key == z->parent->left->key))

{          z = z->parent;

rightRotate(z);

}

z->parent->color = 'b';

z->parent->parent->color = 'r';

leftRotate(z->parent->parent);

}

}

}          root->color = 'b';

}

void insert(int val)

{          struct rbtNode *x, *y;

struct rbtNode *z = (struct rbtNode*)malloc(sizeof(struct rbtNode));

z->key = val;

z->left = NULL;

z->right = NULL;

z->color = 'r';

x=root;

if(search(val)==1)

{          printf("\nEntered element already exists in the tree\n");

return;

}

if ( root == NULL )

{          root = z;

root->color = 'b';

return;

}

while ( x != NULL)

{          y = x;

if ( z->key < x->key)

{          x = x->left;

}

else x = x->right;

}

z->parent = y;

if ( y == NULL)

{          root = z;

}

else if( z->key < y->key )

{          y->left = z;

}

else y->right = z;

color-insert(z);

return;

}

void inorderTree(struct rbtNode* root)

{          struct rbtNode* temp = root;

if (temp != NULL)

{          inorderTree(temp->left);

printf(" %d--%c ",temp->key,temp->color);

inorderTree(temp->right);

}return;

}

void postorderTree(struct rbtNode* root)

{          struct rbtNode* temp = root;

if (temp != NULL)

{          postorderTree(temp->left);

postorderTree(temp->right);

printf(" %d--%c ",temp->key,temp->color);

}return;

}

void traversal(struct rbtNode* root)

{          if (root != NULL)

{          printf("root is %d-- %c",root->key,root->color);

printf("\nInorder tree traversal\n");

inorderTree(root);

printf("\npostorder tree traversal\n");

postorderTree(root);

}return;

}

int search(int val)

{          struct rbtNode* temp = root;

int diff;

while (temp != NULL)

{          diff = val - temp->key;

if (diff > 0)

{          temp = temp->right;

}

else if (diff < 0)

{          temp = temp->left;

}

else

{          printf("Search Element Found!!\n");

return 1;

}

}          printf("Given Data Not Found in RB Tree!!\n");

return 0;

}

struct rbtNode* min(struct rbtNode *x)

{          while (x->left)

{          x = x->left;

} return x;

}

struct rbtNode* successor(struct rbtNode *x)

{          struct rbtNode *y;

if (x->right)

{          return min(x->right);

}          y = x->parent;

while (y && x == y->right)

{          x = y;

y = y->parent;

}return y;

}

void color-delete(struct rbtNode *x)

{          while (x != root && x->color == 'b')

{          struct rbtNode *w = NULL;

if ((x->parent->left!=NULL) && (x == x->parent->left))

{          w = x->parent->right;

if ((w!=NULL) && (w->color == 'r'))

{          w->color = 'b';

x->parent->color = 'r';

leftRotate(x->parent);

w = x->parent->right;

}

if ((w!=NULL) && (w->right!=NULL) && (w->left!=NULL) && (w->left->color == 'b') && (w->right->color == 'b'))

{

w->color = 'r';

x = x->parent;

}

else if((w!=NULL) && (w->right->color == 'b'))

{          w->left->color = 'b';

w->color = 'r';

rightRotate(w);

w = x->parent->right;

}

if(w!=NULL)

{          w->color = x->parent->color;

x->parent->color = 'b';

w->right->color = 'b';

leftRotate(x->parent);

x = root;

}

}

else if(x->parent!=NULL)

{          w = x->parent->left;

if ((w!=NULL) && (w->color == 'r'))

{

w->color = 'b';

x->parent->color = 'r';

leftRotate(x->parent);

if(x->parent!=NULL)

w = x->parent->left;

}

if ((w!=NULL) && (w->right!=NULL) && (w->left!=NULL) && (w->right->color == 'b') && (w->left->color == 'b'))

{

x = x->parent;

}

else if((w!=NULL) && (w->right!=NULL) && (w->left!=NULL) && (w->left-       >color == 'b'))

{

w->right->color = 'b';

w->color = 'r';

rightRotate(w);

w = x->parent->left;

}

if(x->parent!=NULL)

{          w->color = x->parent->color;

x->parent->color = 'b';

}

if(w->left!=NULL)

w->left->color = 'b';

if(x->parent !=NULL)

leftRotate(x->parent);

x = root;

}

} x->color = 'b';

}

struct rbtNode* delete(int var)

{          struct rbtNode *x = NULL, *y = NULL, *z;

z=root;

if((z->left ==NULL ) &&(z->right==NULL) && (z->key==var))

{          root=NULL;

printf("\nRBTREE is empty\n");

return;

}

while(z->key !=var && z!=NULL)

{          if(var<z->key)

z=z->left;

else

z=z->right;

if(z== NULL)

return;

}

if((z->left==NULL)||(z->right==NULL))

{          y = z;

}

else

{          y = successor(z);

}

if (y->left!=NULL)

{          x = y->left;

}

else

{          if(y->right !=NULL)

x = y->right;

}

if((x!=NULL) && (y->parent !=NULL))

x->parent = y->parent;

if ((y !=NULL) && (x!=NULL) && (y->parent==NULL))

{          root=x;

}

else if (y == y->parent->left)

{          y->parent->left = x;

}

else

{          y->parent->right = x;

}

if (y != z)

{          z->key = y->key;

}

if ((y!=NULL) && (x!=NULL) && (y->color == 'b'))

{          color-delete(x);

}return y;

}

int main(int argc, char* argv[])

{

int choice,val,data,var,fl=0;

while(1)

{          printf("\nRed Black Tree Management - Enter your choice :1:Insert  2:Delete  3:Search  4:Traversal  5:Exit\n");

scanf("%d",&choice);

switch(choice)

{          case 1:printf("Enter the integer you want to add : ");

scanf("%d",&val);

insert(val);break;

case 2:printf("Enter the integer you want to delete : ");

scanf("%d",&var);

delete(var);break;

case 3:printf("Enter search element \n");

scanf("%d",&val);

search(val);break;

case 4:traversal(root);break;

case 5:fl=1;break;

default:printf("\nInvalid Choice\n");

}

if(fl==1)

{          break;}

}return 0;

}

Sample Output

kdt1

kdt2

C Implementation of K-dimensional Tree


#include <stdio.h>

struct node

{          int data1,data2,level;

struct node *right,*left;

}*root,*temp;

void inorder(struct node *p)

{          if(p!=NULL)

{          inorder(p->left);

printf("\t%d:%d   ",p->data1,p->data2);

inorder(p->right);

}

}

void postorder(struct node *p)

{          if(p!=NULL)

{          postorder(p->left);

postorder(p->right);

printf("\t%d:%d   ",p->data1,p->data2);

}

}

void insert(int d1,int d2)

{          int for;

struct node *temp,*prev,*z;

z=(struct node *)malloc(sizeof(struct node));

z->right=NULL;

z->left=NULL;

z->level=0;

z->data1=d1;

z->data2=d2;

if(root==NULL)

{          root=z;

return;

}temp=root;

while(temp!=NULL)

{          prev=temp;

f=0;

if(temp->level==0)

{          if(temp->data1>z->data1)

{          temp=temp->left; f=1;

}

else temp=temp->right;

}

else

{          if(temp->data2>z->data2)

{          temp=temp->left; f=1;

}

else temp=temp->right;

}

}

z->level=(1-prev->level);

if(f)      prev->left=z;

else      prev->right=z;

}

void search(struct node *treePtr, int s1,int s2,int flip)

{          if(treePtr !=NULL)

{int x1,y1;

x1=treePtr->data1;

y1=treePtr->data2;

if(x1==s1 && y1==s2)

{          printf("\nElement %d:%d is found ",s1,s2);

}

else

{          if(flip==0)

{          if(s1 < x1)

{          search((treePtr->left),s1,s2,0);

}

else

{          search((treePtr->right),s1,s2,0);

}

}if(flip==1)

{          if(s2 < y1)

{          search((treePtr->left),s1,s2,1);

}

else

{          search((treePtr->right),s1,s2,1);

}

}

}

} if(treePtr==NULL)

printf("\nnot found %d::%d  \n",s1,s2);

}

struct node* min(struct node* treePtr, int dim, int cd)

{          struct node *a,*b;

int c1,c2;

if (treePtr == NULL)

return NULL;

if (treePtr!=NULL && cd == dim)

{          if (treePtr->left == NULL)

return treePtr->data1;

else

return min(treePtr->left, dim, (cd+1)%2);

}

else

{          a=min(treePtr->left, dim, (cd+1)%2);

b=min(treePtr->right, dim, (cd+1)%2);

c1=treePtr->data1;

if(a!=NULL)

{          if(b!=NULL)

{          if(a->data1<b->data1 && a->data1<c1)

return a;

}

else if(a->data1<c1)

return a;

}

if(b!=NULL)

{          if(a!=NULL)

{          if(b->data1<a->data1 && b->data1<c1)

return b;

}

else if(b->data1<c1)

return b;

}          return treePtr;

}

}

struct node* delete(struct node *z,int d3,int d4,int cd)

{          struct node *x = NULL, *y = NULL,*prev=NULL;

int lg=0,next_cd = (cd+1)%2,flag=0;

if((z->data1==d3) && (z->data2==d4))

{          if((z==root) && (z->left ==NULL ) &&(z->right==NULL) )

{          root=NULL;

printf("\nKDTREE is empty\n");

return;

}

if (z->right != NULL)

{          y=min(z->right, cd, next_cd);

z->data1 =y->data1;

z->data2=y->data2;

if(z->right!=NULL)

z->right = delete(z->right, z->right->data1,z->right->data2, next_cd);

}

else if (z->left != NULL)

{          x=min(z->left, cd, next_cd);

z->data1 =x->data1;

z->data2=x->data2;

if(z->right!=NULL)

z->right = delete(z->right, z->left->data1,z->left->data2, next_cd);

z->left=NULL;

}else z=NULL;

}

else

{          while(z!=NULL)

{          if(d3==z->data1 && d4==z->data2)

{          if(z==prev->left)

prev->left=delete(z,d3,d4,next_cd);

else if(z==prev->right)

prev->right=delete(z,d3,d4,next_cd);

break;

}

else if(z->level==0)

{          if(d3<z->data1)

{          prev=z; z=z->left;

}

else if(d3>z->data1)

{          prev=z; z=z->right;

}

}

else if(z->level==1)

{          if(d4<z->data2)

{          prev=z; z=z->left;

}

else if(d4>z->data2)

{          prev=z; z=z->right;

}

}

}

}return z;

}

int main(int argc,char *argv[])

{

int fl=0,n,d1,d2,d3,d4,s1,s2,flip,val,flip1;

struct node *minvalue;

printf("KDTree Management");

while(1)

{          printf("\nEnter ur option \t1.Insert\t2.Delete\t3.Search\t4.Traversal\t5.Exit\n");

scanf("%d",&val);

switch(val)

{case 1:printf("Enter the elements:");

scanf("%d",&d1);

scanf("%d",&d2);

insert(d1,d2);break;

case 2:printf("\nEnter the node you want to delete : ");

scanf("%d",&d3);

scanf("%d",&d4);

printf("Enter the splitting axis of the node x-axis:-0 y-axis:-1 : ");

scanf("%d",&flip1);

delete(root,d3,d4,flip1);

printf("\nDeleted element is %d:%d",d3,d4);break;

case 3:printf("\nEnter the node you want to search : ");

scanf("%d",&s1);

scanf("%d",&s2);

printf("Enter the splitting axis of the node x-axis:-0 y-axis:-1 : ");

scanf("%d",&flip);

search(root,s1,s2,flip);break;

case 4:printf("Root is %d::%d",root->data1,root->data2);

printf("\nInorder traversal \n");

inorder(root);

printf("\nPostorder traversal \n");

postorder(root);

break;

case 5:fl=1;break;

default:break;

}

if(fl==1)

{          break;              }

}

}




Sample Output
Sample Output

kdt1

kdt2

C Implementation of LEFTIST Tree

C Implementation of LEFTIST Tree


#include <stdio.h>



struct node

{          int data,dist;

struct node *right,*left;

}*root,*temp,*r1,*r2;

void inorder(struct node *p)

{          if(p!=NULL)

{          inorder(p->left);

printf("\t%d",p->data);

inorder(p->right);

}

}

void postorder(struct node *p)

{          if(p!=NULL)

{          postorder(p->left);

postorder(p->right);

printf("\t%d",p->data);

}

}

int depth(struct node *p)

{          if(p==NULL)

{          return(-1);

}else

{          return(p->dist);

}

}

struct node * meld(struct node *h,struct node *k)

{

if(h==NULL)

return k;

if(k==NULL)

return h;

if(k->data>h->data)

{          temp=k;  k=h; h=temp;

}

h->right=meld(h->right,k);

if(depth(h->right)>depth(h->left))

{          temp=h->right;

h->right=h->left;

h->left=temp;

}

if(h->right==NULL)

h->dist=0;

else

h->dist=1+(h->right->dist);

return(h);

}

struct node * deletion(struct node * root)

{          if(root !=NULL)

{          printf("Deleted element is %d\n",root->data);

root=meld(root->right,root->left);

}return root;

}

struct node * insert(struct node *newroot)

{          int val;

struct node *z,*x;

z=(struct node *)malloc(sizeof(struct node));

z->right=NULL;

z->left=NULL;

z->dist=0;

printf("Enter the value of the node to be added: ");

scanf("%d",&val);

z->data=val;

newroot =meld(newroot,z);

printf("Root element is %d\t distance value is %d",newroot->data,newroot->dist+1);

return(newroot);

}

void tree merge()

{          int val;

r1=(struct node *)malloc(sizeof(struct node));

r1->right=NULL;

r1->left=NULL;

r1->dist=0;

printf("*****First tree***********");

printf("\nEnter the root node");

scanf("%d",&val);

r1->data=val;

while(1)

{          printf("\nIf you want to insert element to first tree enter 1 else 0");

scanf("%d",&val);

if(val)

{          r1=insertion(r1);

}

else

break;

}

r2=(struct node *)malloc(sizeof(struct node));

r2->right=NULL;

r2->left=NULL;

r2->dist=0;

printf("*****Second tree***********");

printf("\nEnter the root node");

scanf("%d",&val);

r2->data=val;

while(1)

{

printf("\nIf you want to insert element to second tree enter 1 else 0");

 

scanf("%d",&val);

if(val)

{          r2=insert(r2);

}

else

break;

}

printf("\nFirst tree");

inorder(r1);

printf("\nSecond tree");

inorder(r2);

r1=treemerge(r1,r2);

printf("\nRoot element is: %d\n",r1->data);

inorder(r1);

}

int main(int argc,char **argv) {

int bkpoint=0,value,val1;

printf("\n****Lefist Max Heap Management****");

printf("\nEnter root node\n");

scanf("%d",&value);

root=(struct node *)malloc(sizeof(struct node));

root->right=NULL;

root->left=NULL;

root->dist=0;

root->data=value;

while(1){
        printf("\nEnter ur option 1.insert\t2.Delete\t3.Traversal\t4.Meld\t5.exit\n");

scanf("%d",&val);

switch(val) {

case 1:root=insertion(root);break;

case 2:root=deletion(root);break;

case 3:printf("Inorder traversal \n");inorder(root);

printf("\nPostorder traversal \n");postorder(root);

break;

case 4:treemerge();break;

case 5:bkpoint=1;break;

default:break;

}

if(bkpoint==1) {

         break;

}


}
}

Sample Output

left1

let2

left3

Virtualization – Time Break – Glusterfs !

hmmm.. Its been long time I am writing articles in my space.. More than 50% were virtualization oriented ..

Right now I am taking a break here and planning to come back with more Filesystem articles , obviously it will be centred on “glusterfs” where I am going to put my finger on. How-ever at any stage I cant forget virtualization, so definitely it will be flashed at times…

Configure/install Swift and Gluster-Swift on a RHEL/CentOS system

Here is step by step guide which helps you to configure/install Swift and Gluster-Swift on a RHEL system.

 

Install EPEL repo:

wget download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6-8.noarch.rpm

Install Openstack Repo:

cd /etc/yum.repos.d
wget repos.fedorapeople.org/repos/openstack/openstack-trunk/el6-openstack-trunk.repo

Install glusterfs Repo:

cd /etc/yum.repos.d
wget download.gluster.org/pub/gluster/glusterfs/LATEST/RHEL/glusterfs-epel.repo

Check if EPEL, glusterfs, and Openstack repos have been installed correctly:

yum repolist

repo id               repo name                                                         status
el6-openstack-trunk   Openstack Upstream Repository for EL6                              6,501
epel                  Extra Packages for Enterprise Linux 6 - x86_64                     9,806
glusterfs-epel        GlusterFS is a clustered file-system capable of scaling to severa     11
glusterfs-noarch-epel GlusterFS is a clustered file-system capable of scaling to severa      1
openstack-havana      OpenStack Havana Repository for EPEL 6                               357
rhel-x86_64-server-6  Red Hat Enterprise Linux Server (v. 6 for 64-bit x86_64)          11,029
repolist: 27,705

Install Openstack Swift

yum --enablerepo=openstack-havana install openstack-swift openstack-swift-account openstack-swift-proxy openstack-swift-container openstack-swift-object

Install gluster-swift from latest builds here: build.gluster.org/ As of now, RHEL6 RPMs are available only for grizzly version. We can just go ahead and use fedora builds for now. Alternatively, you can get the gluster-swift source code and run makerpm.sh in RHEL box.

yum install rpm-build git-core
git clone github.com/gluster/gluster-swift
cd gluster-swift
git checkout master
chmod +x ./makerpm.sh
./makerpm.sh
rpm -ivh --nodeps ./build/glusterfs-openstack-swift-1.9.1-0.el6.noarch.rpm

The –nodeps option is mentioned as gluster-swift has hardcoded dependency on swift 1.9.1 Installing glusterfs

yum --enablerepo=glusterfs-epel install glusterfs glusterfs-server glusterfs-cli

To perform the following tasks:

Create volumes and start Copy and rename conf files in /etc/swift Generate ring files

Follow the Quick Start Guide here : github.com/gluster/gluster-swift/blob/master/doc/markdown/quick_start_guide.md

Troubleshooting If you have python-jinja2 as missing dependency, you can install python-jinja2 from here: rpm.pbone.net/index.php3/stat/4/idpl/18007532/dir/redhat_el_6/com/python-jinja2-2.2.1-1.el6.rf.x86_64.rpm.html

yum install ftp.univie.ac.at/systems/linux/dag/redhat/el6/en/x86_64/dag/RPMS/python-jinja2-2.2.1-1.el6.rf.x86_64.rpm If you are unable to find mkfs.xfs command, you'll have to install xfsprogs package from here: rpmfind.net/linux/rpm2html/search.php?query=xfsprogs If the logs in /var/log/httpd contain [Errno 111] ECONNREFUSED,

you need to set selinux to permissive or disabled by editing /ets/sysconfig/selinux and verify by running: getenforce

virt-manager is not able to detect the ISO file ?

[ ping blog]

Any way its a common complaint that, the virt-manager is not able to scan or show the iso files stored in a system … Even after making sure the permissions and other bits correct , virt-manager is not able to populate it..

First of all I would like to ask where is that ISO stored ?

if its ** NOT ** in below path, can u move the subject ISO file to this location and see it helps ?

/var/lib/libvirt/images

Once you move the ISO file to above location normally issue should go away.. If yes/no please let me know ..

We can poke more… Hope this helps..

How to list qemu device options using command line in KVM environment..

[Back to blogging after busy season of ....]

Any way, its a very common query on qemu/kvm and most of the people dont know .. It is really useful to know which options are available with some of the devices and qemu-kvm binary…

Here is an example on the same: You have to replace your qemu binary path accordingly

First of all if you want to list the devices available for the qemu binary, please list it using :


[root@node ~]# /usr/bin/qemu-kvm -device ?
name "pci-bridge", bus PCI
name "virtio-scsi-pci", bus PCI, alias "virtio-scsi"
name "virtio-balloon-pci", bus PCI
name "virtio-serial-pci", bus PCI, alias "virtio-serial"
name "virtio-net-pci", bus PCI
name "virtio-blk-pci", bus PCI, alias "virtio-blk"
name "i82562", bus PCI

*****

If you want to list specific options of a particular device, view it by invoking in similar way as below.. Here I used “virtio-net-pci” as an example..

[root@node ~]# /usr/bin/qemu-kvm -device virtio-net-pci,? 

virtio-net-pci.ioeventfd=on/off
virtio-net-pci.__com_redhat_macvtap_compat=on/off
virtio-net-pci.x-__com_redhat_rhel620_compat=on/off
virtio-net-pci.vectors=uint32
virtio-net-pci.indirect_desc=on/off
virtio-net-pci.event_idx=on/off
virtio-net-pci.csum=on/off
virtio-net-pci.guest_csum=on/off
virtio-net-pci.gso=on/off
virtio-net-pci.guest_tso4=on/off
virtio-net-pci.guest_tso6=on/off
virtio-net-pci.guest_ecn=on/off
virtio-net-pci.guest_ufo=on/off
virtio-net-pci.host_tso4=on/off
virtio-net-pci.host_tso6=on/off
virtio-net-pci.host_ecn=on/off
virtio-net-pci.host_ufo=on/off
virtio-net-pci.mrg_rxbuf=on/off
virtio-net-pci.status=on/off
virtio-net-pci.ctrl_vq=on/off
virtio-net-pci.ctrl_rx=on/off
virtio-net-pci.ctrl_vlan=on/off
virtio-net-pci.ctrl_rx_extra=on/off
virtio-net-pci.ctrl_guest_offloads=on/off
virtio-net-pci.ctrl_mac_addr=on/off
virtio-net-pci.mac=macaddr
virtio-net-pci.vlan=vlan
virtio-net-pci.netdev=netdev
virtio-net-pci.bootindex=int32
virtio-net-pci.x-txtimer=uint32
virtio-net-pci.x-txburst=int32
virtio-net-pci.tx=string
virtio-net-pci.addr=pci-devfn
virtio-net-pci.romfile=string
virtio-net-pci.rombar=uint32
virtio-net-pci.multifunction=on/off

The same way you can list available CPUs and Machine types

-M ?
-cpu ?

For ex:

[root@node ~]# /usr/bin/qemu-kvm -cpu ?
x86       Opteron_G5  AMD Opteron 63xx class CPU                      
x86       Opteron_G4  AMD Opteron 62xx class CPU                      
x86       Opteron_G3  AMD Opteron 23xx (Gen 3 Class Opteron)          
x86       Opteron_G2  AMD Opteron 22xx (Gen 2 Class Opt

sys-unconfig command to reconfigure your system from next boot..

sys-unconfig is a shell script to reconfigure the system upon next boot .. The man page description is more than enough to know what parameters are reconfigured from next boot..

sys-unconfig provides a simple method of reconfiguring a system in a new environment. Upon executing sys-unconfig will halt your system,
and run the following configuration programs at boot: passwd (to change the root password), netconfig, timeconfig, kbdconfig, authconfig,
and ntsysv.

A file ( hidden) called “unconfigured” will be present inside “/” when you run sys-unconfig command . The presence of this file will cause /etc/rc.d/rc.sysinit to run the programs mentioned above.

Please note that, running “sys-unconfig” command will cause the system to go down immediately..

Also, all persistent rules will be deleted from /etc/udev/rules.d/.

Understanding Qcow2 image , its header and verifying corruption..

qcow2 is one of the best image formats available for virtual machines running on top of KVM .. Its known as qemu image format version 2. Use it to have smaller images (useful if your filesystem does not supports holes, for example on Windows), optional AES encryption, zlib based compression and support of multiple VM snapshots.

Supported options:

            "compat"
               Determines the qcow2 version to use. "compat=0.10" uses the traditional image format that can be read by any QEMU since 0.10 (this
               is the default).  "compat=1.1" enables image format extensions that only QEMU 1.1 and newer understand. Amongst others, this
               includes zero clusters, which allow efficient copy-on-read for sparse images.

           "backing_file"
               File name of a base image (see create subcommand)

           "backing_fmt"
               Image format of the base image

           "encryption"
               If this option is set to "on", the image is encrypted.

               Encryption uses the AES format which is very secure (128 bit keys). Use a long password (16 characters) to get maximum protection.

           "cluster_size"
               Changes the qcow2 cluster size (must be between 512 and 2M). Smaller cluster sizes can improve the image file size whereas larger
               cluster sizes generally provide better performance.
           "preallocation"
               Preallocation mode (allowed values: off, metadata). An image with preallocated metadata is initially larger but can improve
               performance when the image needs to grow.

           "lazy_refcounts"
               If this option is set to "on", reference count updates are postponed with the goal of avoiding metadata I/O and improving
               performance. This is particularly interesting with cache=writethrough which doesn't batch metadata updates. The tradeoff is that
               after a host crash, the reference count tables must be rebuilt, i.e. on the next open an (automatic) "qemu-img check -r all" is
               required, which may take some time.

               This option can only be enabled if "compat=1.1" is specified.

Qcow2 header is composed by below byte allocation..

Byte 0 – 3: magic
QCOW magic string (“QFI\xfb”)

4 – 7: version
Version number (valid values are 2 and 3)

8 – 15: backing_file_offset
Offset into the image file at which the backing file name
is stored (NB: The string is not null terminated). 0 if the
image doesn’t have a backing file.

16 – 19: backing_file_size
Length of the backing file name in bytes. Must not be
longer than 1023 bytes. Undefined if the image doesn’t have
a backing file.

20 – 23: cluster_bits
Number of bits that are used for addressing an offset
within a cluster (1 << cluster_bits is the cluster size).
Must not be less than 9 (i.e. 512 byte clusters).

Note: qemu as of today has an implementation limit of 2 MB
as the maximum cluster size and won't be able to open images
with larger cluster sizes.

24 - 31: size
Virtual disk size in bytes

32 - 35: crypt_method
0 for no encryption
1 for AES encryption

36 - 39: l1_size
Number of entries in the active L1 table

40 - 47: l1_table_offset
Offset into the image file at which the active L1 table
starts. Must be aligned to a cluster boundary.

48 - 55: refcount_table_offset
Offset into the image file at which the refcount table
starts. Must be aligned to a cluster boundary.

56 - 59: refcount_table_clusters
Number of clusters that the refcount table occupies

60 - 63: nb_snapshots
Number of snapshots contained in the image

64 - 71: snapshots_offset
Offset into the image file at which the snapshot table
starts. Must be aligned to a cluster boundary.

Now lets verify a qcow image header by following above byte allocation.

I have an image whose first 1 MB look like :

[humble@localhost source-gits]$ hexdump -C -n $((1024 * 1024)) myimg.qcow
00000000  51 46 49 fb 00 00 00 02  00 00 00 00 00 00 00 00  |QFI………….|
00000010  00 00 00 00 00 00 00 10  00 00 00 00 3e 80 00 00  |…………>…|
00000020  00 00 00 00 00 00 00 02  00 00 00 00 00 01 00 00  |…………….|
00000030  00 00 00 00 00 02 00 00  00 00 00 01 00 00 00 00  |…………….|
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |…………….|
*
00020000  00 00 00 00 00 03 00 00  00 00 00 00 00 00 00 00  |…………….|
00020010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |…………….|
*
00030000  00 01 00 01 00 01 00 01  00 00 00 00 00 00 00 00  |…………….|
00030010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |…………….|
*
00040000
[humble@localhost source-gits]$

Lets start verifying the image integrity ( well atleast its header) by manually unwinding above data in hexadecimal notation...

The first 4 bytes represents its magic string.. so starting from offset 0x00000000 we can see its "51 46 49 fb" which is equivalanto to "QFI" . luckily atleast these bytes are not corrupted..

lets see next 4 bytes.. 00 00 00 02 , Isnt it saying its version is "2" ?? yes..

Now, lets see what is the size of this image : Bytes from 24-31 tells us the size of the image..

3e 80 00 00 00 00 00 00 which is equivalent to
00111110100000000000000000000000 in binary or 1048576000 in decimal.. 1048576000 == 1 GB ? yes, it is..

Lets see whether this image has any snapshots ? 60-63 says it all..
00 00 00 00 -> so, NO SNAPSHOTS!

If you extract above hexadecimal values you would end up in :

magic                     0x514649fb
version                   2
backing_file_offset       0x0
backing_file_size         0x0
cluster_bits              16
size                      1048576000
crypt_method              0
l1_size                   2
l1_table_offset           0x10000
refcount_table_offset     0x20000
refcount_table_clusters   1
nb_snapshots              0
snapshot_offset           0x0
incompatible_features     0x0
compatible_features       0x0
autoclear_features        0x0
refcount_order            4
header_length             72

Hmmmm.. looks like there is no corruption reported at least in this header.. well, is there any binary available for checking integrity of the image itself ? Yes, 'qemu-img' check can be used for the same purpose..

lot many operations can be performed against qcow2 image using this binary..

To get some information about this image we can try:

[humble@localhost source-gits]$ qemu-img info myimg.qcow 
image: myimg.qcow
file format: qcow2
virtual size: 1.0G (1048576000 bytes)
disk size: 256K
cluster_size: 65536
[humble@localhost source-gits]$ 

Also its possible to check the integrity of the image by :


[humble@localhost source-gits]$ qemu-img check myimg.qcow 
No errors were found on the image
[humble@localhost source-gits]$ 

Hope this helps!!