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;
}
Ejemplo n.º 2
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 */
}
Ejemplo n.º 3
0
struct dm_timestamp *dm_timestamp_alloc(void)
{
	struct dm_timestamp *ts = NULL;

	if (!(ts = dm_zalloc(sizeof(*ts))))
		stack;

	return ts;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
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;
}