don't use free and alloc as structure elements
[sfrench/samba-autobuild/.git] / source3 / locking / locking_shm.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    shared memory locking implementation
5    Copyright (C) Andrew Tridgell 1992-1997
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21    Revision History:
22
23    12 aug 96: Erik.Devriendt@te6.siemens.be
24    added support for shared memory implementation of share mode locking
25
26    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27    locking to deal with multiple share modes per open file.
28
29    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30    support.
31
32    October 1997 - split into separate file (tridge)
33 */
34
35 #ifdef FAST_SHARE_MODES
36
37 #include "includes.h"
38 extern int DEBUGLEVEL;
39 extern connection_struct Connections[];
40 extern files_struct Files[];
41
42 static struct shmem_ops *shmops;
43
44 /* share mode record pointed to in shared memory hash bucket */
45 typedef struct
46 {
47   int next_offset; /* offset of next record in chain from hash bucket */
48   int locking_version;
49   int32 st_dev;
50   int32 st_ino;
51   int num_share_mode_entries;
52   int share_mode_entries; /* Chain of share mode entries for this file */
53   char file_name[1];
54 } share_mode_record;
55
56 /* share mode entry pointed to by share_mode_record struct */
57 typedef struct
58 {
59         int next_share_mode_entry;
60         share_mode_entry e;
61 } shm_share_mode_entry;
62
63 static int read_only;
64
65
66 /* Conversion to hash entry index from device and inode numbers. */
67 #define HASH_ENTRY(dev,ino) ((((uint32)(dev)) ^ ((uint32)(ino))) % shmops->hash_size())
68
69
70 /*******************************************************************
71   deinitialize the shared memory for share_mode management 
72   ******************************************************************/
73 static BOOL shm_stop_share_mode_mgmt(void)
74 {
75    return shmops->shm_close();
76 }
77
78 /*******************************************************************
79   lock a hash bucket entry in shared memory for share_mode management 
80   ******************************************************************/
81 static BOOL shm_lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
82 {
83   return shmops->lock_hash_entry(HASH_ENTRY(dev, inode));
84 }
85
86 /*******************************************************************
87   unlock a hash bucket entry in shared memory for share_mode management 
88   ******************************************************************/
89 static BOOL shm_unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token)
90 {
91   return shmops->unlock_hash_entry(HASH_ENTRY(dev, inode));
92 }
93
94 /*******************************************************************
95 get all share mode entries in shared memory for a dev/inode pair.
96 ********************************************************************/
97 static int shm_get_share_modes(int cnum, int token, uint32 dev, uint32 inode, 
98                                share_mode_entry **old_shares)
99 {
100   int *mode_array;
101   unsigned int hash_entry = HASH_ENTRY(dev, inode); 
102   share_mode_record *file_scanner_p;
103   share_mode_record *file_prev_p;
104   shm_share_mode_entry *entry_scanner_p;
105   shm_share_mode_entry *entry_prev_p;
106   int num_entries;
107   int num_entries_copied;
108   BOOL found = False;
109   share_mode_entry *share_array = (share_mode_entry *)0;
110
111   *old_shares = 0;
112
113   mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
114   
115   if(mode_array[hash_entry] == 0)
116   {
117     DEBUG(5,("get_share_modes hash bucket %d empty\n", hash_entry));
118     return 0;
119   }
120
121   file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
122   file_prev_p = file_scanner_p;
123   while(file_scanner_p)
124   {
125     if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
126     {
127       found = True;
128       break;
129     }
130     else
131     {
132       file_prev_p = file_scanner_p ;
133       file_scanner_p = (share_mode_record *)shmops->offset2addr(
134                                     file_scanner_p->next_offset);
135     }
136   }
137   
138   if(!found)
139   {
140     DEBUG(5,("get_share_modes no entry for file dev = %d ino = %d\n",
141              dev, inode));
142     return (0);
143   }
144   
145   if(file_scanner_p->locking_version != LOCKING_VERSION)
146   {
147     DEBUG(0,("ERROR: get_share_modes  Deleting old share mode v1 %d dev=%d ino=%d\n", 
148              file_scanner_p->locking_version, dev, inode));
149     if(file_prev_p == file_scanner_p)
150       mode_array[hash_entry] = file_scanner_p->next_offset;
151     else
152       file_prev_p->next_offset = file_scanner_p->next_offset;
153     shmops->shm_free(shmops->addr2offset(file_scanner_p));
154     return (0);
155   }
156
157   /* Allocate the old_shares array */
158   num_entries = file_scanner_p->num_share_mode_entries;
159   if(num_entries)
160   {
161     *old_shares = share_array = (share_mode_entry *)
162                  malloc(num_entries * sizeof(share_mode_entry));
163     if(*old_shares == 0)
164     {
165       DEBUG(0,("get_share_modes: malloc fail!\n"));
166       return 0;
167     }
168   }
169
170   num_entries_copied = 0;
171   
172   entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
173                                            file_scanner_p->share_mode_entries);
174   entry_prev_p = entry_scanner_p;
175   while(entry_scanner_p)
176   {
177     int pid = entry_scanner_p->e.pid;
178
179     if (pid && !process_exists(pid))
180     {
181       /* Delete this share mode entry */
182       shm_share_mode_entry *delete_entry_p = entry_scanner_p;
183
184       if(entry_prev_p == entry_scanner_p)
185       {
186         /* We are at start of list */
187         file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
188         entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
189                                            file_scanner_p->share_mode_entries);
190         entry_prev_p = entry_scanner_p;
191       }
192       else
193       {
194         entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
195         entry_scanner_p = (shm_share_mode_entry*)
196                            shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
197       }
198       /* Decrement the number of share mode entries on this share mode record */
199       file_scanner_p->num_share_mode_entries -= 1;
200
201       /* PARANOIA TEST */
202       if(file_scanner_p->num_share_mode_entries < 0)
203       {
204         DEBUG(0,("PANIC ERROR: get_share_mode: entries=%d dev=%d ino=%d\n",
205                  file_scanner_p->num_share_mode_entries,dev, inode));
206         return 0;
207       }
208
209       DEBUG(0,("get_share_modes: process %d no longer exists\n", pid));
210
211       shmops->shm_free(shmops->addr2offset(delete_entry_p));
212     } 
213     else
214     {
215        /* This is a valid share mode entry and the process that
216            created it still exists. Copy it into the output array.
217        */
218        share_array[num_entries_copied].pid = entry_scanner_p->e.pid;
219        share_array[num_entries_copied].share_mode = entry_scanner_p->e.share_mode;
220        share_array[num_entries_copied].op_port = entry_scanner_p->e.op_port;
221        share_array[num_entries_copied].op_type = entry_scanner_p->e.op_type;
222        memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->e.time,
223               sizeof(struct timeval));
224        num_entries_copied++;
225        DEBUG(5,("get_share_modes Read share mode 0x%X pid=%d\n", 
226                 entry_scanner_p->e.share_mode, entry_scanner_p->e.pid));
227        entry_prev_p = entry_scanner_p;
228        entry_scanner_p = (shm_share_mode_entry *)
229                            shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
230     }
231   }
232   
233   /* If no valid share mode entries were found then this record shouldn't exist ! */
234   if(num_entries_copied == 0)
235   {
236     DEBUG(0,("get_share_modes: file with dev %d inode %d empty\n", 
237              dev, inode));
238     if(*old_shares)
239       free((char *)*old_shares);
240     *old_shares = 0;
241
242     if(file_prev_p == file_scanner_p)
243       mode_array[hash_entry] = file_scanner_p->next_offset;
244     else
245       file_prev_p->next_offset = file_scanner_p->next_offset;
246     shmops->shm_free(shmops->addr2offset(file_scanner_p));
247   }
248
249   DEBUG(5,("get_share_modes: file with dev %d inode %d -> %d entries\n",
250            dev, inode, num_entries_copied));
251
252   return(num_entries_copied);
253 }  
254
255 /*******************************************************************
256 del the share mode of a file.
257 ********************************************************************/
258 static void shm_del_share_mode(int token, int fnum)
259 {
260   uint32 dev, inode;
261   int *mode_array;
262   unsigned int hash_entry;
263   share_mode_record *file_scanner_p;
264   share_mode_record *file_prev_p;
265   shm_share_mode_entry *entry_scanner_p;
266   shm_share_mode_entry *entry_prev_p;
267   BOOL found = False;
268   int pid = getpid();
269
270   dev = Files[fnum].fd_ptr->dev;
271   inode = Files[fnum].fd_ptr->inode;
272
273   hash_entry = HASH_ENTRY(dev, inode);
274
275   mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
276  
277   if(mode_array[hash_entry] == 0)
278   {  
279     DEBUG(0,("PANIC ERROR:del_share_mode hash bucket %d empty\n", 
280                   hash_entry));
281     return;
282   }  
283   
284   file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
285   file_prev_p = file_scanner_p;
286
287   while(file_scanner_p)
288   {
289     if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
290     {
291       found = True;
292       break;
293     }
294     else
295     {
296       file_prev_p = file_scanner_p ;
297       file_scanner_p = (share_mode_record *)
298                         shmops->offset2addr(file_scanner_p->next_offset);
299     }
300   }
301     
302   if(!found)
303   {
304      DEBUG(0,("ERROR: del_share_mode no entry for dev %d inode %d\n",
305               dev, inode));
306      return;
307   }
308   
309   if(file_scanner_p->locking_version != LOCKING_VERSION)
310   {
311     DEBUG(0,("ERROR: del_share_modes Deleting old share mode v1 %d dev=%d ino=%d\n",
312              file_scanner_p->locking_version, dev, inode));
313     if(file_prev_p == file_scanner_p)
314       mode_array[hash_entry] = file_scanner_p->next_offset;
315     else
316       file_prev_p->next_offset = file_scanner_p->next_offset;
317     shmops->shm_free(shmops->addr2offset(file_scanner_p));
318     return;
319   }
320
321   found = False;
322   entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
323                                          file_scanner_p->share_mode_entries);
324   entry_prev_p = entry_scanner_p;
325   while(entry_scanner_p)
326   {
327     if( (pid == entry_scanner_p->e.pid) && 
328           (memcmp(&entry_scanner_p->e.time, 
329                  &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
330     {
331       found = True;
332       break;
333     }
334     else
335     {
336       entry_prev_p = entry_scanner_p;
337       entry_scanner_p = (shm_share_mode_entry *)
338                           shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
339     }
340   } 
341
342   if (found)
343   {
344     /* Decrement the number of entries in the record. */
345     file_scanner_p->num_share_mode_entries -= 1;
346
347     DEBUG(2,("del_share_modes Deleting share mode entry dev=%d ino=%d\n",
348               dev, inode));
349     if(entry_prev_p == entry_scanner_p)
350       /* We are at start of list */
351       file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
352     else
353       entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
354     shmops->shm_free(shmops->addr2offset(entry_scanner_p));
355
356     /* PARANOIA TEST */
357     if(file_scanner_p->num_share_mode_entries < 0)
358     {
359       DEBUG(0,("PANIC ERROR:del_share_mode num_share_mode_entries=%d\n", 
360                file_scanner_p->num_share_mode_entries));
361       return;
362     }
363
364     /* If we deleted the last share mode entry then remove the share mode record. */
365     if(file_scanner_p->num_share_mode_entries == 0)
366     {
367       DEBUG(2,("del_share_modes num entries = 0, deleting share_mode dev=%d ino=%d\n", 
368                dev, inode));
369       if(file_prev_p == file_scanner_p)
370         mode_array[hash_entry] = file_scanner_p->next_offset;
371       else
372         file_prev_p->next_offset = file_scanner_p->next_offset;
373       shmops->shm_free(shmops->addr2offset(file_scanner_p));
374     }
375   }
376   else
377   {
378     DEBUG(0,("ERROR: del_share_modes No share mode dev=%d ino=%d\n", 
379              dev, inode));
380   }
381 }
382
383 /*******************************************************************
384 set the share mode of a file. Return False on fail, True on success.
385 ********************************************************************/
386 static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
387 {
388   files_struct *fs_p = &Files[fnum];
389   int32 dev, inode;
390   int *mode_array;
391   unsigned int hash_entry;
392   share_mode_record *file_scanner_p;
393   share_mode_record *file_prev_p;
394   shm_share_mode_entry *new_entry_p;
395   int new_entry_offset;
396   BOOL found = False;
397
398   dev = fs_p->fd_ptr->dev;
399   inode = fs_p->fd_ptr->inode;
400
401   hash_entry = HASH_ENTRY(dev, inode);
402
403   mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
404
405   file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
406   file_prev_p = file_scanner_p;
407   
408   while(file_scanner_p)
409   {
410     if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
411     {
412       found = True;
413       break;
414     }
415     else
416     {
417       file_prev_p = file_scanner_p ;
418       file_scanner_p = (share_mode_record *)
419                          shmops->offset2addr(file_scanner_p->next_offset);
420     }
421   }
422   
423   if(!found)
424   {
425     /* We must create a share_mode_record */
426     share_mode_record *new_mode_p = NULL;
427     int new_offset = shmops->shm_alloc(sizeof(share_mode_record) +
428                                    strlen(fs_p->name) + 1);
429     if(new_offset == 0) {
430             DEBUG(0,("ERROR:set_share_mode shmops->shm_alloc fail!\n"));
431             return False;
432     }
433     new_mode_p = shmops->offset2addr(new_offset);
434     new_mode_p->locking_version = LOCKING_VERSION;
435     new_mode_p->st_dev = dev;
436     new_mode_p->st_ino = inode;
437     new_mode_p->num_share_mode_entries = 0;
438     new_mode_p->share_mode_entries = 0;
439     strcpy(new_mode_p->file_name, fs_p->name);
440
441     /* Chain onto the start of the hash chain (in the hope we will be used first). */
442     new_mode_p->next_offset = mode_array[hash_entry];
443     mode_array[hash_entry] = new_offset;
444
445     file_scanner_p = new_mode_p;
446
447     DEBUG(3,("set_share_mode: Created share record for %s (dev %d inode %d)\n", 
448              fs_p->name, dev, inode));
449   }
450  
451   /* Now create the share mode entry */ 
452   new_entry_offset = shmops->shm_alloc(sizeof(shm_share_mode_entry));
453   if(new_entry_offset == 0) {
454           int delete_offset = mode_array[hash_entry];
455           DEBUG(0,("ERROR:set_share_mode: shmops->shm_alloc fail 1!\n"));
456           /* Unlink the damaged record */
457           mode_array[hash_entry] = file_scanner_p->next_offset;
458           /* And delete it */
459           shmops->shm_free( delete_offset );
460           return False;
461   }
462
463   new_entry_p = shmops->offset2addr(new_entry_offset);
464
465   new_entry_p->e.pid = getpid();
466   new_entry_p->e.share_mode = fs_p->share_mode;
467   new_entry_p->e.op_port = port;
468   new_entry_p->e.op_type = op_type;
469   memcpy( (char *)&new_entry_p->e.time, (char *)&fs_p->open_time, sizeof(struct timeval));
470
471   /* Chain onto the share_mode_record */
472   new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries;
473   file_scanner_p->share_mode_entries = new_entry_offset;
474
475   /* PARANOIA TEST */
476   if(file_scanner_p->num_share_mode_entries < 0)
477   {
478     DEBUG(0,("PANIC ERROR:set_share_mode num_share_mode_entries=%d\n", 
479              file_scanner_p->num_share_mode_entries));
480     return False;
481   }
482
483   /* Increment the share_mode_entries counter */
484   file_scanner_p->num_share_mode_entries += 1;
485
486   DEBUG(3,("set_share_mode: Created share entry for %s with mode 0x%X pid=%d\n",
487            fs_p->name, fs_p->share_mode, new_entry_p->e.pid));
488
489   return(True);
490 }
491
492 /*******************************************************************
493 Remove an oplock port and mode entry from a share mode.
494 ********************************************************************/
495 static BOOL shm_remove_share_oplock(int fnum, int token)
496 {
497   uint32 dev, inode;
498   int *mode_array;
499   unsigned int hash_entry;
500   share_mode_record *file_scanner_p;
501   share_mode_record *file_prev_p;
502   shm_share_mode_entry *entry_scanner_p;
503   shm_share_mode_entry *entry_prev_p;
504   BOOL found = False;
505   int pid = getpid();
506
507   dev = Files[fnum].fd_ptr->dev;
508   inode = Files[fnum].fd_ptr->inode;
509
510   hash_entry = HASH_ENTRY(dev, inode);
511
512   mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
513
514   if(mode_array[hash_entry] == 0)
515   {
516     DEBUG(0,("PANIC ERROR:remove_share_oplock: hash bucket %d empty\n",
517                   hash_entry));
518     return False;
519   } 
520     
521   file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
522   file_prev_p = file_scanner_p;
523     
524   while(file_scanner_p)
525   { 
526     if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
527     {
528       found = True;
529       break;
530     }
531     else
532     {
533       file_prev_p = file_scanner_p ;
534       file_scanner_p = (share_mode_record *)
535                         shmops->offset2addr(file_scanner_p->next_offset);
536     }
537   } 
538    
539   if(!found)
540   { 
541      DEBUG(0,("ERROR:remove_share_oplock: no entry found for dev=%d ino=%d\n", 
542               dev, inode));
543      return False;
544   } 
545
546   if(file_scanner_p->locking_version != LOCKING_VERSION)
547   {
548     DEBUG(0,("ERROR: remove_share_oplock: Deleting old share mode v1=%d dev=%d ino=%d\n",
549              file_scanner_p->locking_version, dev, inode));
550     if(file_prev_p == file_scanner_p)
551       mode_array[hash_entry] = file_scanner_p->next_offset;
552     else
553       file_prev_p->next_offset = file_scanner_p->next_offset;
554     shmops->shm_free(shmops->addr2offset(file_scanner_p));
555     return False;
556   }
557
558   found = False;
559   entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
560                                          file_scanner_p->share_mode_entries);
561   entry_prev_p = entry_scanner_p;
562   while(entry_scanner_p)
563   {
564     if( (pid == entry_scanner_p->e.pid) && 
565         (entry_scanner_p->e.share_mode == Files[fnum].share_mode) &&
566         (memcmp(&entry_scanner_p->e.time, 
567                 &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
568     {
569       /* Delete the oplock info. */
570       entry_scanner_p->e.op_port = 0;
571       entry_scanner_p->e.op_type = 0;
572       found = True;
573       break;
574     }
575     else
576     {
577       entry_prev_p = entry_scanner_p;
578       entry_scanner_p = (shm_share_mode_entry *)
579                           shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
580     }
581   } 
582
583   if(!found)
584   {
585     DEBUG(0,("ERROR: remove_share_oplock: No oplock granted. dev=%d ino=%d\n", 
586              dev, inode));
587     return False;
588   }
589
590   return True;
591 }
592
593
594 /*******************************************************************
595 call the specified function on each entry under management by the
596 share mode system
597 ********************************************************************/
598 static int shm_share_forall(void (*fn)(share_mode_entry *, char *))
599 {
600         int i, count=0;
601         int *mode_array;
602         share_mode_record *file_scanner_p;
603
604         mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
605
606         for( i = 0; i < shmops->hash_size(); i++) {
607                 shmops->lock_hash_entry(i);
608                 if(mode_array[i] == 0)  {
609                         shmops->unlock_hash_entry(i);
610                         continue;
611                 }
612
613                 file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[i]);
614                 while((file_scanner_p != 0) && 
615                       (file_scanner_p->num_share_mode_entries != 0)) {
616                         shm_share_mode_entry *entry_scanner_p = 
617                                 (shm_share_mode_entry *)
618                                 shmops->offset2addr(file_scanner_p->share_mode_entries);
619
620                         while(entry_scanner_p != 0) {
621                                 
622                                 if (process_exists(entry_scanner_p->e.pid)) {
623                                         fn(&entry_scanner_p->e, 
624                                            file_scanner_p->file_name);
625                                         count++;
626                                 }
627
628                                 entry_scanner_p = 
629                                         (shm_share_mode_entry *)
630                                         shmops->offset2addr(
631                                                             entry_scanner_p->next_share_mode_entry);
632                         } /* end while entry_scanner_p */
633                         file_scanner_p = (share_mode_record *)
634                                 shmops->offset2addr(file_scanner_p->next_offset);
635                 } /* end while file_scanner_p */
636                 shmops->unlock_hash_entry(i);
637         } /* end for */
638
639         return count;
640 }
641
642
643 /*******************************************************************
644 dump the state of the system
645 ********************************************************************/
646 static void shm_share_status(FILE *f)
647 {
648         int bytes_free, bytes_used, bytes_overhead, bytes_total;
649
650         shmops->get_usage(&bytes_free, &bytes_used, &bytes_overhead);
651         bytes_total = bytes_free + bytes_used + bytes_overhead;
652
653         fprintf(f, "Share mode memory usage (bytes):\n");
654         fprintf(f, "   %d(%d%%) free + %d(%d%%) used + %d(%d%%) overhead = %d(100%%) total\n",
655                 bytes_free, (bytes_free * 100)/bytes_total,
656                 bytes_used, (bytes_used * 100)/bytes_total,
657                 bytes_overhead, (bytes_overhead * 100)/bytes_total,
658                 bytes_total);
659 }
660
661
662 static struct share_ops share_ops = {
663         shm_stop_share_mode_mgmt,
664         shm_lock_share_entry,
665         shm_unlock_share_entry,
666         shm_get_share_modes,
667         shm_del_share_mode,
668         shm_set_share_mode,
669         shm_remove_share_oplock,
670         shm_share_forall,
671         shm_share_status,
672 };
673
674 /*******************************************************************
675   initialize the shared memory for share_mode management 
676   ******************************************************************/
677 struct share_ops *locking_shm_init(int ronly)
678 {
679         read_only = ronly;
680
681 #ifdef USE_SYSV_IPC
682         shmops = sysv_shm_open(read_only);
683         if (shmops) return &share_ops;
684 #endif
685
686         shmops = smb_shm_open(read_only);
687         if (shmops) return &share_ops;
688
689         return NULL;
690 }
691
692 #else
693  int locking_shm_dummy_procedure(void)
694 {return 0;}
695 #endif
696
697
698