Please take our Survey
logo       

Choosing A Webhost:
A web hosting service is a type of Internet hosting service that allows individuals and organizations to provide their own website accessible via the World Wide Web. Web hosts are companies that provide space on a server they own for use by their clients as well as providing Internet connectivity, typically in a data center. Web hosts can also provide data center space and connectivity to the Internet for servers they do not own to be located in their data center, called colocation. more...

[SSI] openssi/kernel/ipc msg.c,1.2.2.5,1.2.2.6 sem.c,1.2.2.9,1.2.2.10 shm.c: msg#00038

Subject: [SSI] openssi/kernel/ipc msg.c,1.2.2.5,1.2.2.6 sem.c,1.2.2.9,1.2.2.10 shm.c,1.2.2.13,1.2.2.14 util.c,1.2.2.5,1.2.2.6 util.h,1.2.2.3,1.2.2.4
Update of /cvsroot/ssic-linux/openssi/kernel/ipc
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31205/kernel/ipc

Modified Files:
      Tag: OPENSSI-RH
        msg.c sem.c shm.c util.c util.h 
Log Message:
1. Generating msg and sem ids from nameserver.
2. Handling the "under-migration" ipc object status.
3. Object database updation now follows base logic of id generation.
4. Converting the object data base to array from of linked list.


Index: util.h
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/Attic/util.h,v
retrieving revision 1.2.2.3
retrieving revision 1.2.2.4
diff -u -d -r1.2.2.3 -r1.2.2.4
--- util.h      27 Feb 2004 03:24:35 -0000      1.2.2.3
+++ util.h      17 Jun 2004 13:15:13 -0000      1.2.2.4
@@ -41,7 +41,11 @@
 
 /* must be called with ids->sem acquired.*/
 int ipc_findkey(struct ipc_ids* ids, key_t key);
+#ifdef CONFIG_SSI
+int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size, int 
newid);
+#else
 int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size);
+#endif
 
 /* must be called with both locks acquired. */
 struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id);
@@ -77,15 +81,11 @@
 extern inline struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
 {
        struct kern_ipc_perm* out;
-#ifdef CONFIG_SSI
-       int lid = (id - (this_node << SHIFT_SERVER))% SEQ_MULTIPLIER;
+       int lid = id % SEQ_MULTIPLIER;
 #ifdef TEST_IPC
        printk("%s%d%s%d%s%d\n","id = ", id,"lid = ",lid,
                        " ids->size = ",ids->size);
 #endif  /*  TEST_IPC  */
-#else
-       int lid = id % SEQ_MULTIPLIER;
-#endif  /*  CONFIG_SSI  */
 
 #ifdef CONFIG_SSI
        if((lid > ids->size) || !ids->in_use)
@@ -108,26 +108,14 @@
 
 extern inline int ipc_buildid(struct ipc_ids* ids, int id, int seq)
 {
-#ifdef CONFIG_SSI
-       return (this_node << SHIFT_SERVER) + SEQ_MULTIPLIER*seq + id;
-#else
        return SEQ_MULTIPLIER*seq +id;
-#endif /*  SSI_IPC  */
 }
 
 extern inline int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, 
int uid)
 {
-#ifdef CONFIG_SSI
-       if ((uid - (this_node << SHIFT_SERVER))/SEQ_MULTIPLIER != ipcp->seq) 
-               return 1;
-       else
-       return 0;
-#else  /* ! CONFIG_SSI  */
-
        if(uid/SEQ_MULTIPLIER != ipcp->seq)
                return 1;
        return 0;
-#endif  /*  CONFIG_SSI  */
 }
 
 #ifdef CONFIG_SSI

Index: sem.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/Attic/sem.c,v
retrieving revision 1.2.2.9
retrieving revision 1.2.2.10
diff -u -d -r1.2.2.9 -r1.2.2.10
--- sem.c       19 Feb 2004 08:43:02 -0000      1.2.2.9
+++ sem.c       17 Jun 2004 13:15:12 -0000      1.2.2.10
@@ -90,14 +90,15 @@
 #define SEM_IPC_ID(i,seq)      (local_view ? sem_buildid(i,seq) : ipc_id)
 #define PRINT_HEADER len += sprintf(buffer, "       key      semid perms      
nsems   uid   gid  cuid  cgid      otime      ctime       view    node_num\n")
 
-#else
+static int newary (key_t key, int nsems, int semflg, int newid);
+#else /* !CONFIG_SSI */
 static struct ipc_ids sem_ids;
 #define SEM_MAX_ID     sem_ids.max_id
 #define SEM_IPC_ID(i,seq)      sem_buildid(i,seq)
 #define PRINT_HEADER len += sprintf(buffer, "       key      semid perms      
nsems   uid   gid  cuid  cgid      otime      ctime\n")
+static int newary (key_t, int, int);
 #endif /* CONFIG_SSI */
 
-static int newary (key_t, int, int);
 static void freeary (int id);
 #ifdef CONFIG_PROC_FS
 static int sysvipc_sem_read_proc(char *buffer, char **start, off_t offset, int 
length, int *eof, void *data);
@@ -122,8 +123,9 @@
 #define sc_semmni      (sem_ctls[3])
 
 #ifdef CONFIG_SSI
+extern int cli_ipcname_findid(int, int, key_t *, clusternode_t *, int *, int 
*, int *);
 extern int cli_ipcname_rmid(int service, global_id_t glid);
-extern int cli_ipcname_getid (int objtype, key_t key, int msgflg,
+extern int cli_ipcname_getid (int objtype, key_t key, int in_flag,
                                         global_id_t *id, clusternode_t *server,
                                        int, int *);
 extern int cli_ripc_semctl(clusternode_t, int *, int, int, int,
@@ -132,12 +134,14 @@
                          ssi_procstate_t *, ics_userbuf_t *, ics_userbuf_t *);
 extern int cli_ripc_semexit(clusternode_t, int *, ssi_procstate_t *, int,
                                         pid_t);
-extern int ipc_idsvr(int semid);
 extern int cli_ipcname_gettotal(int objtype, char **, int *);
 extern int ssi_sem_get_sem_array(clusternode_t, int, int **);
 extern clusternode_t name_server_node;
 void ssi_semexit(int semid, pid_t pid);
 static struct sem_undo* freeundos(struct sem_undo* un);
+static clusternode_t sem_get_svr_node(int);
+static void sem_set_svr_node (int, clusternode_t);
+clusternode_t sem_nodehint[SEMMNI]={0};
 #endif  /*  CONFIG_SSI  */
 
 static int used_sems;
@@ -152,7 +156,11 @@
 #endif
 }
 
