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
|