static int dm_dev_t (const char * mapname, char * dev_t, int len) { int r = 1; struct dm_task *dmt; struct dm_info info; if (!(dmt = dm_task_create(DM_DEVICE_INFO))) return 0; if (!dm_task_set_name(dmt, mapname)) goto out; if (!dm_task_run(dmt)) goto out; if (!dm_task_get_info(dmt, &info) || !info.exists) goto out; if (snprintf(dev_t, len, "%i:%i", info.major, info.minor) > len) goto out; r = 0; out: dm_task_destroy(dmt); return r; }
int dm_get_minor (char * mapname) { int r = -1; struct dm_task *dmt; struct dm_info info; if (!(dmt = dm_task_create(DM_DEVICE_INFO))) return 0; if (!dm_task_set_name(dmt, mapname)) goto out; if (!dm_task_run(dmt)) goto out; if (!dm_task_get_info(dmt, &info)) goto out; if (!info.exists) goto out; r = info.minor; out: dm_task_destroy(dmt); return r; }
extern int dm_get_status(char * name, char * outstatus) { int r = 1; struct dm_task *dmt; uint64_t start, length; char *target_type; char *status; if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) return 1; if (!dm_task_set_name(dmt, name)) goto out; dm_task_no_open_count(dmt); if (!dm_task_run(dmt)) goto out; /* Fetch 1st target */ dm_get_next_target(dmt, NULL, &start, &length, &target_type, &status); if (snprintf(outstatus, PARAMS_SIZE, "%s", status) <= PARAMS_SIZE) r = 0; out: if (r) condlog(0, "%s: error getting map status string", name); dm_task_destroy(dmt); return r; }
/* * returns: * 1 : match * 0 : no match * -1 : empty map */ extern int dm_type(const char * name, char * type) { int r = 0; struct dm_task *dmt; uint64_t start, length; char *target_type = NULL; char *params; if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) return 0; if (!dm_task_set_name(dmt, name)) goto out; dm_task_no_open_count(dmt); if (!dm_task_run(dmt)) goto out; /* Fetch 1st target */ dm_get_next_target(dmt, NULL, &start, &length, &target_type, ¶ms); if (!target_type) r = -1; else if (!strcmp(target_type, type)) r = 1; out: dm_task_destroy(dmt); return r; }
int era_dm_list(int (*cb)(void *arg, const char *name), void *cbarg) { struct dm_task *dmt; struct dm_names *names; unsigned next = 0; if (!(dmt = dm_task_create(DM_DEVICE_LIST))) return -1; if (!dm_task_run(dmt)) goto out; if (!(names = dm_task_get_names(dmt))) goto out; if (names->dev) { do { names = (struct dm_names *)((char *)names + next); if (cb(cbarg, names->name)) goto out; next = names->next; } while(next); } dm_task_destroy(dmt); return 0; out: dm_task_destroy(dmt); return -1; }
static int virStorageBackendGetMinorNumber(const char *dev_name, uint32_t *minor) { int ret = -1; struct dm_task *dmt; struct dm_info info; if (!(dmt = dm_task_create(DM_DEVICE_INFO))) goto out; if (!dm_task_set_name(dmt, dev_name)) goto out; if (!dm_task_run(dmt)) goto out; if (!dm_task_get_info(dmt, &info)) goto out; *minor = info.minor; ret = 0; out: if (dmt != NULL) dm_task_destroy(dmt); return ret; }
int dm_geteventnr (char *name) { struct dm_task *dmt; struct dm_info info; int event = -1; if (!(dmt = dm_task_create(DM_DEVICE_INFO))) return -1; if (!dm_task_set_name(dmt, name)) goto out; dm_task_no_open_count(dmt); if (!dm_task_run(dmt)) goto out; if (!dm_task_get_info(dmt, &info)) goto out; if (info.exists) event = info.event_nr; out: dm_task_destroy(dmt); return event; }
static int dm_get_info(const char *name, struct dm_info *dmi) { struct dm_task *dmt = NULL; int error = -1; if ((dmt = dm_task_create(DM_DEVICE_INFO)) == NULL) goto out; if ((dm_task_set_name(dmt, name)) == 0) goto out; if ((dm_task_run(dmt)) == 0) goto out; if ((dm_task_get_info(dmt, dmi)) == 0) goto out; error = 0; out: if (dmt) dm_task_destroy(dmt); return error; }
static int _dm_check_versions(void) { struct dm_task *dmt; struct dm_versions *target, *last_target; if (_dm_crypt_checked) return 1; if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS))) return 0; if (!dm_task_run(dmt)) { dm_task_destroy(dmt); return 0; } target = dm_task_get_versions(dmt); do { last_target = target; if (!strcmp(DM_CRYPT_TARGET, target->name)) { _dm_set_crypt_compat((int)target->version[0], (int)target->version[1], (int)target->version[2]); } target = (void *) target + target->next; } while (last_target != target); dm_task_destroy(dmt); return 1; }
/* Create a task, set its name and run it. */ static int run_task(struct lib_context *lc, struct raid_set *rs, char *table, int type, char *name) { /* * DM_UUID_LEN is defined in dm-ioctl.h as 129 characters; * though not all 129 must be used (md uses just 16 from * a quick review of md.c. * We will be using: (len vol grp name) */ char uuid[DM_UUID_LEN]; int ret; struct dm_task *dmt; _init_dm(); ret = (dmt = dm_task_create(type)) && dm_task_set_name(dmt, name); if (ret && table) ret = parse_table(lc, dmt, table); if (ret) { if (DM_DEVICE_CREATE == type) { ret = dmraid_uuid(lc, rs, uuid, DM_UUID_LEN, name) && dm_task_set_uuid(dmt, uuid) && dm_task_run(dmt); } else ret = dm_task_run(dmt); } _exit_dm(dmt); return ret; }
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; }
/* DM helpers */ static int _dm_simple(int task, const char *name, int udev_wait) { int r = 0; struct dm_task *dmt; uint32_t cookie = 0; if (!_dm_use_udev()) udev_wait = 0; if (!(dmt = dm_task_create(task))) return 0; if (name && !dm_task_set_name(dmt, name)) goto out; if (udev_wait && !dm_task_set_cookie(dmt, &cookie, 0)) goto out; r = dm_task_run(dmt); if (udev_wait) (void)dm_udev_wait(cookie); out: dm_task_destroy(dmt); return r; }
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; }
int dm_message(char *path, char *message) { struct dm_task *task; int e = -EIO; if(!path) { goto fail; } if(!(task = dm_task_create(DM_DEVICE_TARGET_MSG))) { goto fail; } if(!dm_task_set_name(task, path)) { goto fail; } if(!dm_task_set_sector(task, 0)) { goto fail; } if(!dm_task_set_message(task, message)) { goto fail; } if(!dm_task_run(task)) { e = -errno; goto fail; } e = 0; fail: dm_task_destroy(task); return e; }
static int _lookup_dev_name(uint64_t dev, char *buf, size_t len) { struct dm_names *names; unsigned next = 0; struct dm_task *dmt; int r = 0; if (!(dmt = dm_task_create(DM_DEVICE_LIST))) return 0; if (!dm_task_run(dmt)) goto out; if (!(names = dm_task_get_names(dmt))) goto out; if (!names->dev) goto out; do { names = (void *) names + next; if (names->dev == dev) { strncpy(buf, names->name, len); r = 1; break; } next = names->next; } while (next); out: dm_task_destroy(dmt); return r; }
int dm_message(const char * mapname, char * message) { int r = 1; struct dm_task *dmt; if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG))) return 1; if (!dm_task_set_name(dmt, mapname)) goto out; if (!dm_task_set_sector(dmt, 0)) goto out; if (!dm_task_set_message(dmt, message)) goto out; dm_task_no_open_count(dmt); if (!dm_task_run(dmt)) goto out; r = 0; out: if (r) condlog(0, "DM message failed [%s]", message); dm_task_destroy(dmt); return r; }
extern int dm_map_present (const char * str) { int r = 0; struct dm_task *dmt; struct dm_info info; if (!(dmt = dm_task_create(DM_DEVICE_INFO))) return 0; if (!dm_task_set_name(dmt, str)) goto out; dm_task_no_open_count(dmt); if (!dm_task_run(dmt)) goto out; if (!dm_task_get_info(dmt, &info)) goto out; if (info.exists) r = 1; out: dm_task_destroy(dmt); return r; }
int era_dm_message0(const char *name, const char *message) { struct dm_task *dmt; int rc = -1; if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG))) return -1; if (!dm_task_set_name(dmt, name)) goto out; if (!dm_task_set_sector(dmt, 0)) goto out; if (!dm_task_set_message(dmt, message)) goto out; if (!dm_task_run(dmt)) goto out; rc = 0; out: dm_task_destroy(dmt); return rc; }
static int dm_get_prefixed_uuid(const char *name, char *uuid) { struct dm_task *dmt; const char *uuidtmp; int r = 1; dmt = dm_task_create(DM_DEVICE_INFO); if (!dmt) return 1; if (!dm_task_set_name (dmt, name)) goto uuidout; if (!dm_task_run(dmt)) goto uuidout; uuidtmp = dm_task_get_uuid(dmt); if (uuidtmp) strcpy(uuid, uuidtmp); else uuid[0] = '\0'; r = 0; uuidout: dm_task_destroy(dmt); return r; }
static int _dm_simple(int task, int wait, const char *name) { 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 (wait && !dm_task_set_cookie(dmt, &cookie, 0)) goto out; rc = dm_task_run(dmt); if (wait) (void) dm_udev_wait(cookie); dm_task_destroy(dmt); return rc ? 0 : -1; out: dm_task_destroy(dmt); return -1; }
extern int dm_flush_maps (void) { int r = 0; struct dm_task *dmt; struct dm_names *names; unsigned next = 0; if (!(dmt = dm_task_create (DM_DEVICE_LIST))) return 0; dm_task_no_open_count(dmt); if (!dm_task_run (dmt)) goto out; if (!(names = dm_task_get_names (dmt))) goto out; if (!names->dev) goto out; do { r |= dm_suspend_and_flush_map(names->name); next = names->next; names = (void *) names + next; } while (next); out: dm_task_destroy (dmt); return r; }
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; }
/* * Retrieve list of registered mapping targets. * * dm-library must get inititalized by caller. */ static struct dm_versions * get_target_list(void) { struct dm_task *dmt; return (dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)) && dm_task_run(dmt) ? dm_task_get_versions(dmt) : NULL; }
static int dm_device_remove(uint64_t dev) { struct dm_task *dmt; struct dm_names *dmnames; char *name = NULL; int ret = 0; /* Look for dev_name via dev, if dev_name could be transferred here, we could jump to DM_DEVICE_REMOVE directly */ dmt = dm_task_create(DM_DEVICE_LIST); if (!dmt) { BL_LOG_ERR("dm_task creation failed\n"); goto out; } ret = dm_task_run(dmt); if (!ret) { BL_LOG_ERR("dm_task_run failed\n"); goto out; } dmnames = dm_task_get_names(dmt); if (!dmnames || !dmnames->dev) { BL_LOG_ERR("dm_task_get_names failed\n"); goto out; } while (dmnames) { if (dmnames->dev == dev) { name = strdup(dmnames->name); break; } dmnames = (void *)dmnames + dmnames->next; } if (!name) { BL_LOG_ERR("Could not find device\n"); goto out; } dm_task_update_nodes(); out: if (dmt) dm_task_destroy(dmt); /* Start to remove device */ if (name) { ret = dm_device_remove_byname(name); free(name); } return ret; }
static gboolean map_is_multipath (const gchar *map_name, GError **error) { struct dm_task *task = NULL; struct dm_info info; guint64 start = 0; guint64 length = 0; gchar *type = NULL; gchar *params = NULL; gboolean ret = FALSE; if (geteuid () != 0) { g_set_error (error, BD_MPATH_ERROR, BD_MPATH_ERROR_NOT_ROOT, "Not running as root, cannot query DM maps"); return FALSE; } task = dm_task_create (DM_DEVICE_STATUS); if (!task) { g_warning ("Failed to create DM task"); g_set_error (error, BD_MPATH_ERROR, BD_MPATH_ERROR_DM_ERROR, "Failed to create DM task"); return FALSE; } if (dm_task_set_name (task, map_name) == 0) { g_set_error (error, BD_MPATH_ERROR, BD_MPATH_ERROR_DM_ERROR, "Failed to create DM task"); dm_task_destroy (task); return FALSE; } if (dm_task_run (task) == 0) { g_set_error (error, BD_MPATH_ERROR, BD_MPATH_ERROR_DM_ERROR, "Failed to run DM task"); dm_task_destroy (task); return FALSE; } if (dm_task_get_info (task, &info) == 0) { g_set_error (error, BD_MPATH_ERROR, BD_MPATH_ERROR_DM_ERROR, "Failed to get task info"); dm_task_destroy (task); return FALSE; } dm_get_next_target(task, NULL, &start, &length, &type, ¶ms); if (g_strcmp0 (type, "multipath") == 0) ret = TRUE; else ret = FALSE; dm_task_destroy (task); return ret; }
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; }
int main(int argc, char** argv) { /* * Dump a devices table. First arg should be the device name. * */ char* name; if (argc < 2) { printf("usage: dump_table <device name>\n"); return 1; } else { name = argv[1]; } struct dm_task *dmt; struct dm_info info; struct dm_names *names; uint64_t start, length; char* params, * target_type; void* next = NULL; if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) { printf("could not create dm task\n"); return 1; } if (!_set_task_device(dmt, name, 0)) { printf("device %s may not exist -?\n", name); } if (!dm_task_run(dmt)) { printf("error running task\n"); dm_task_destroy(dmt); return 1; } if (!dm_task_get_info(dmt, &info) || !info.exists) { printf("could not get info for %s\n", name); return 1; } /* not sure about this bit */ do { next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms); printf("%" PRIu64 " %" PRIu64 " %s %s\n", start, length, target_type, params); } while(next); dm_task_destroy(dmt); return 0; }
/* FIXME: more status for device monitoring... */ int dm_status(struct lib_context *lc, struct raid_set *rs) { int ret; struct dm_task *dmt; struct dm_info info; _init_dm(); /* Status <dev_name>. */ ret = (dmt = dm_task_create(DM_DEVICE_STATUS)) && dm_task_set_name(dmt, rs->name) && dm_task_run(dmt) && dm_task_get_info(dmt, &info) && info.exists; _exit_dm(dmt); return ret; }
char * dm_mapname(int major, int minor) { char * response = NULL; const char *map; struct dm_task *dmt; int r; int loop = MAX_WAIT * LOOPS_PER_SEC; if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) return NULL; if (!dm_task_set_major(dmt, major) || !dm_task_set_minor(dmt, minor)) goto bad; dm_task_no_open_count(dmt); /* * device map might not be ready when we get here from * daemon uev_trigger -> uev_add_map */ while (--loop) { r = dm_task_run(dmt); if (r) break; usleep(1000 * 1000 / LOOPS_PER_SEC); } if (!r) { condlog(0, "%i:%i: timeout fetching map name", major, minor); goto bad; } map = dm_task_get_name(dmt); if (map && strlen(map)) response = STRDUP((char *)dm_task_get_name(dmt)); dm_task_destroy(dmt); return response; bad: dm_task_destroy(dmt); condlog(0, "%i:%i: error fetching map name", major, minor); return NULL; }
/* Retrieve device-mapper driver version. */ int dm_version(struct lib_context *lc, char *version, size_t size) { int ret; struct dm_task *dmt; /* Be prepared for device-mapper not in kernel. */ strncpy(version, "unknown", size); _init_dm(); ret = (dmt = dm_task_create(DM_DEVICE_VERSION)) && dm_task_run(dmt) && dm_task_get_driver_version(dmt, version, size); _exit_dm(dmt); return ret; }