int dm_event_unregister_handler(const struct dm_event_handler *dmevh) { int ret = 1, err; const char *uuid; struct dm_task *dmt; struct dm_event_daemon_message msg = { 0, 0, NULL }; if (!(dmt = _get_device_info(dmevh))) { stack; return 0; } uuid = dm_task_get_uuid(dmt); if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg, dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) { log_error("%s: event deregistration failed: %s", dm_task_get_name(dmt), msg.data ? msg.data : strerror(-err)); ret = 0; } dm_free(msg.data); dm_task_destroy(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; }
/* Check, if a device exists. */ static int _fill_device_data(struct thread_status *ts) { struct dm_task *dmt; struct dm_info dmi; if (!ts->device.uuid) return 0; ts->device.name = NULL; ts->device.major = ts->device.minor = 0; dmt = dm_task_create(DM_DEVICE_INFO); if (!dmt) return 0; dm_task_set_uuid(dmt, ts->device.uuid); if (!dm_task_run(dmt)) goto fail; ts->device.name = dm_strdup(dm_task_get_name(dmt)); if (!ts->device.name) goto fail; if (!dm_task_get_info(dmt, &dmi)) goto fail; ts->device.major = dmi.major; ts->device.minor = dmi.minor; dm_task_destroy(dmt); return 1; fail: dm_task_destroy(dmt); dm_free(ts->device.name); return 0; }
/* * Returns 0 if handler found; error (-ENOMEM, -ENOENT) otherwise. */ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next) { int ret = 0; const char *uuid = NULL; char *reply_dso = NULL, *reply_uuid = NULL; enum dm_event_mask reply_mask = 0; struct dm_task *dmt = NULL; struct dm_event_daemon_message msg = { 0, 0, NULL }; struct dm_info info; if (!(dmt = _get_device_info(dmevh))) { stack; return 0; } uuid = dm_task_get_uuid(dmt); if (!(ret = _do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE : DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path, &msg, dmevh->dso, uuid, dmevh->mask, 0))) { /* FIXME this will probably horribly break if we get ill-formatted reply */ ret = _parse_message(&msg, &reply_dso, &reply_uuid, &reply_mask); } else { ret = -ENOENT; goto fail; } dm_task_destroy(dmt); dmt = NULL; dm_free(msg.data); msg.data = NULL; _dm_event_handler_clear_dev_info(dmevh); dmevh->uuid = dm_strdup(reply_uuid); if (!dmevh->uuid) { ret = -ENOMEM; goto fail; } if (!(dmt = _get_device_info(dmevh))) { ret = -ENXIO; /* dmeventd probably gave us bogus uuid back */ goto fail; } dm_event_handler_set_dso(dmevh, reply_dso); dm_event_handler_set_event_mask(dmevh, reply_mask); dm_free(reply_dso); reply_dso = NULL; dm_free(reply_uuid); reply_uuid = NULL; dmevh->dev_name = dm_strdup(dm_task_get_name(dmt)); if (!dmevh->dev_name) { ret = -ENOMEM; goto fail; } if (!dm_task_get_info(dmt, &info)) { ret = -1; goto fail; } dmevh->major = info.major; dmevh->minor = info.minor; dm_task_destroy(dmt); return ret; fail: dm_free(msg.data); dm_free(reply_dso); dm_free(reply_uuid); _dm_event_handler_clear_dev_info(dmevh); if (dmt) dm_task_destroy(dmt); return ret; }
int device_is_usable(struct device *dev) { struct dm_task *dmt; struct dm_info info; const char *name, *uuid; uint64_t start, length; char *target_type = NULL; char *params, *vgname = NULL, *lvname, *layer; void *next = NULL; int r = 0; if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) { log_error("Failed to allocate dm_task struct to check dev status"); return 0; } if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1)) goto_out; if (!dm_task_run(dmt)) { log_error("Failed to get state of mapped device"); goto out; } if (!dm_task_get_info(dmt, &info)) goto_out; if (!info.exists || info.suspended) goto out; name = dm_task_get_name(dmt); uuid = dm_task_get_uuid(dmt); /* FIXME Also check for mirror block_on_error and mpath no paths */ /* For now, we exclude all mirrors */ do { next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms); /* Skip if target type doesn't match */ if (target_type && !strcmp(target_type, "mirror")) { log_debug("%s: Mirror device not usable.", dev_name(dev)); goto out; } } while (next); /* FIXME Also check dependencies? */ /* Check internal lvm devices */ if (uuid && !strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1)) { if (!(vgname = dm_strdup(name)) || !dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer)) goto_out; if (lvname && (is_reserved_lvname(lvname) || *layer)) { log_debug("%s: Reserved internal LV device %s/%s%s%s not usable.", dev_name(dev), vgname, lvname, *layer ? "-" : "", layer); goto out; } } r = 1; out: dm_free(vgname); dm_task_destroy(dmt); return r; }
int era_dm_info(const char *name, const char *uuid, struct era_dm_info *info, size_t name_size, char *name_ptr, size_t uuid_size, char *uuid_ptr) { struct dm_task *dmt; struct dm_info dmi; int rc = -1; if (!(dmt = dm_task_create(DM_DEVICE_INFO))) return -1; if (name && !dm_task_set_name(dmt, name)) goto out; if (uuid && !dm_task_set_uuid(dmt, uuid)) goto out; if (!dm_task_run(dmt)) goto out; if (!dm_task_get_info(dmt, &dmi)) goto out; if (info) { 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; } if (dmi.exists && name_size > 0 && name_ptr) { const char *dm_name; size_t dm_name_len; dm_name = dm_task_get_name(dmt); if (!dm_name) goto out; dm_name_len = strlen(dm_name); if (dm_name_len >= name_size) { rc = dm_name_len + 1; goto out; } strcpy(name_ptr, dm_name); } if (dmi.exists && uuid_size > 0 && uuid_ptr) { const char *dm_uuid; size_t dm_uuid_len; dm_uuid = dm_task_get_uuid(dmt); if (!dm_uuid) goto out; dm_uuid_len = strlen(dm_uuid); if (dm_uuid_len >= uuid_size) { dm_task_destroy(dmt); return dm_uuid_len + 1; } strcpy(uuid_ptr, dm_uuid); } rc = 0; out: dm_task_destroy(dmt); return rc; }
p[0] = '\0'; syslog(LOG_INFO, "%s array, %s, is %s in-sync.", raid_type, device, strcmp(resync_ratio, p+1) ? "not" : "now"); return 0; } void process_event(struct dm_task *dmt, enum dm_event_mask event __attribute__((unused)), void **unused __attribute__((unused))) { void *next = NULL; uint64_t start, length; char *target_type = NULL; char *params; const char *device = dm_task_get_name(dmt); dmeventd_lvm2_lock(); do { next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms); if (!target_type) { syslog(LOG_INFO, "%s mapping lost.", device); continue; } if (strcmp(target_type, "raid")) { syslog(LOG_INFO, "%s has non-raid portion.", device); continue;