struct dm_hash_table *dm_hash_create(unsigned size_hint) { size_t len; unsigned new_size = 16u; struct dm_hash_table *hc = dm_zalloc(sizeof(*hc)); if (!hc) return_0; /* round size hint up to a power of two */ while (new_size < size_hint) new_size = new_size << 1; hc->num_slots = new_size; len = sizeof(*(hc->slots)) * new_size; if (!(hc->slots = dm_malloc(len))) { stack; goto bad; } memset(hc->slots, 0, len); return hc; bad: dm_free(hc->slots); dm_free(hc); return 0; }
/* Real locking */ static int _lock_resource(const char *resource, int mode, int flags, int *lockid) { struct lock *lck; DEBUGLOG("Locking resource %s, flags=%d, mode=%d\n", resource, flags, mode); mode &= LCK_TYPE_MASK; pthread_mutex_lock(&_lock_mutex); retry: if (!(lck = dm_hash_lookup(_locks, resource))) { /* Add new locked resource */ if (!(lck = dm_zalloc(sizeof(struct lock))) || !dm_hash_insert(_locks, resource, lck)) goto bad; lck->lockid = ++_lockid; goto out; } /* Update/convert lock */ if (flags == LCKF_CONVERT) { if (lck->excl) mode = LCK_EXCL; } else if ((lck->mode == LCK_WRITE) || (lck->mode == LCK_EXCL)) { DEBUGLOG("Resource %s already %s locked (%d)...\n", resource, (lck->mode == LCK_WRITE) ? "write" : "exclusively", lck->lockid); goto maybe_retry; } else if (lck->mode > mode) { DEBUGLOG("Resource %s already locked and %s lock requested...\n", resource, (mode == LCK_READ) ? "READ" : (mode == LCK_WRITE) ? "WRITE" : "EXCLUSIVE"); goto maybe_retry; } out: *lockid = lck->lockid; lck->mode = mode; lck->excl |= (mode == LCK_EXCL); DEBUGLOG("Locked resource %s, lockid=%d, mode=%d\n", resource, lck->lockid, mode); pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */ pthread_mutex_unlock(&_lock_mutex); return 0; maybe_retry: if (!(flags & LCK_NONBLOCK)) { pthread_cond_wait(&_lock_cond, &_lock_mutex); DEBUGLOG("Resource %s RETRYING lock...\n", resource); goto retry; } bad: DEBUGLOG("Failed to lock resource %s\n", resource); pthread_mutex_unlock(&_lock_mutex); return 1; /* fail */ }
struct dm_timestamp *dm_timestamp_alloc(void) { struct dm_timestamp *ts = NULL; if (!(ts = dm_zalloc(sizeof(*ts)))) stack; return ts; }
struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint) { size_t new_size = 1024; struct dm_pool *p = dm_zalloc(sizeof(*p)); if (!p) { log_error("Couldn't create memory pool %s (size %" PRIsize_t ")", name, sizeof(*p)); return 0; } p->name = name; /* round chunk_hint up to the next power of 2 */ p->chunk_size = chunk_hint + sizeof(struct chunk); while (new_size < p->chunk_size) new_size <<= 1; p->chunk_size = new_size; dm_list_add(&_dm_pools, &p->list); return p; }
static int add_internal_client(int fd, fd_callback_t callback) { struct local_client *client; DEBUGLOG("Add_internal_client, fd = %d\n", fd); if (!(client = dm_zalloc(sizeof(*client)))) { DEBUGLOG("malloc failed\n"); return -1; } client->fd = fd; client->type = CLUSTER_INTERNAL; client->callback = callback; add_client(client); /* Set Close-on-exec */ fcntl(fd, F_SETFD, 1); return 0; }
struct dev_types *create_dev_types(const char *proc_dir, const struct dm_config_node *cn) { struct dev_types *dt; char line[80]; char proc_devices[PATH_MAX]; FILE *pd = NULL; int i, j = 0; int line_maj = 0; int blocksection = 0; size_t dev_len = 0; const struct dm_config_value *cv; const char *name; char *nl; if (!(dt = dm_zalloc(sizeof(struct dev_types)))) { log_error("Failed to allocate device type register."); return NULL; } if (!*proc_dir) { log_verbose("No proc filesystem found: using all block device types"); for (i = 0; i < NUMBER_OF_MAJORS; i++) dt->dev_type_array[i].max_partitions = 1; return dt; } if (dm_snprintf(proc_devices, sizeof(proc_devices), "%s/devices", proc_dir) < 0) { log_error("Failed to create /proc/devices string"); goto bad; } if (!(pd = fopen(proc_devices, "r"))) { log_sys_error("fopen", proc_devices); goto bad; } while (fgets(line, sizeof(line), pd) != NULL) { i = 0; while (line[i] == ' ') i++; /* If it's not a number it may be name of section */ line_maj = atoi(((char *) (line + i))); if (line_maj < 0 || line_maj >= NUMBER_OF_MAJORS) { /* * Device numbers shown in /proc/devices are actually direct * numbers passed to registering function, however the kernel * uses only 12 bits, so use just 12 bits for major. */ if ((nl = strchr(line, '\n'))) *nl = '\0'; log_warn("WARNING: /proc/devices line: %s, replacing major with %d.", line, line_maj & (NUMBER_OF_MAJORS - 1)); line_maj &= (NUMBER_OF_MAJORS - 1); } if (!line_maj) { blocksection = (line[i] == 'B') ? 1 : 0; continue; } /* We only want block devices ... */ if (!blocksection) continue; /* Find the start of the device major name */ while (line[i] != ' ' && line[i] != '\0') i++; while (line[i] == ' ') i++; /* Look for md device */ if (!strncmp("md", line + i, 2) && isspace(*(line + i + 2))) dt->md_major = line_maj; /* Look for blkext device */ if (!strncmp("blkext", line + i, 6) && isspace(*(line + i + 6))) dt->blkext_major = line_maj; /* Look for drbd device */ if (!strncmp("drbd", line + i, 4) && isspace(*(line + i + 4))) dt->drbd_major = line_maj; /* Look for DASD */ if (!strncmp("dasd", line + i, 4) && isspace(*(line + i + 4))) dt->dasd_major = line_maj; /* Look for EMC powerpath */ if (!strncmp("emcpower", line + i, 8) && isspace(*(line + i + 8))) dt->emcpower_major = line_maj; if (!strncmp("power2", line + i, 6) && isspace(*(line + i + 6))) dt->power2_major = line_maj; /* Look for device-mapper device */ /* FIXME Cope with multiple majors */ if (!strncmp("device-mapper", line + i, 13) && isspace(*(line + i + 13))) dt->device_mapper_major = line_maj; /* Major is SCSI device */ if (!strncmp("sd", line + i, 2) && isspace(*(line + i + 2))) dt->dev_type_array[line_maj].flags |= PARTITION_SCSI_DEVICE; /* Go through the valid device names and if there is a match store max number of partitions */ for (j = 0; _dev_known_types[j].name[0]; j++) { dev_len = strlen(_dev_known_types[j].name); if (dev_len <= strlen(line + i) && !strncmp(_dev_known_types[j].name, line + i, dev_len) && (line_maj < NUMBER_OF_MAJORS)) { dt->dev_type_array[line_maj].max_partitions = _dev_known_types[j].max_partitions; break; } } if (!cn) continue; /* Check devices/types for local variations */ for (cv = cn->v; cv; cv = cv->next) { if (cv->type != DM_CFG_STRING) { log_error("Expecting string in devices/types " "in config file"); if (fclose(pd)) log_sys_error("fclose", proc_devices); goto bad; } dev_len = strlen(cv->v.str); name = cv->v.str; cv = cv->next; if (!cv || cv->type != DM_CFG_INT) { log_error("Max partition count missing for %s " "in devices/types in config file", name); if (fclose(pd)) log_sys_error("fclose", proc_devices); goto bad; } if (!cv->v.i) { log_error("Zero partition count invalid for " "%s in devices/types in config file", name); if (fclose(pd)) log_sys_error("fclose", proc_devices); goto bad; } if (dev_len <= strlen(line + i) && !strncmp(name, line + i, dev_len) && (line_maj < NUMBER_OF_MAJORS)) { dt->dev_type_array[line_maj].max_partitions = cv->v.i; break; } } } if (fclose(pd)) log_sys_error("fclose", proc_devices); return dt; bad: dm_free(dt); return NULL; }