<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML ><HEAD ><TITLE >My processes won't migrate</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" TITLE="The openMosix HOWTO" HREF="index.html"><LINK REL="UP" TITLE="Common Problems" HREF="problems.html"><LINK REL="PREVIOUS" TITLE="Introduction" HREF="x1243.html"><LINK REL="NEXT" TITLE="I don't see all my nodes" HREF="x1271.html"></HEAD ><BODY CLASS="SECT1" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >The openMosix HOWTO: </TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="x1243.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" >Chapter 12. Common Problems</TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="x1271.html" ACCESSKEY="N" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="AEN1247" ></A >12.2. My processes won't migrate</H1 ><P ><EM >Help process XYZ doesn't migrate. </EM > Moshe Bar explains below why some processes migrate and why some don't. But before that you can always look in /proc/$pid/, there often is a <EM >cantmove</EM > file which will tell you why a certain process can't migrate.</P ><P >Processes can also be locked. You can check if a process is locked with: <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" >cat /proc/$PID/lock</PRE ></FONT ></TD ></TR ></TABLE > where $PID is the processid of the process in question. </P ><P >Now listen to what Moshe himself has to say about this topic. </P ><P >Often people have the same kernel but on a different distribution, say a mixed environment of RedHat and Debian ,rc scripts from different distros tend to start openmosix differently. Some implementations completely modify /etc/inittab to start all daemons (and their children) with <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" >mosrun -h</PRE ></FONT ></TD ></TR ></TABLE >. So that they won't migrate. Therefore all these processes have a 1 in /proc/pid/lock when you start. You can force them to migrate by writing a 0 to this file .</P ><P > Ok, this simple program should always migrate if launched more times than number of local CPUs. So for a 2-way SMP system, starting this program 3 times will start migration if the other nodes in the cluster have at least the same speed like the local ones: <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" >int main() { unsigned int i; while (1) { i++; } return 0; }</PRE ></FONT ></TD ></TR ></TABLE > On a Pentium 800Mhz CPU it takes quite a while to overflow. </P ><P > This sample program with content like this will never migrate: <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" >#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> ... key_t key; /* key to be passed to shmget() */ int shmflg; /* shmflg to be passed to shmget() */ int shmid; /* return value from shmget() */ int size; /* size to be passed to shmget() */ ... key = ... size = ... shmflg) = ... if ((shmid = shmget (key, size, shmflg)) == -1) { perror("shmget: shmget failed"); exit(1); } else { (void) fprintf(stderr, "shmget: shmget returned %d\n", shmid); exit(0); } ...</PRE ></FONT ></TD ></TR ></TABLE > </P ><P > Program using pipes like this do migrate nicely: <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" > int pdes[2]; pipe(pdes); if ( fork() == 0 ) { /* child */ close(pdes[1]); /* not required */ read( pdes[0]); /* read from parent */ ..... } else { close(pdes[0]); /* not required */ write( pdes[1]); /* write to child */ ..... }</PRE ></FONT ></TD ></TR ></TABLE > <EM >MODIFIED</EM > Programs using pthreads since version 2.4.17 don't migrate, however they don't segfault anymore. <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" >// // Very simple program demonstrating the use of threads. // // Command-line argument is P (number of threads). // // Each thread writes "hello" message to standard output, with // no attempt to synchronize. Output will likely be garbled. // #include <iostream> #include <cstdlib> // has exit(), etc. #include <unistd.h> // has usleep() #include <pthread.h> // has pthread_ routines // declaration for function to be executed by each thread void * printHello(void * threadArg); // ---- Main program ------------------------------------------------- int main(int argc, char* argv[]) { if (argc < 2) { cerr << "Usage: " << argv[0] << " numThreads\n"; exit(EXIT_FAILURE); } int P = atoi(argv[1]); // Set up IDs for threads (need a separate variable for each // since they're shared among threads). int * threadIDs = new int[P]; for (int i = 0; i < P; ++i) threadIDs[i] = i; // Start P new threads, each with different ID. pthread_t * threads = new pthread_t[P]; for (int i = 0; i < P; ++i) pthread_create(&threads[i], NULL, printHello, (void *) &threadIDs[i]); // Wait for all threads to complete. for (int i = 0; i < P; ++i) pthread_join(threads[i], NULL); // Clean up and exit. delete [] threadIDs; delete [] threads; cout << "That's all, folks!\n"; return EXIT_SUCCESS; } // ---- Code to be executed by each thread --------------------------- // pre: *threadArg is an integer "thread ID". // post: "hello" message printed to standard output. // return value is null pointer. void * printHello(void * threadArg) { int * myID = (int *) threadArg; cout << "hello, world, "; // pointless pause, included to make the effects of // synchronization (or lack thereof) more obvious usleep(10); cout << "from thread " << *myID << endl; pthread_exit((void* ) NULL); } </PRE ></FONT ></TD ></TR ></TABLE > Programs using all kinds of file descriptors, including sockets do migrate (sockets are not migrated with the process however, files are migrated if using oMFS/DFSA)</P ><P > (all above code is by Moshe as Moshe Bar or by Moshe as CTO of Qlusters, Inc.) </P ><P >Please also refer to the man pages of openMosix , they also give an adequate explanation why processes don't migrate. </P ><P >If for some reason your processes stay locked while they shouldn't. You can try to allow locked processes to migrate by simply putting <TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="100%" ><TR ><TD ><FONT COLOR="#000000" ><PRE CLASS="PROGRAMLISTING" ># tell shells to allow subprocs to migrate to other nodes echo 0 > /proc/self/lock</PRE ></FONT ></TD ></TR ></TABLE > into <SPAN CLASS="QUOTE" >"/etc/profile"</SPAN > Warning : this fix will allow <EM >all</EM > process to migrate not just the ones you want. To only allow specific process to migrate use 'mosrun -l' to unlock only the desired process. </P ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="x1243.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="index.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="x1271.html" ACCESSKEY="N" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Introduction</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="problems.html" ACCESSKEY="U" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >I don't see all my nodes</TD ></TR ></TABLE ></DIV ></BODY ></HTML >