summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/locking_shm.c51
-rw-r--r--source3/locking/shmem.c48
-rw-r--r--source3/locking/shmem_sysv.c70
3 files changed, 88 insertions, 81 deletions
diff --git a/source3/locking/locking_shm.c b/source3/locking/locking_shm.c
index 3abd6b25a7..d299e34caa 100644
--- a/source3/locking/locking_shm.c
+++ b/source3/locking/locking_shm.c
@@ -64,7 +64,7 @@ static int read_only;
/* Conversion to hash entry index from device and inode numbers. */
-#define HASH_ENTRY(dev,ino) ((( (uint32)(dev) )* ( (uint32)(ino) )) % lp_shmem_hash_size())
+#define HASH_ENTRY(dev,ino) ((((uint32)(dev)) * ((uint32)(ino))) % shmops->hash_size())
/*******************************************************************
@@ -110,15 +110,6 @@ static int shm_get_share_modes(int cnum, int token, uint32 dev, uint32 inode,
*old_shares = 0;
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR : get_share_modes (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return 0;
- }
-
mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
if(mode_array[hash_entry] == NULL_OFFSET)
@@ -289,15 +280,6 @@ static void shm_del_share_mode(int token, int fnum)
hash_entry = HASH_ENTRY(dev, inode);
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return;
- }
-
mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
if(mode_array[hash_entry] == NULL_OFFSET)
@@ -428,14 +410,6 @@ static BOOL shm_set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
inode = fs_p->fd_ptr->inode;
hash_entry = HASH_ENTRY(dev, inode);
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return False;
- }
mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
@@ -550,15 +524,6 @@ static BOOL shm_remove_share_oplock(int fnum, int token)
hash_entry = HASH_ENTRY(dev, inode);
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR:remove_share_oplock (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return False;
- }
-
mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
if(mode_array[hash_entry] == NULL_OFFSET)
@@ -654,7 +619,7 @@ static int shm_share_forall(void (*fn)(share_mode_entry *, char *))
mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
- for( i = 0; i < lp_shmem_hash_size(); i++) {
+ for( i = 0; i < shmops->hash_size(); i++) {
shmops->lock_hash_entry(i);
if(mode_array[i] == NULL_OFFSET) {
shmops->unlock_hash_entry(i);
@@ -730,19 +695,11 @@ struct share_ops *locking_shm_init(int ronly)
read_only = ronly;
#ifdef USE_SYSV_IPC
- shmops = sysv_shm_open(lp_shmem_size(), read_only);
+ shmops = sysv_shm_open(read_only);
if (shmops) return &share_ops;
#endif
- pstrcpy(shmem_file_name,lp_lockdir());
- if (!directory_exist(shmem_file_name,NULL)) {
- if (read_only) return NULL;
- mkdir(shmem_file_name,0755);
- }
- trim_string(shmem_file_name,"","/");
- if (!*shmem_file_name) return(False);
- strcat(shmem_file_name, "/SHARE_MEM_FILE");
- shmops = smb_shm_open(shmem_file_name, lp_shmem_size(), read_only);
+ shmops = smb_shm_open(read_only);
if (shmops) return &share_ops;
return NULL;
diff --git a/source3/locking/shmem.c b/source3/locking/shmem.c
index 72d7c07751..909e8dd435 100644
--- a/source3/locking/shmem.c
+++ b/source3/locking/shmem.c
@@ -41,6 +41,9 @@ extern int DEBUGLEVEL;
#define SHM_FILE_MODE 0644
#endif
+#define SHMEM_HASH_SIZE 113
+
+
/* WARNING : offsets are used because mmap() does not guarantee that all processes have the
shared memory mapped to the same address */
@@ -653,12 +656,6 @@ static BOOL smb_shm_lock_hash_entry( unsigned int entry)
return False;
}
- if(entry >= lp_shmem_hash_size())
- {
- DEBUG(0,("ERROR smb_shm_lock_hash_entry : hash entry size too big (%d)\n", entry));
- return False;
- }
-
/* Do an exclusive wait lock on the 4 byte region mapping into this entry */
if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(int), F_WRLCK) == False)
{
@@ -683,12 +680,6 @@ static BOOL smb_shm_unlock_hash_entry( unsigned int entry )
return False;
}
- if(entry >= lp_shmem_hash_size())
- {
- DEBUG(0,("ERROR smb_shm_unlock_hash_entry : hash entry size too big (%d)\n", entry));
- return False;
- }
-
/* Do a wait lock on the 4 byte region mapping into this entry */
if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(int), F_UNLCK) == False)
{
@@ -720,6 +711,13 @@ static BOOL smb_shm_get_usage(int *bytes_free,
return True;
}
+/*******************************************************************
+hash a number into a hash_entry
+ ******************************************************************/
+static unsigned smb_shm_hash_size(void)
+{
+ return SHMEM_HASH_SIZE;
+}
static struct shmem_ops shmops = {
smb_shm_close,
@@ -731,18 +729,30 @@ static struct shmem_ops shmops = {
smb_shm_lock_hash_entry,
smb_shm_unlock_hash_entry,
smb_shm_get_usage,
+ smb_shm_hash_size,
};
/*******************************************************************
open the shared memory
******************************************************************/
-struct shmem_ops *smb_shm_open(char *file_name, int size, int ronly)
+struct shmem_ops *smb_shm_open(int ronly)
{
- int filesize;
- BOOL created_new = False;
- BOOL other_processes = True;
-
- read_only = ronly;
+ pstring file_name;
+ int filesize;
+ BOOL created_new = False;
+ BOOL other_processes = True;
+ int size = lp_shmem_size();
+
+ read_only = ronly;
+
+ pstrcpy(file_name,lp_lockdir());
+ if (!directory_exist(file_name,NULL)) {
+ if (read_only) return NULL;
+ mkdir(file_name,0755);
+ }
+ trim_string(file_name,"","/");
+ if (!*file_name) return(False);
+ strcat(file_name, "/SHARE_MEM_FILE");
DEBUG(5,("smb_shm_open : using shmem file %s to be of size %d\n",file_name,size));
@@ -840,7 +850,7 @@ struct shmem_ops *smb_shm_open(char *file_name, int size, int ronly)
{
smb_shm_initialize(size);
/* Create the hash buckets for the share file entries. */
- smb_shm_create_hash_table( lp_shmem_hash_size() );
+ smb_shm_create_hash_table(SHMEM_HASH_SIZE);
}
else if (!smb_shm_validate_header(size) )
{
diff --git a/source3/locking/shmem_sysv.c b/source3/locking/shmem_sysv.c
index 36d0cca27f..e3f40418d9 100644
--- a/source3/locking/shmem_sysv.c
+++ b/source3/locking/shmem_sysv.c
@@ -39,6 +39,14 @@ extern int DEBUGLEVEL;
#define IPC_PERMS 0644
#endif
+#ifdef SEMMSL
+#define SHMEM_HASH_SIZE (SEMMSL-1)
+#else
+#define SHMEM_HASH_SIZE 63
+#endif
+
+#define MIN_SHM_SIZE 10240
+
static int shm_id;
static int sem_id;
static int shm_size;
@@ -487,6 +495,16 @@ static BOOL shm_get_usage(int *bytes_free,
return True;
}
+
+/*******************************************************************
+hash a number into a hash_entry
+ ******************************************************************/
+static unsigned shm_hash_size(void)
+{
+ return hash_size;
+}
+
+
static struct shmem_ops shmops = {
shm_close,
shm_alloc,
@@ -497,12 +515,13 @@ static struct shmem_ops shmops = {
shm_lock_hash_entry,
shm_unlock_hash_entry,
shm_get_usage,
+ shm_hash_size,
};
/*******************************************************************
open the shared memory
******************************************************************/
-struct shmem_ops *sysv_shm_open(int size, int ronly)
+struct shmem_ops *sysv_shm_open(int ronly)
{
BOOL created_new = False;
BOOL other_processes;
@@ -513,17 +532,23 @@ struct shmem_ops *sysv_shm_open(int size, int ronly)
read_only = ronly;
- shm_size = size;
+ shm_size = lp_shmem_size();
- DEBUG(4,("Trying sysv shmem open of size %d\n", size));
+ DEBUG(4,("Trying sysv shmem open of size %d\n", shm_size));
/* first the semaphore */
sem_id = semget(SEMAPHORE_KEY, 0, 0);
if (sem_id == -1) {
if (read_only) return NULL;
- sem_id = semget(SEMAPHORE_KEY, lp_shmem_hash_size()+1,
- IPC_CREAT | IPC_EXCL | IPC_PERMS);
+ hash_size = SHMEM_HASH_SIZE;
+
+ while (hash_size > 1) {
+ sem_id = semget(SEMAPHORE_KEY, hash_size+1,
+ IPC_CREAT | IPC_EXCL | IPC_PERMS);
+ if (sem_id != -1 || errno != EINVAL) break;
+ hash_size--;
+ }
if (sem_id == -1) {
DEBUG(0,("Can't create or use semaphore %s\n",
@@ -532,7 +557,7 @@ struct shmem_ops *sysv_shm_open(int size, int ronly)
if (sem_id != -1) {
su.val = 1;
- for (i=0;i<lp_shmem_hash_size()+1;i++) {
+ for (i=0;i<hash_size+1;i++) {
if (semctl(sem_id, i, SETVAL, su) != 0) {
DEBUG(1,("Failed to init semaphore %d\n", i));
}
@@ -552,10 +577,16 @@ struct shmem_ops *sysv_shm_open(int size, int ronly)
if (semctl(sem_id, 0, IPC_STAT, su) != 0) {
DEBUG(0,("ERROR shm_open : can't IPC_STAT\n"));
}
- hash_size = sem_ds.sem_nsems;
- if (hash_size != lp_shmem_hash_size()+1) {
- DEBUG(0,("WARNING: nsems=%d\n", hash_size));
+ hash_size = sem_ds.sem_nsems-1;
+
+ if (!read_only) {
+ if (sem_ds.sem_perm.cuid != 0 || sem_ds.sem_perm.cgid != 0) {
+ DEBUG(0,("ERROR: root did not create the semaphore\n"));
+ return NULL;
+ }
}
+
+
if (!global_lock())
return NULL;
@@ -566,7 +597,12 @@ struct shmem_ops *sysv_shm_open(int size, int ronly)
/* if that failed then create one */
if (shm_id == -1) {
if (read_only) return NULL;
- shm_id = shmget(SHMEM_KEY, shm_size, IPC_CREAT | IPC_EXCL);
+ while (shm_size > MIN_SHM_SIZE) {
+ shm_id = shmget(SHMEM_KEY, shm_size,
+ IPC_CREAT | IPC_EXCL | IPC_PERMS);
+ if (shm_id != -1 || errno != EINVAL) break;
+ shm_size *= 0.9;
+ }
created_new = (shm_id != -1);
}
@@ -592,19 +628,23 @@ struct shmem_ops *sysv_shm_open(int size, int ronly)
DEBUG(0,("ERROR shm_open : can't IPC_STAT\n"));
}
- /* set the permissions */
if (!read_only) {
- shm_ds.shm_perm.mode = IPC_PERMS;
- shmctl(shm_id, IPC_SET, &shm_ds);
+ if (shm_ds.shm_perm.cuid != 0 || shm_ds.shm_perm.cgid != 0) {
+ DEBUG(0,("ERROR: root did not create the shmem\n"));
+ global_unlock();
+ return NULL;
+ }
}
+ shm_size = shm_ds.shm_segsz;
+
other_processes = (shm_ds.shm_nattch > 1);
if (!read_only && !other_processes) {
memset((char *)shm_header_p, 0, shm_size);
shm_initialize(shm_size);
- shm_create_hash_table(lp_shmem_hash_size());
- DEBUG(1,("Initialised IPC area of size %d\n", shm_size));
+ shm_create_hash_table(hash_size);
+ DEBUG(3,("Initialised IPC area of size %d\n", shm_size));
} else if (!shm_validate_header(shm_size)) {
/* existing file is corrupt, samba admin should remove
it by hand */