+#ifdef CONFIG_SSI
+static int newary (key_t key, int nsems, int semflg, int newid)
+#else
 static int newary (key_t key, int nsems, int semflg)
+#endif
 {
        int id;
        struct sem_array *sma;
@@ -169,7 +177,11 @@
                return -ENOMEM;
        }
        memset (sma, 0, size);
+#ifdef CONFIG_SSI
+       id = ipc_addid(&sem_ids, &sma->sem_perm, sc_semmni, newid);
+#else
        id = ipc_addid(&sem_ids, &sma->sem_perm, sc_semmni);
+#endif
        if(id == -1) {
                ipc_free(sma, size);
                return -ENOSPC;
@@ -194,9 +206,39 @@
 }
 
 #ifdef CONFIG_SSI
+static clusternode_t sem_get_svr_node(int semid)
+{
+       clusternode_t svr_node = 0;
+       int i;
+
+       if (semid%SEQ_MULTIPLIER > sc_semmni) {
+#ifdef TEST_IPC
+               printk("Invalid id %d, clearing the nodehint array\n", semid);
+#endif
+               for (i=0; i<sc_semmni; i++) {
+                       sem_nodehint[i] = 0;
+               }
+       } else
+               svr_node = sem_nodehint[semid%SEQ_MULTIPLIER];
+       return svr_node;
+}
+static void sem_set_svr_node(int semid, clusternode_t svr_node)
+{
+       int i;
+
+       if (semid%SEQ_MULTIPLIER > sc_semmni) {
+#ifdef TEST_IPC
+               printk("Invalid id %d, clearing the nodehint array\n", semid);
+#endif
+               for (i=0; i<sc_semmni; i++) {
+                       sem_nodehint[i] = 0;
+               }
+       } else
+               sem_nodehint[semid%SEQ_MULTIPLIER] = svr_node;
+}
 long ssi_semget (key_t key, int nsems, int semflg, struct sem_array* sma)
 {
-        int id = 0;
+       int id;
         global_id_t newid = 0;
         clusternode_t server = this_node;
         int retval = 0;
@@ -225,42 +267,33 @@
                         return retval;
                 }
         }
