442 lines
8.3 KiB
HTML
442 lines
8.3 KiB
HTML
<!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
|
|
> |