Ejemplo n.º 1
0
static int _error_device(const char *name, size_t size)
{
	struct dm_task *dmt;
	int r = 0;

	if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
		return 0;

	if (!dm_task_set_name(dmt, name))
		goto error;

	if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))
		goto error;

	if (!dm_task_set_ro(dmt))
		goto error;

	if (!dm_task_no_open_count(dmt))
		goto error;

	if (!dm_task_run(dmt))
		goto error;

	if (!_dm_simple(DM_DEVICE_RESUME, name, 1)) {
		_dm_simple(DM_DEVICE_CLEAR, name, 0);
		goto error;
	}

	r = 1;

error:
	dm_task_destroy(dmt);
	return r;
}
Ejemplo n.º 2
0
/*
 * Parse a mapping table and create the appropriate targets or
 * check that a target type is registered with the device-mapper core.
 */
static int
handle_table(struct lib_context *lc, struct dm_task *dmt,
	     char *table, struct dm_versions *targets)
{
	int line = 0, n, ret = 0;
	uint64_t start, size;
	char *nl = table, *p, ttype[32];

	do {
		p = nl;
		line++;

		/*
		 * Not using sscanf string allocation
		 * because it's not available in dietlibc.
		 */
		*ttype = 0;
		if (sscanf(p, "%" PRIu64 " %" PRIu64 " %31s %n",
			   &start, &size, ttype, &n) < 3)
			LOG_ERR(lc, 0, "Invalid format in table line %d", line);

		if (!(ret = valid_ttype(lc, ttype, targets)))
			break;

		nl = remove_delimiter((p += n), '\n');
		if (dmt)
			ret = dm_task_add_target(dmt, start, size, ttype, p);

		add_delimiter(&nl, '\n');
	} while (nl && ret);

	return ret;
}
Ejemplo n.º 3
0
Archivo: dm.c Proyecto: radii/dmsteg
int dm_mount_aspect(substrate_t *substrate, u64 header_offset, u8 *header_key, char *name)
{
	char *params;
	struct dm_task *task;
	task = dm_task_create(DM_DEVICE_CREATE);
	if(!task) {
		die("dm_task_create");
	}
	if(!dm_task_set_name(task, name)) {
		die("dm_task_set_name");
	}
	if(!dm_task_set_uuid(task, name)) {
		die("dm_task_set_uuid");
	}
	params = steg_malloc(strlen(substrate->filename) + 4096);
	sprintf(params, "%s %zu ", substrate->filename, header_offset);
	sprint_hex(params + strlen(params), header_key, KEY_BYTES);
	if(!dm_task_add_target(task, 0, substrate->bytes, "steg", params)) {
		die("dm_task_add_target");
	}
	if(!dm_task_run(task)) {
		die("dm_task_run");
	}
	dm_task_destroy(task);
	steg_free(params);
	return 0;
}
Ejemplo n.º 4
0
int dm_addmap(int task, const char *name, const char *target,
	      const char *params, uint64_t size, int ro, const char *uuid,
	      int part, mode_t mode, uid_t uid, gid_t gid)
{
	int r = 0;
	struct dm_task *dmt;
	char *prefixed_uuid = NULL;
#ifdef LIBDM_API_COOKIE
	uint32_t cookie = 0;
	uint16_t udev_flags = 0;
#endif

	if (!(dmt = dm_task_create (task)))
		return 0;

	if (!dm_task_set_name (dmt, name))
		goto addout;

	if (!dm_task_add_target (dmt, 0, size, target, params))
		goto addout;

	if (ro && !dm_task_set_ro (dmt))
			goto addout;

	if (task == DM_DEVICE_CREATE && uuid) {
		prefixed_uuid = make_prefixed_uuid(part, uuid);
		if (prefixed_uuid == NULL)
			goto addout;
		if (!dm_task_set_uuid(dmt, prefixed_uuid))
			goto addout;
	}

	if (!dm_task_set_mode(dmt, mode))
		goto addout;
	if (!dm_task_set_uid(dmt, uid))
		goto addout;
	if (!dm_task_set_gid(dmt, gid))
		goto addout;

	dm_task_no_open_count(dmt);

#ifdef LIBDM_API_COOKIE
	if (!udev_sync)
		udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
	if (task == DM_DEVICE_CREATE &&
	    !dm_task_set_cookie(dmt, &cookie, udev_flags))
		goto addout;
#endif
	r = dm_task_run (dmt);
#ifdef LIBDM_API_COOKIE
	if (task == DM_DEVICE_CREATE)
			dm_udev_wait(cookie);
#endif
addout:
	dm_task_destroy (dmt);
	free(prefixed_uuid);

	return r;
}
Ejemplo n.º 5
0
static int _dm_create(int task, int wait,
                      const char *name, const char *uuid,
                      uint64_t start, uint64_t length,
                      const char *target, const char *table,
                      struct era_dm_info *info)
{
	struct dm_task *dmt;
	uint32_t cookie = 0;
	int rc;

