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; }
int dm_resume_and_reinstate_key(const char *name, size_t key_size, const char *key) { int msg_size = key_size * 2 + 10; // key set <key> char *msg; int r = 0; if (!_dm_check_versions()) return -ENOTSUP; if (!_dm_crypt_wipe_key_supported) return -ENOTSUP; msg = safe_alloc(msg_size); if (!msg) return -ENOMEM; memset(msg, 0, msg_size); strcpy(msg, "key set "); hex_key(&msg[8], key_size, key); if (!_dm_message(name, msg) || !_dm_simple(DM_DEVICE_RESUME, name, 1)) r = -EINVAL; safe_free(msg); return r; }
int dm_suspend_and_wipe_key(const char *name) { if (!_dm_check_versions()) return -ENOTSUP; if (!_dm_crypt_wipe_key_supported) return -ENOTSUP; if (!_dm_simple(DM_DEVICE_SUSPEND, name, 0)) return -EINVAL; if (!_dm_message(name, "key wipe")) { _dm_simple(DM_DEVICE_RESUME, name, 1); return -EINVAL; } return 0; }
int dm_remove_device(const char *name, int force, uint64_t size) { int r = -EINVAL; int retries = force ? RETRY_COUNT : 1; int error_target = 0; if (!name || (force && !size)) return -EINVAL; do { r = _dm_simple(DM_DEVICE_REMOVE, name, 1) ? 0 : -EINVAL; if (--retries && r) { log_dbg("WARNING: other process locked internal device %s, %s.", name, retries ? "retrying remove" : "giving up"); if (force && (crypt_get_debug_level() == CRYPT_LOG_DEBUG)) debug_processes_using_device(name); sleep(1); if (force && !error_target) { /* If force flag is set, replace device with error, read-only target. * it should stop processes from reading it and also removed underlying * device from mapping, so it is usable again. * Force flag should be used only for temporary devices, which are * intended to work inside cryptsetup only! * Anyway, if some process try to read temporary cryptsetup device, * it is bug - no other process should try touch it (e.g. udev). */ _error_device(name, size); error_target = 1; } } } while (r == -EINVAL && retries); dm_task_update_nodes(); return r; }
int era_dm_clear(const char *name) { return _dm_simple(DM_DEVICE_CLEAR, 0, name); }
int era_dm_remove(const char *name) { return _dm_simple(DM_DEVICE_REMOVE, 1, name); }
int era_dm_resume(const char *name) { return _dm_simple(DM_DEVICE_RESUME, 1, name); }
int era_dm_suspend(const char *name) { return _dm_simple(DM_DEVICE_SUSPEND, 0, name); }