-
-       id = 0;
-        if (nsems)
-                id = newary(IPC_PRIVATE, nsems, semflg);
-       if (id < 0) {
-               up(&sem_ids.sem);
-               return id;
+       newid = 0;
+       if (!nsems) {
+               retval = -EINVAL;
+               goto out_up;
        }
-        newid = id;
-        up(&sem_ids.sem);
-
+       up(&sem_ids.sem);
         retval = cli_ipcname_getid(NAME_SERVICE_SEM, key, semflg, &newid, 
                                        &server, ssi_get_localview(), &create);
-        down(&sem_ids.sem);
-        if (retval < 0) {
-                if (nsems) {
-                       sma = sem_lock(id);
-                       freeary(id);
-               }
-        }
-        else if (newid == id)  {
-                retval = -ESRCH;
-               sma = sem_lock(id);
-                if (sma != NULL) {
-                        sma->sem_perm.key = key;
-                        retval = id;
-                       sem_unlock(id);
-                }
-        }
-        else {
-                if (nsems) {
-                       sma = sem_lock(id);
-                        freeary(id);
+#ifdef TEST_IPC
+       printk("after cli_ipcname_getid, glid = %d\n", newid);
+#endif /* TEST_IPC */
+       down(&sem_ids.sem);
+       if (!retval){
+               retval = newid;
+               if (!create)
+                       goto out_up;
+               if (server == this_node) {
+                       /* Create the server structure */
+                       if ((retval = newary (key, nsems, semflg, newid))<0) {
+                               printk("Unable to add new id %lu to sem_ids, 
removing the object on the nameserver\n", newid);
+                               cli_ipcname_rmid(NAME_SERVICE_SEM, newid);
+                               server = 0;
+                       }
                }
-                retval = newid;
-        }
+               sem_set_svr_node(newid, server);
+       }
+out_up:
         up(&sem_ids.sem);
         return retval;
 }
@@ -282,7 +315,7 @@
                 return -EINVAL;
 
         return ssi_semget(key, nsems, semflg, sma);
-#endif  /*  CONFIG_SSI   */
+#else  /* !CONFIG_SSI   */
 
        down(&sem_ids.sem);
        
@@ -310,6 +343,7 @@
 
        up(&sem_ids.sem);
        return err;
+#endif /* CONFIG_SSI */
 }
 
 /* doesn't acquire the sem_lock on error! */
@@ -536,7 +570,7 @@
 {
        struct sem_array *sma;
 #ifdef CONFIG_SSI
-        struct sem_semundo *un;
+       struct sem_semundo *un;
 #else
        struct sem_undo *un;
 #endif /* CONFIG_SSI */
@@ -570,6 +604,7 @@
 
 #ifdef CONFIG_SSI
         cli_ipcname_rmid(NAME_SERVICE_SEM,id);
+       sem_set_svr_node(id, 0);
 #endif /* CONFIG_SSI */
 }
 
@@ -766,7 +801,7 @@
        {
                int i;
 #ifdef CONFIG_SSI
-                struct sem_semundo *un;
+               struct sem_semundo *un;
 #else
                struct sem_undo *un;
 #endif /* CONFIG_SSI */
@@ -847,7 +882,7 @@
        {
                int val = arg.val;
 #ifdef CONFIG_SSI
-                struct sem_semundo *un;
+               struct sem_semundo *un;
 #else
                struct sem_undo *un;
 #endif /* CONFIG_SSI */
@@ -948,6 +983,7 @@
 #ifdef CONFIG_SSI
                 if(current->semundo && (current->epid == current->pid))
                         freeundos(current->semundo);
+               sem_set_svr_node(semid, 0);
 #endif /* CONFIG_SSI */
 
                err = 0;
@@ -979,10 +1015,12 @@
        int version;
 
 #ifdef CONFIG_SSI
-        int rval;
-        int arg_len;
-        clusternode_t svr_node;
-        ssi_procstate_t pstate;
+       int rval;
+       int arg_len, flags, view, sz;
+       clusternode_t svr_node=0;
+       ssi_procstate_t pstate;
+       key_t key;
+       int tmpcmd = cmd;
        
        remote_cmd = FALSE;
        if (semid == -1) {
@@ -999,26 +1037,50 @@
                return -EINVAL;
 
 #ifdef CONFIG_SSI
-        svr_node = ipc_idsvr(semid);
-        if ((svr_node && (svr_node != this_node)))
-        {
-                ssi_procstate_get(&pstate);
-                arg_len = sizeof((union semun)arg);
-                if (!svr_node)
-                        svr_node = name_server_node;
-
-                cli_ripc_semctl(svr_node, &rval, semid, semnum,
+       if ((semid > 0)&&(cmd >= 0)) {
+namesvr_go:
+               svr_node = sem_get_svr_node(semid);
+               if (!svr_node) {
+                       if (cli_ipcname_findid(NAME_SERVICE_SEM, semid, &key,
+                                       &svr_node, &flags, &view, &sz)<0) {
+                               sem_set_svr_node(semid, 0);
+                               return -EINVAL;
+                       } else if (svr_node == CLUSTERNODE_INVAL) {
+                               sem_set_svr_node(semid, 0);
+                               idelay(HZ/10);
+                               goto namesvr_go;
+                       } else if (svr_node) {
+                               down(&sem_ids.sem);
+                               sem_set_svr_node(semid, svr_node);
+                               up(&sem_ids.sem);
+                       }
+               }
+               if (svr_node && (svr_node != this_node)) {
+                       int status;
+                       ssi_procstate_get(&pstate);
+                       arg_len = sizeof((union semun)arg);
+                       status = cli_ripc_semctl(svr_node, &rval, semid, semnum,
                                         cmd, &pstate, &arg, arg_len);
-
-                /* If we are able to invalidate server semaphore objects,
-                   delete the local objects. */
-
-                version = ipc_parse_version(&cmd);
-                if(current->semundo && (rval == 0) && (cmd == IPC_RMID))
-                        freeundos(current->semundo);
-
-                return rval;
-        }
+                       version = ipc_parse_version(&cmd);
+                       /* If we are able to invalidate server semaphore objects
+                          delete the local objects. */
+                       if (status || (rval == -EINVAL && cmd != SEM_STAT)) {
+                               cmd = tmpcmd;
+                               sem_set_svr_node(semid, 0);
+                               goto namesvr_go;
+                       } else if(current->semundo && (rval == 0) && 
+                                                       (cmd == IPC_RMID)) {
+                               /* If we are able to invalidate server semaphore
+                                  objects, delete the local objects. */
+                               freeundos(current->semundo);
+                               sem_set_svr_node(semid, 0);
+                               return rval;
+                       }
+                       else
+                               return rval;
+               }
+               cmd = tmpcmd;
+       }
 #endif  /*  CONFIG_SSI  */
 
        version = ipc_parse_version(&cmd);
@@ -1028,6 +1090,13 @@
        case SEM_INFO:
        case SEM_STAT:
                err = semctl_nolock(semid,semnum,cmd,version,arg);
+#ifdef CONFIG_SSI
+               if (err == -EINVAL && remote_cmd == FALSE) {
+                       sem_set_svr_node(semid, 0);
+                       goto namesvr_go;
+               }
+               else
+#endif
                return err;
        case GETALL:
        case GETVAL:
@@ -1038,12 +1107,26 @@
        case SETVAL:
        case SETALL:
                err = semctl_main(semid,semnum,cmd,version,arg);
+#ifdef CONFIG_SSI
+               if (err == -EINVAL && remote_cmd == FALSE) {
+                       sem_set_svr_node(semid, 0);
+                       goto namesvr_go;
+               }
+               else
+#endif
                return err;
        case IPC_RMID:
        case IPC_SET:
                down(&sem_ids.sem);
                err = semctl_down(semid,semnum,cmd,version,arg);
                up(&sem_ids.sem);
+#ifdef CONFIG_SSI
+               if (err == -EINVAL && remote_cmd == FALSE) {
+                       sem_set_svr_node(semid, 0);
+                       goto namesvr_go;
+               }
+               else
+#endif
                return err;
        default:
                return -EINVAL;
@@ -1074,8 +1157,8 @@
 #ifdef CONFIG_SSI
 static struct sem_semundo* free_semundos(struct sem_array *sma, struct 
sem_semundo* un)
 {
-        struct sem_semundo* u;
-        struct sem_semundo** up;
+       struct sem_semundo* u;
+       struct sem_semundo** up;
 
         for(up = &sma->undo;(u=*up);up=&u->id_next) {
                 if(u->pid == un->pid ) {
@@ -1176,13 +1259,13 @@
               const struct timespec *timeout)
 {
 
-        int error = -EINVAL;
-        struct sem_array *sma;
-        struct sembuf fast_sops[SEMOPM_FAST];
-        struct sembuf* sops = fast_sops, *sop;
-        struct sem_semundo *un;
-        int undos = 0, decrease = 0, alter = 0;
-        struct sem_queue queue;
+       int error = -EINVAL;
+       struct sem_array *sma;
+       struct sembuf fast_sops[SEMOPM_FAST];
+       struct sembuf* sops = fast_sops, *sop;
+       struct sem_semundo *un;
+       int undos = 0, decrease = 0, alter = 0;
+       struct sem_queue queue;
        unsigned long jiffies_left = 0;
 
         if(nsops > SEMOPM_FAST) {
@@ -1387,11 +1470,12 @@
        struct sem_queue queue;
        unsigned long jiffies_left = 0;
 #else
-        int rval;
-        clusternode_t svr_node;
-        ssi_procstate_t pstate;
+       int rval, flags, view, sz;
+       clusternode_t svr_node=0;
+       ssi_procstate_t pstate;
        ics_userbuf_t utsops;
        ics_userbuf_t utimeout;
+       key_t key;
 #endif  /*  CONFIG_SSI  */
 
        if (nsops < 1 || semid < 0)
@@ -1399,7 +1483,23 @@
        if (nsops > sc_semopm)
                return -E2BIG;
 #ifdef CONFIG_SSI
-        svr_node = ipc_idsvr(semid);
+namesvr_op_go:
+       svr_node = sem_get_svr_node(semid);
+       if (!svr_node) {
+               if (cli_ipcname_findid(NAME_SERVICE_SEM, semid, &key,
+                                       &svr_node, &flags, &view, &sz)<0) {
+                       sem_set_svr_node(semid, 0);
+                       return -EINVAL;
+               } else if (svr_node == CLUSTERNODE_INVAL) {
+                       sem_set_svr_node(semid, 0);
+                       idelay(HZ/10);
+                       goto namesvr_op_go;
+               } else if (svr_node) {
+                       down(&sem_ids.sem);
+                       sem_set_svr_node(semid, svr_node);
+                       up(&sem_ids.sem);
+               }
+       }
         if (svr_node && (svr_node != this_node))
         {
                 ssi_procstate_get(&pstate);
@@ -1411,13 +1511,21 @@
 
                 if(!rval)
                         undocheck(tsops, semid, nsops);
+               if (rval == -EINVAL) {
+                       sem_set_svr_node(semid, 0);
+                       goto namesvr_op_go;
+               }
                 return rval;
 
         } else {
                 error = ssi_semop(semid, tsops, nsops, timeout);
-                if(!error)
+                if(!error) {
                         undocheck(tsops, semid, nsops);
-                return error;
+               } else if (error == -EINVAL) {
+                       sem_set_svr_node(semid, 0);
+                       goto namesvr_op_go;
+               }
+               return error;
         }
 #else /* !CONFIG_SSI */
        if(nsops > SEMOPM_FAST) {
@@ -1579,18 +1687,15 @@
  */
 void sem_exit (void)
 {
-#ifndef CONFIG_SSI
        struct sem_queue *q;
        struct sem_undo *u, *un = NULL, **up, **unp;
        struct sem_array *sma;
        int nsems, i;
-#else
-        struct sem_undo *u, **up;
-        struct sem_queue *q;
-        struct sem_array *sma;
-        int rval;
-        clusternode_t svr_node;
-        ssi_procstate_t pstate;
+#ifdef CONFIG_SSI
+       int rval, flags, view, sz;
+       clusternode_t svr_node=0;
+       ssi_procstate_t pstate;
+       key_t key;
 #endif /* CONFIG_SSI */
 
        /* If the current process was sleeping for a semaphore,
@@ -1615,9 +1720,21 @@
                 int semid = u->semid;
                 if(semid == -1)
                         continue;
-                svr_node = ipc_idsvr(semid);
-
+namesvr_semexit_go:
+               svr_node = sem_get_svr_node(semid);
+               if (!svr_node) {
+                       if (cli_ipcname_findid(NAME_SERVICE_SEM, semid, &key,
+                                       &svr_node, &flags, &view, &sz)<0) {
+                               sem_set_svr_node(semid, 0);
+                       } else if (svr_node == CLUSTERNODE_INVAL) {
+                               sem_set_svr_node(semid, 0);
+                               idelay(HZ/10);
+                               goto namesvr_semexit_go;
+                       } else if (svr_node)
+                               sem_set_svr_node(semid, svr_node);
+               }
                 if (svr_node && (svr_node != this_node)) {
+                       sem_set_svr_node(semid, 0);
                         ssi_procstate_get(&pstate);
                         cli_ripc_semexit(svr_node, &rval, &pstate, semid, 
current->epid);
                 } else
@@ -1718,7 +1835,9 @@
                        ipc_id = *((key_t *)tmp_pairs);
                        tmp_pairs += sizeof(key_t);
                        i++;
-                       if (node_num == this_node)
+                       if (node_num == CLUSTERNODE_INVAL)
+                               node_num = -1;
+                       else if (node_num == this_node)
                                sma = sem_lock(ipc_id);
                        else
                        {
@@ -1796,10 +1915,10 @@
 #ifdef CONFIG_SSI
 void ssi_semexit(int semid, pid_t pid)
 {
-        /* struct sem_queue *q; */
-        struct sem_semundo *un = NULL, **unp;
-        struct sem_array *sma;
-        int nsems, i;
+       /* struct sem_queue *q; */
+       struct sem_semundo *un = NULL, **unp;
+       struct sem_array *sma;
+       int nsems, i;
 
         sma = sem_lock(semid);
         if (sma == NULL)

Index: shm.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/Attic/shm.c,v
retrieving revision 1.2.2.13
retrieving revision 1.2.2.14
diff -u -d -r1.2.2.13 -r1.2.2.14
--- shm.c       27 May 2004 18:51:08 -0000      1.2.2.13
+++ shm.c       17 Jun 2004 13:15:12 -0000      1.2.2.14
@@ -86,7 +86,6 @@
 #define shm_unlockall()        ipc_unlockall(&shm_ids)
 #define shm_get(id)    ((struct shmid_kernel*)ipc_get(&shm_ids,id))
 #ifdef CONFIG_SSI
-#define shm_buildid(id, seq) (SEQ_MULTIPLIER*seq +id)
 #define SHM_MAX_ID     local_view ? shm_ids.max_id : size-1
 #define SHM_IPC_ID(i,seq)      (local_view ? shm_buildid(i,seq) : ipc_id)
 #define PRINT_HEADER \
@@ -101,21 +100,16 @@
 {
        return ((struct shmid_kernel *)ipc_get(&shm_ids,id));
 }
-
+static int newseg (key_t key, int shmflg, size_t size, struct file *, int 
view);
 #else
-#define shm_buildid(id, seq) \
-       ipc_buildid(&shm_ids, id, seq)
 #define SHM_MAX_ID     shm_ids.max_id
 #define SHM_IPC_ID(i,seq)      shm_buildid(i,seq)
 #define PRINT_HEADER \
                len += sprintf(buffer, "       key      shmid perms       size  
cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n");
-#endif
-
-#ifdef CONFIG_SSI
-static int newseg (key_t key, int shmflg, size_t size, struct file *, int 
view);
-#else
 static int newseg (key_t key, int shmflg, size_t size);
 #endif
+#define shm_buildid(id, seq) \
+       ipc_buildid(&shm_ids, id, seq)
 static void shm_open (struct vm_area_struct *shmd);
 static void shm_close (struct vm_area_struct *shmd);
 #ifdef CONFIG_PROC_FS
@@ -167,7 +161,11 @@
 
 static inline int shm_addid(struct shmid_kernel *shp)
 {
+#ifdef CONFIG_SSI
+       return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni+1, 0);
+#else
        return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni+1);
+#endif
 }
 
 
@@ -606,7 +604,7 @@
 #ifdef CONFIG_SSI
                int max_id=0;
                nsc_nodelist_t *nl;
-               nsc_nlcookie_t cookie;
+               nsc_nlcookie_t cookie;
 #endif
                memset(&shm_info,0,sizeof(shm_info));
                down(&shm_ids.sem);

Index: util.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/Attic/util.c,v
retrieving revision 1.2.2.5
retrieving revision 1.2.2.6
diff -u -d -r1.2.2.5 -r1.2.2.6
--- util.c      30 Mar 2004 09:08:30 -0000      1.2.2.5
+++ util.c      17 Jun 2004 13:15:13 -0000      1.2.2.6
@@ -96,6 +96,9 @@
 {
        int id;
        struct kern_ipc_perm* p;
+#ifdef CONFIG_SSI
+       extern struct ipc_ids shm_ids_svr;
+#endif
 
        for (id = 0; id <= ids->max_id; id++) {
                p = ids->entries[id].p;
@@ -108,7 +111,7 @@
 
                        if (view ^ p->local_view)
                                continue;
-                       else if (shm_svr_get(id) == NULL)
+                       else if((shm_svr_get(id) == NULL)&&(ids==&shm_ids_svr))
                                continue;
                        else
                                return id;
@@ -203,7 +206,7 @@
 
        if (table)
                down(&ids->sem);
-       if (id)
+       if (id>0)
                p = ipc_lock(ids, id);
        return p;
 }
@@ -211,7 +214,7 @@
 void
 ipc_drop_locks(int id, struct ipc_ids *ids, int table)
 {
-       if (id)
+       if (id>0)
                ipc_unlock(ids, id);
        if (table)
                up(&ids->sem);
@@ -229,12 +232,22 @@
  *     is returned. The list is returned in a locked state on success.
  *     On failure the list is not locked and -1 is returned.
  */
- 
+#ifdef CONFIG_SSI 
+int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size, int 
newid)
+#else
 int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
+#endif
 {
        int id;
 
        size = grow_ary(ids,size);
+#ifdef CONFIG_SSI
+       if (newid) {
+               id = newid%SEQ_MULTIPLIER;
+               ids->seq = newid/SEQ_MULTIPLIER;
+               goto found;
+       }
+#endif
        for (id = 0; id < size; id++) {
                if(ids->entries[id].p == NULL)
                        goto found;

Index: msg.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/ipc/Attic/msg.c,v
retrieving revision 1.2.2.5
retrieving revision 1.2.2.6
diff -u -d -r1.2.2.5 -r1.2.2.6
--- msg.c       19 Feb 2004 08:43:02 -0000      1.2.2.5
+++ msg.c       17 Jun 2004 13:15:12 -0000      1.2.2.6
@@ -32,6 +32,9 @@
 #include <cluster/nsc.h>
 #include <cluster/nodelist.h>
 
+extern int cli_ipcname_getid (int objtype, key_t key, int in_flag,
+                     global_id_t *id, clusternode_t *server,int view, int *sz);
+extern int cli_ipcname_findid(int, int, key_t *, clusternode_t *, int *, int 
*, int *);
 extern int cli_ipcname_gettotal(int objtype, char **, int *);
 extern int cli_ipcname_rmid(int service, global_id_t glid);
 extern int cli_ripc_msgctl(clusternode_t, int *, int, int, ssi_procstate_t *,
@@ -45,7 +48,6 @@
 
 #define MSG_MAX_ID     local_view ? msg_ids.max_id : size-1
 #define MSG_IPC_ID(i,seq)      (local_view ? msg_buildid(i,seq) : ipc_id)
-
 #define PRINT_HEADER \
                len += sprintf(buffer, "       key      msqid perms      cbytes 
      qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime 
      view     node_num\n");
 #else
@@ -124,41 +126,53 @@
 static atomic_t msg_hdrs = ATOMIC_INIT(0);
 
 struct ipc_ids msg_ids;
+#ifdef CONFIG_SSI
+clusternode_t msg_nodehint[MSGMNI]={0};
 
+#endif
 #define msg_lock(id)   ((struct msg_queue*)ipc_lock(&msg_ids,id))
 #define msg_unlock(id) ipc_unlock(&msg_ids,id)
 #define msg_rmid(id)   ((struct msg_queue*)ipc_rmid(&msg_ids,id))
 #define msg_checkid(msq, msgid)        \
-       ipc_checkid(&msg_ids,&msq->q_perm,msgid)
+       ipc_checkid(&msg_ids, &msq->q_perm, msgid)
 #define msg_buildid(id, seq) \
        ipc_buildid(&msg_ids, id, seq)
-
 static void freeque (int id);
+#ifdef CONFIG_SSI
+int newque (key_t key, int msgflg, int newid);
+static clusternode_t msg_get_svr_node(int);
+static void msg_set_svr_node(int, clusternode_t);
+#else
 int newque (key_t key, int msgflg);
+#endif
 #ifdef CONFIG_PROC_FS
 static int sysvipc_msg_read_proc(char *buffer, char **start, off_t offset, int 
length, int *eof, void *data);
 #endif
 
-extern int ipc_idsvr(int msqid);
-
 void __init msg_init (void)
 {
        ipc_init_ids(&msg_ids,msg_ctlmni);
-
 #ifdef CONFIG_PROC_FS
        create_proc_read_entry("sysvipc/msg", 0, 0, sysvipc_msg_read_proc, 
NULL);
 #endif
 }
 
+#ifdef CONFIG_SSI
+int newque (key_t key, int msgflg, int newid)
+#else
 int newque (key_t key, int msgflg)
+#endif
 {
        int id;
        struct msg_queue *msq;
-
        msq  = (struct msg_queue *) kmalloc (sizeof (*msq), GFP_KERNEL);
        if (!msq) 
                return -ENOMEM;
+#ifdef CONFIG_SSI
+       id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni, newid);
+#else
        id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni);
+#endif
        if(id == -1) {
                kfree(msq);
                return -ENOSPC;
@@ -350,7 +364,6 @@
        struct list_head *tmp;
 
        msq = msg_rmid(id);
-
        expunge_all(msq,-EIDRM);
        ss_wakeup(&msq->q_senders,1);
        msg_unlock(id);
@@ -365,17 +378,47 @@
        atomic_sub(msq->q_cbytes, &msg_bytes);
        kfree(msq);
 #ifdef CONFIG_SSI
-       cli_ipcname_rmid(0,id);
+       cli_ipcname_rmid(NAME_SERVICE_MSG,id);
+       msg_set_svr_node (id, 0);
 }
 
-extern int cli_ipcname_getid (int objtype, key_t key, int msgflg,
-                     global_id_t *id, clusternode_t *server,int view, int *sz);
 
 long checkid (key_t key, int id)
 {
        return id;
 }
 
+static clusternode_t msg_get_svr_node(int msqid)
+{
+       clusternode_t svr_node = 0;
+       int i;
+
+       if (msqid%SEQ_MULTIPLIER > msg_ctlmni) {
+#ifdef TEST_IPC
+               printk("Invalid id %d, clearing the nodehint array\n", msqid);
+#endif
+               for (i=0; i<msg_ctlmni; i++) {
+                       msg_nodehint[i] = 0;
+               }
+       } else
+               svr_node = msg_nodehint[msqid%SEQ_MULTIPLIER];
+       return svr_node;
+}
+
+static void msg_set_svr_node(int msqid, clusternode_t svr_node)
+{
+       int i;
+
+       if (msqid%SEQ_MULTIPLIER > msg_ctlmni) {
+#ifdef TEST_IPC
+               printk("Invalid id %d, clearing the nodehint array\n", msqid);
+#endif
+               for (i=0; i<msg_ctlmni; i++) {
+                       msg_nodehint[i] = 0;
+               }
+       } else
+               msg_nodehint[msqid%SEQ_MULTIPLIER] = svr_node;
+}
 
 long ssi_msgget (key_t key, int msgflg, struct msg_queue* msq)
 {
@@ -383,7 +426,7 @@
        global_id_t newid = 0;
        clusternode_t server = this_node;
        int retval = 0;
-       int tmp = 0;
+       int create = 0;
 
        down(&msg_ids.sem);
        if (key != IPC_PRIVATE) {
@@ -407,7 +450,7 @@
                                        retval = -EACCES;
                                else
                                        retval = msg_buildid(id,
-                                                            msq->q_perm.seq);
+                                                    msq->q_perm.seq);
                                msg_unlock(id);
                        }
                        up(&msg_ids.sem);
@@ -417,38 +460,29 @@
 #ifdef TEST_IPC
        printk("%s\n","key either private or not found");
 #endif  /*  TEST_IPC  */
-       id = newque (IPC_PRIVATE, msgflg);
-       if (id < 0) {
-               up(&msg_ids.sem);
-                return id;
-       }
-       newid = id;
+       newid = 0;
        up(&msg_ids.sem);
        retval = cli_ipcname_getid(NAME_SERVICE_MSG, key, msgflg, &newid,
-                                  &server, ssi_get_localview(), &tmp);
+                                  &server, ssi_get_localview(), &create);
 #ifdef TEST_IPC
        printk("after cli_ipcname_getid, glid = %d\n",newid);
 #endif /*  TEST_IPC  */
        down(&msg_ids.sem);
-       msq = msg_lock(id);
-       if (retval < 0) {
-               freeque(id);
-       }
-       else if (newid == id)  {
-               retval = -ESRCH;
-               if (msq != NULL) {
-                       msq->q_perm.key = key;
-                       retval = checkid (key, id);  /*****/
-               }
-               msg_unlock(id);
-       }
-       else {
-#ifdef TEST_IPC
-               printk("%s%d\n","removing id ", id);
-#endif  /*  TEST_IPC  */
-               freeque(id);
+       if (!retval)
+       {
                retval = newid;
+               if (!create)
+                       goto out_nolock;
+               if (server == this_node) {
+                       if ((retval=newque(key, msgflg, newid)) < 0) {
+                               printk("Unable to add newid %lu to msg_ids, 
removing the object on nameserver\n", newid);
+                               cli_ipcname_rmid(NAME_SERVICE_MSG,newid);
+                               server = 0;
+                       } 
+               } 
+               msg_set_svr_node(newid, server);
        }
+out_nolock:
        up(&msg_ids.sem);
        return retval;
 #endif  /*  CONFIG_SSI  */
@@ -463,7 +497,6 @@
        (void) ret;
        return ssi_msgget(key, msgflg, msq);
 #else
-
        down(&msg_ids.sem);
        if (key == IPC_PRIVATE) 
                ret = newque(key, msgflg);
@@ -579,7 +612,6 @@
                return -EINVAL;
        }
 }
-
 asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds *buf)
 {
        int err, version;
@@ -588,10 +620,12 @@
        struct kern_ipc_perm *ipcp;
        
 #ifdef CONFIG_SSI  
-       int rval, remote_cmd;
-       clusternode_t svr_node;
+       int rval, remote_cmd, flags, sz, view;
+       key_t key;
+       clusternode_t svr_node=0;
        ssi_procstate_t pstate;
        long bufp = (long)buf;
+       int tmpcmd = cmd;
 
        remote_cmd = FALSE;
        if (msqid == -1) {
@@ -602,27 +636,45 @@
                        msqid = 0;
                }
        }
-       svr_node = ipc_idsvr(msqid);
-       if ((svr_node && (svr_node != this_node)))
-       {
-               int status;
-
-               ssi_procstate_get(&pstate);
-               if (!svr_node)
-                       svr_node = name_server_node;
-               status = cli_ripc_msgctl(svr_node, &rval, msqid, cmd, &pstate, 
&bufp);
-               if (status)
-                       return -EINVAL;
-
-               return rval;
-       }
 #endif  /*  CONFIG_SSI  */
 
        if (msqid < 0 || cmd < 0)
                return -EINVAL;
 
        version = ipc_parse_version(&cmd);
-
+#ifdef CONFIG_SSI
+       if ((msqid > 0)&&(cmd >= 0)) {
+namesvr_go:
+               svr_node = msg_get_svr_node(msqid);
+               if (!svr_node) {
+                       if (cli_ipcname_findid(NAME_SERVICE_MSG, msqid, &key, 
+                                       &svr_node, &flags, &view, &sz)<0) {
+                               msg_set_svr_node (msqid, 0);
+                               return -EINVAL;
+                       } else if (svr_node == CLUSTERNODE_INVAL) {
+                               /* Cant determine svr node - object is moving */
+                               msg_set_svr_node(msqid, 0);
+                               idelay(HZ/10);
+                               goto namesvr_go;
+                       } else if (svr_node > 0) {
+                               down (&msg_ids.sem);
+                               msg_set_svr_node(msqid, svr_node);
+                               up (&msg_ids.sem);
+                       }
+               }
+               if (svr_node && (svr_node != this_node)) {
+                       int status;
+                       ssi_procstate_get(&pstate);
+                       status = cli_ripc_msgctl(svr_node, &rval, msqid, 
tmpcmd, &pstate, &bufp);
+                       if (status || (rval == -EINVAL && cmd != MSG_STAT)) {
+                               msg_set_svr_node(msqid, 0);
+                               goto namesvr_go;
+                       }
+                       else
+                               return rval;
+               }
+        }
+#endif
        switch (cmd) {
        case IPC_INFO: 
        case MSG_INFO: 
@@ -718,7 +770,18 @@
 
                msq = msg_lock(msqid);
                if (msq == NULL)
+#ifdef CONFIG_SSI
+               {
+                       if (remote_cmd == FALSE) {
+                               msg_set_svr_node(msqid, 0);
+                               goto namesvr_go;
+                       }
+                       else
+                               return -EINVAL;
+               }
+#else
                        return -EINVAL;
+#endif
 
                if(cmd == MSG_STAT) {
 #ifndef CONFIG_SSI
@@ -764,8 +827,19 @@
        msq = msg_lock(msqid);
        err=-EINVAL;
        if (msq == NULL)
+#ifdef CONFIG_SSI
+       {
+               if (remote_cmd == FALSE) {
+                       msg_set_svr_node(msqid, 0);
+                       up(&msg_ids.sem);
+                       goto namesvr_go;
+               }
+               else
+                       goto out_up;
+       }
+#else
                goto out_up;
-
+#endif
        err = -EIDRM;
        if (msg_checkid(msq,msqid))
                goto out_unlock_up;
@@ -971,10 +1045,11 @@
        int err;
 
 #ifdef CONFIG_SSI
-       int rval;
+       int rval, flags, view, sz;
+       key_t key;
        int msize, bufsize = 0;
        char *packedsegs = NULL;
-       clusternode_t svr_node;
+       clusternode_t svr_node=0;
 #endif  /*  CONFIG_SSI  */
 
        if (msgsz > msg_ctlmax || (long) msgsz < 0 || msqid < 0)
@@ -993,14 +1068,32 @@
 
 #ifdef CONFIG_SSI
 #ifdef TEST_IPC
-       printk("checking objeect server node\n");
+       printk("checking object server node\n");
 #endif  /*  TEST_IPC  */
-       if ((svr_node = ipc_idsvr(msqid)) == this_node) {
-               rval = ssi_msgsnd(msqid, &msg, msgflg);
-               goto ssi_out;
+namesvr_snd_go:
+       svr_node = msg_get_svr_node(msqid);
+       if (!svr_node) {
+               if (cli_ipcname_findid(NAME_SERVICE_MSG, msqid, &key, &svr_node,
+                                                       &flags, &view, &sz)<0) {
+                       rval = -EINVAL;
+                       goto ssi_out;
+               } else if (svr_node == CLUSTERNODE_INVAL) {
+                       /* Cant determine svr node - object is moving */
+                       msg_set_svr_node(msqid, 0);
+                       idelay(HZ/10);
+                       goto namesvr_snd_go;
+               } else if (svr_node) {
+                       down(&msg_ids.sem);
+                       msg_set_svr_node(msqid, svr_node);
+                       up(&msg_ids.sem);
+               }
        }
-       else if (svr_node == CLUSTERNODE_INVAL) {
-               rval = -EINVAL;
+       if (svr_node && (svr_node == this_node)) {
+               rval = ssi_msgsnd(msqid, &msg, msgflg);
+               if (rval == -EINVAL) {
+                       msg_set_svr_node(msqid, 0);
+                       goto namesvr_snd_go;
+               }
                goto ssi_out;
        }
 #ifdef TEST_IPC
@@ -1015,7 +1108,10 @@
                        bufsize, msgflg);       
        if (packedsegs != NULL)
                kfree(packedsegs);
-
+       if (err || (rval == -EINVAL)) {
+               msg_set_svr_node(msqid, 0);
+               goto namesvr_snd_go;
+       }
 ssi_out:
        if (msg)
                free_msg(msg);
@@ -1114,37 +1210,56 @@
        int mode;
 
 #ifdef CONFIG_SSI
-       int rval, txtsz;
+       int rval, txtsz, flags, view, sz;
+       key_t key;
        long rettyp;
-       clusternode_t svr_node;
+       clusternode_t svr_node=0;
        char *msgtxt;
-       if ((svr_node = ipc_idsvr(msqid)) != this_node) {
-               int status;
 
-               if (svr_node < 0 || (long)msgsz < 0) 
+namesvr_rcv_go:
+       svr_node = msg_get_svr_node(msqid);
+       if (!svr_node) {
+               if (cli_ipcname_findid (NAME_SERVICE_MSG, msqid, &key, 
+                                       &svr_node, &flags, &view, &sz) < 0) {
+                       return -EINVAL;
+               } else if (svr_node == CLUSTERNODE_INVAL) {
+                       /* Cant determine svr node - object is moving */
+                       msg_set_svr_node(msqid, 0);
+                       idelay(HZ/10);
+                       goto namesvr_rcv_go;
+               } else if (svr_node) {
+                       down(&msg_ids.sem);
+                       msg_set_svr_node(msqid, svr_node);
+                       up(&msg_ids.sem);
+               }
+       }
+       if (svr_node && (svr_node != this_node)) {
+               int status;
+               if (svr_node < 0 || (long)msgsz < 0)
                        return -EINVAL; 
-                txtsz = (int)msgsz;
-                msgtxt = (char *)kmalloc(txtsz, GFP_KERNEL); 
-                if (msgtxt == NULL)
+               txtsz = (int)msgsz;
+               msgtxt = (char *)kmalloc(txtsz, GFP_KERNEL); 
+               if (msgtxt == NULL)
                         return -ENOMEM;
-                memset (msgtxt, 0, txtsz);
-                rval = 0;
-                status = cli_ripc_msgrcv(svr_node, &rval, msqid, msgsz, 
msgtyp, msgflg,
-                       &msgtxt, &txtsz, &rettyp);  
-                if (rval > 0) {
+               memset (msgtxt, 0, txtsz);
+               rval = 0;
+               status = cli_ripc_msgrcv(svr_node, &rval, msqid, msgsz, msgtyp, 
                                          msgflg, &msgtxt, &txtsz, &rettyp);  
+               if (rval > 0) {
                        if (put_user (rettyp, &msgp->mtype)) {
                                rval = -EFAULT;
-                       }
+                       }
                        if (copy_to_user(msgp->mtext, msgtxt, msgsz)) {
-                               rval = -EFAULT;
+                               rval = -EFAULT;
                        }
-                }
+               }
 #ifdef  TEST_IPC
-                else printk("receive failed, rval = %d\n",rval);
+               else printk("receive failed, rval = %d\n",rval);
 #endif  /*  TEST_IPC  */
                kfree(msgtxt);
-               if (status)
-                       return -EINVAL;
+               if (status) {
+                       msg_set_svr_node(msqid, 0);
+                       goto namesvr_rcv_go;
+               }
                return rval;
        }
 #endif  /*  CONFIG_SSI  */
@@ -1155,7 +1270,14 @@
 
        msq = msg_lock(msqid);
        if(msq==NULL)
+#ifdef CONFIG_SSI
+       {
+               msg_set_svr_node(msqid, 0);
+               goto namesvr_rcv_go;
+       }
+#else
                return -EINVAL;
+#endif
 retry:
        err = -EIDRM;
        if (msg_checkid(msq,msqid))
@@ -1242,8 +1364,9 @@
                        goto out_success;
                */
                t = msg_lock(msqid);
+
                if(t==NULL)
-                       msqid=-1;
+                       msqid = -1;
                msg = (struct msg_msg*)msr_d.r_msg;
                if(!IS_ERR(msg)) {
                        /* our message arived while we waited for
@@ -1423,7 +1546,6 @@
        char *node_id_pairs=NULL;
        char *tmp_pairs=NULL;
        int  size=0, node_num=0;
-       char *tmsq=NULL;
 
        bzero(viewstr, 10);
        if (!local_view)
@@ -1453,16 +1575,17 @@
                        tmp_pairs += sizeof(int);
                        ipc_id = *((key_t *)tmp_pairs);
                        tmp_pairs += sizeof(key_t);
-                       i++;
-                       if (node_num == this_node)
+                       i++; 
+                       if (node_num == CLUSTERNODE_INVAL)
+                               node_num = -1;
+                       else if (node_num == this_node)
                                msq = msg_lock(ipc_id);
                        else
                        {
-                               tmsq = (struct msg_queue 
*)kmalloc(sizeof(struct msg_queue), GFP_KERNEL);
-                               if (tmsq == NULL) break;
-                               memset(tmsq, 0, sizeof(struct msg_queue));
-                               ssi_msg_get_msg_queue(node_num, ipc_id, &tmsq);
-                               msq = (struct msg_queue *)tmsq;
+                               msq = kmalloc(sizeof(struct msg_queue), 
GFP_KERNEL);
+                               if (msq == NULL) break;
+                               memset(msq, 0, sizeof(struct msg_queue));
+                               ssi_msg_get_msg_queue(node_num, ipc_id, (char 
**)&msq);
                        }
                }
                else {
@@ -1518,7 +1641,6 @@
                        if(pos > offset + length)
                                goto done;
                }
-
        }
        *eof = 1;
 done:



-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

Recently Viewed:
qplus.devel/200...    network.jabber....    debian.qa-packa...    encryption.gpg....    python.dabo.dev...    uclinux.devel/2...    science.mathema...    recreation.pesc...    kernel.ck/2004-...    mozilla.devel.e...    tex.latex.prosp...    ietf.multi6/200...    bbc.cvs/2002-11...    xfree86.newbie/...    jakarta.taglibs...    altlinux.hardwa...    comedi/2002-05/...    horde.bugs/2004...    games.diplomacy...    finance.e-gold....    web.dom.test-su...    lang.ruby.rails...    os.netbsd.devel...    video.gstreamer...   
Home | advertise | OSDir is an inevitable website. super tiny logo

Free Magazines

Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe

Systems Management News, the newspaper for IT systems administration and data center managers! Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe

The Enterprise Newsweekly eWeek is the essential technology information source for builders of e-business.
subscribe

Oracle Magazine Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe

Total Telecom Total Telecom is "The Economist of the communications industry".
subscribe

Navigation