	if (!(dmt = dm_task_create(task)))
		return -1;

	if (!dm_task_set_name(dmt, name))
		goto out;

	if (uuid && !dm_task_set_uuid(dmt, uuid))
		goto out;

	if (target && !dm_task_add_target(dmt, start, length, target, table))
		goto out;

	if (wait && !dm_task_set_cookie(dmt, &cookie, 0))
		goto out;

	rc = dm_task_run(dmt);

	if (wait)
		(void) dm_udev_wait(cookie);

	if (rc && info)
	{
		struct dm_info dmi;

		if (!dm_task_get_info(dmt, &dmi))
			goto out;

		info->target_count = dmi.target_count;
		info->open_count = dmi.open_count;
		info->suspended = dmi.suspended;
		info->exists = dmi.exists;
		info->major = dmi.major;
		info->minor = dmi.minor;
	}

	dm_task_destroy(dmt);

	return rc ? 0 : -1;
out:
	dm_task_destroy(dmt);
	return -1;
}
Ejemplo n.º 6
0
/*
 * Create device via device mapper
 * return 0 when creation failed
 * return dev no for created device
 */
static uint64_t
dm_device_create_mapped(const char *dev_name, struct bl_dm_table *p)
{
	struct dm_task *dmt;
	struct dm_info dminfo;
	int ret = 0;

	dmt = dm_task_create(DM_DEVICE_CREATE);
	if (!dmt) {
		BL_LOG_ERR("Create dm_task for %s failed\n", dev_name);
		return 0;
	}
	ret = dm_task_set_name(dmt, dev_name);
	if (!ret)
		goto err_out;

	while (p) {
		ret =
		    dm_task_add_target(dmt, p->offset, p->size, p->target_type,
				       p->params);
		if (!ret)
			goto err_out;
		p = p->next;
	}

	ret = dm_task_run(dmt) && dm_task_get_info(dmt, &dminfo)
	    && dminfo.exists;

	if (!ret)
		goto err_out;

	dm_task_update_nodes();

 err_out:
	dm_task_destroy(dmt);

	if (!ret) {
		BL_LOG_ERR("Create device %s failed\n", dev_name);
		return 0;
	}
	return MKDEV(dminfo.major, dminfo.minor);
}
/* Unmarshall the target info returned from a status call */
static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi)
{
	char *outbuf = (char *) dmi + dmi->data_start;
	char *outptr = outbuf;
	uint32_t i;
	struct dm_target_spec *spec;

	for (i = 0; i < dmi->target_count; i++) {
		spec = (struct dm_target_spec *) outptr;
		if (!dm_task_add_target(dmt, spec->sector_start,
					spec->length,
					spec->target_type,
					outptr + sizeof(*spec))) {
			return 0;
		}

		outptr = outbuf + spec->next;
	}

	return 1;
}
Ejemplo n.º 8
0
static int
dm_addmap (int task, const char *target, struct multipath *mpp,
	   char * params, int ro) {
	int r = 0;
	struct dm_task *dmt;
	char *prefixed_uuid = NULL;
	uint32_t cookie = 0;

	if (!(dmt = dm_task_create (task)))
		return 0;

	if (!dm_task_set_name (dmt, mpp->alias))
		goto addout;

	if (!dm_task_add_target (dmt, 0, mpp->size, target, params))
		goto addout;

	if (ro)
		dm_task_set_ro(dmt);

	if (task == DM_DEVICE_CREATE) {
		if (strlen(mpp->wwid) > 0) {
			prefixed_uuid = MALLOC(UUID_PREFIX_LEN +
					       strlen(mpp->wwid) + 1);
			if (!prefixed_uuid) {
				condlog(0, "cannot create prefixed uuid : %s",
					strerror(errno));
				goto addout;
			}
			sprintf(prefixed_uuid, UUID_PREFIX "%s", mpp->wwid);
			if (!dm_task_set_uuid(dmt, prefixed_uuid))
				goto freeout;
		}
		dm_task_skip_lockfs(dmt);
#ifdef LIBDM_API_FLUSH
		dm_task_no_flush(dmt);
#endif
	}

	if (mpp->attribute_flags & (1 << ATTR_MODE) &&
	    !dm_task_set_mode(dmt, mpp->mode))
		goto freeout;
	if (mpp->attribute_flags & (1 << ATTR_UID) &&
	    !dm_task_set_uid(dmt, mpp->uid))
		goto freeout;
	if (mpp->attribute_flags & (1 << ATTR_GID) &&
	    !dm_task_set_gid(dmt, mpp->gid))
		goto freeout;
	condlog(4, "%s: %s [0 %llu %s %s]", mpp->alias,
		task == DM_DEVICE_RELOAD ? "reload" : "addmap", mpp->size,
		target, params);

	dm_task_no_open_count(dmt);

	if (task == DM_DEVICE_CREATE &&
	    !dm_task_set_cookie(dmt, &cookie,
				DM_UDEV_DISABLE_LIBRARY_FALLBACK))
		goto freeout;

	r = dm_task_run (dmt);

	if (task == DM_DEVICE_CREATE)
			dm_udev_wait(cookie);
freeout:
	if (prefixed_uuid)
		FREE(prefixed_uuid);

addout:
	dm_task_destroy (dmt);

	return r;
}
Ejemplo n.º 9
0
int main(int argc, char *argv[])
  try {
    State state;
    auto parsers = new_subparser({"device"});
    argp argp = {options, init_parsers, nullptr, doc, parsers.get(), nullptr,
      nullptr};
    argp_parse(&argp, argc, argv, 0, nullptr, &state);

    Params params;

    try {
      params.load(state.device);
    } catch(const std::exception& e) {
      std::cerr << "Error: Header corrupt." << std::endl;
      return 1;
    }
    std::uint64_t blocks = state.device.size()/params.block_size;

    Pinentry pinentry;
    pinentry.SETDESC("Enter passphrases for a partition on this volume.");
    pinentry.SETPROMPT("Passphrase:");
    auto passphrase = pinentry.GETPIN();
    Superblock superblock(params, passphrase, blocks);
    try {
      superblock.load(state.device);
    } catch(...) {
      std::cerr << "Error: No partition found for that passphrase." << std::endl;
    }
    Hash hash(params.hash);
    std::string key = PBKDF2::PBKDF2(hash, passphrase, params.salt,
        params.iters, params.key_size);

    if (state.name.empty()) {
      hash.reset();
      hash.update(key);
      state.name = hex(hash.digest()).substr(8);
    }

    {
      std::unique_ptr<dm_task, void(*)(dm_task*)> dmt(
          dm_task_create(DM_DEVICE_CREATE), dm_task_destroy);
      if (!dmt.get())
        throw std::runtime_error("dm_task_create failed");
      if (!dm_task_set_name(dmt.get(), state.name.c_str()))
        throw std::runtime_error("dm_task_set_name failed");
      std::uint64_t offset = 0;
      for (auto block = superblock.blocks.begin()+superblock.offset;
          block != superblock.blocks.end();
          block++, offset += params.block_size) {
        if (*block != 0) {
          std::stringstream ss;
          ss << params.device_cipher << " " << hex(key) << " 0 ";
          ss << state.device.major() << ":" << state.device.minor() << " ";
          ss << (*block)*params.block_size/512;
          if (!dm_task_add_target(dmt.get(), offset/512, params.block_size/512,
                "crypt", ss.str().c_str()))
            throw std::runtime_error("dm_task_add_target(\"crypt\") failed");
        } else {
          if (!dm_task_add_target(dmt.get(), offset/512, params.block_size/512,
                "error", ""))
            throw std::runtime_error("dm_task_add_target(\"error\") failed");
        }
      }
      if (!dm_task_run(dmt.get()))
        throw std::runtime_error("dm_task_run failed");
    }

    return 0;
  } catch(const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
    return 1;
  }
Ejemplo n.º 10
0
int dm_create_device(const char *name,
		     const char *device,
		     const char *cipher,
		     const char *type,
		     const char *uuid,
		     uint64_t size,
		     uint64_t skip,
		     uint64_t offset,
		     size_t key_size,
		     const char *key,
		     int read_only,
		     int reload)
{
	struct dm_task *dmt = NULL;
	struct dm_info dmi;
	char *params = NULL;
	char *error = NULL;
	char dev_uuid[DM_UUID_LEN] = {0};
	int r = -EINVAL;
	uint32_t read_ahead = 0;
	uint32_t cookie = 0;
	uint16_t udev_flags = 0;

	params = get_params(device, skip, offset, cipher, key_size, key);
	if (!params)
		goto out_no_removal;

	if (type && !strncmp(type, "TEMP", 4))
		udev_flags = CRYPT_TEMP_UDEV_FLAGS;

	/* All devices must have DM_UUID, only resize on old device is exception */
	if (reload) {
		if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
			goto out_no_removal;

		if (!dm_task_set_name(dmt, name))
			goto out_no_removal;
	} else {
		dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid));

		if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
			goto out_no_removal;

		if (!dm_task_set_name(dmt, name))
			goto out_no_removal;

		if (!dm_task_set_uuid(dmt, dev_uuid))
			goto out_no_removal;

		if (_dm_use_udev() && !dm_task_set_cookie(dmt, &cookie, udev_flags))
			goto out_no_removal;
	}

	if (read_only && !dm_task_set_ro(dmt))
		goto out_no_removal;
	if (!dm_task_add_target(dmt, 0, size, DM_CRYPT_TARGET, params))
		goto out_no_removal;

#ifdef DM_READ_AHEAD_MINIMUM_FLAG
	if (_dev_read_ahead(device, &read_ahead) &&
	    !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
		goto out_no_removal;
#endif

	if (!dm_task_run(dmt))
		goto out_no_removal;

	if (reload) {
		dm_task_destroy(dmt);
		if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
			goto out;
		if (!dm_task_set_name(dmt, name))
			goto out;
		if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
			goto out;
		if (_dm_use_udev() && !dm_task_set_cookie(dmt, &cookie, udev_flags))
			goto out;
		if (!dm_task_run(dmt))
			goto out;
	}

	if (!dm_task_get_info(dmt, &dmi))
		goto out;

	r = 0;
out:
	if (_dm_use_udev()) {
		(void)dm_udev_wait(cookie);
		cookie = 0;
	}

	if (r < 0 && !reload) {
		if (get_error())
			error = strdup(get_error());

		dm_remove_device(name, 0, 0);

		if (error) {
			set_error(error);
			free(error);
		}
	}

out_no_removal:
	if (cookie && _dm_use_udev())
		(void)dm_udev_wait(cookie);

	if (params)
		safe_free(params);
	if (dmt)
		dm_task_destroy(dmt);

	dm_task_update_nodes();
	return r;
}