mirror of
				git://sourceware.org/git/lvm2.git
				synced 2025-10-30 20:23:49 +03:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			v2_03_17
			...
			dev-dct-de
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 07338325e5 | 
| @@ -2947,6 +2947,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg, | ||||
|  | ||||
| 	/* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */ | ||||
| 	for (s = start_area; s < areas; s++) { | ||||
|  | ||||
| 		/* FIXME: dev_name() does not return NULL!  It needs to check if dm_list_empty(&dev->aliases) | ||||
| 		   but this knot of logic is too complex to pull apart without careful deconstruction. */ | ||||
|  | ||||
| 		if ((seg_type(seg, s) == AREA_PV && | ||||
| 		     (!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) || | ||||
| 		       !(name = dev_name(seg_dev(seg, s))) || !*name || | ||||
| @@ -2965,7 +2969,10 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg, | ||||
| 				return_0; | ||||
| 			num_error_areas++; | ||||
| 		} else if (seg_type(seg, s) == AREA_PV) { | ||||
| 			if (!dm_tree_node_add_target_area(node, dev_name(seg_dev(seg, s)), NULL, | ||||
| 			struct device *dev = seg_dev(seg, s); | ||||
| 			name = dm_list_empty(&dev->aliases) ? NULL : dev_name(dev); | ||||
|  | ||||
| 			if (!dm_tree_node_add_target_area(node, name, NULL, | ||||
| 				    (seg_pv(seg, s)->pe_start + (extent_size * seg_pe(seg, s))))) | ||||
| 				return_0; | ||||
| 			num_existing_areas++; | ||||
|   | ||||
| @@ -351,7 +351,7 @@ static int _add_alias(struct device *dev, const char *path, enum add_hash hash) | ||||
| 			goto out; | ||||
| 		} | ||||
|  | ||||
| 	if (!(path = dm_pool_strdup(_cache.mem, path)) || | ||||
| 	if (!(path = _strdup(path)) || | ||||
| 	    !(sl = _zalloc(sizeof(*sl)))) { | ||||
| 		log_error("Failed to add allias to dev cache."); | ||||
| 		return 0; | ||||
| @@ -1162,6 +1162,17 @@ static int _insert(const char *path, const struct stat *info, | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static void _drop_all_aliases(struct device *dev) | ||||
| { | ||||
| 	struct dm_str_list *strl, *strl2; | ||||
|  | ||||
| 	dm_list_iterate_items_safe(strl, strl2, &dev->aliases) { | ||||
| 		log_debug("Drop alias for %d:%d %s.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str); | ||||
| 		dm_hash_remove(_cache.names, strl->str); | ||||
| 		dm_list_del(&strl->list); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void dev_cache_scan(struct cmd_context *cmd) | ||||
| { | ||||
| 	log_debug_devs("Creating list of system devices."); | ||||
| @@ -1371,59 +1382,6 @@ int dev_cache_add_dir(const char *path) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| /* Check cached device name is still valid before returning it */ | ||||
| /* This should be a rare occurrence */ | ||||
| /* set quiet if the cache is expected to be out-of-date */ | ||||
| /* FIXME Make rest of code pass/cache struct device instead of dev_name */ | ||||
| const char *dev_name_confirmed(struct device *dev, int quiet) | ||||
| { | ||||
| 	struct stat buf; | ||||
| 	const char *name; | ||||
| 	int r; | ||||
|  | ||||
| 	if ((dev->flags & DEV_REGULAR)) | ||||
| 		return dev_name(dev); | ||||
|  | ||||
| 	while ((r = stat(name = dm_list_item(dev->aliases.n, | ||||
| 					  struct dm_str_list)->str, &buf)) || | ||||
| 	       (buf.st_rdev != dev->dev)) { | ||||
| 		if (r < 0) { | ||||
| 			if (quiet) | ||||
| 				log_sys_debug("stat", name); | ||||
| 			else | ||||
| 				log_sys_error("stat", name); | ||||
| 		} | ||||
| 		if (quiet) | ||||
| 			log_debug_devs("Path %s no longer valid for device(%d,%d)", | ||||
| 				       name, (int) MAJOR(dev->dev), | ||||
| 				       (int) MINOR(dev->dev)); | ||||
| 		else | ||||
| 			log_warn("Path %s no longer valid for device(%d,%d)", | ||||
| 				 name, (int) MAJOR(dev->dev), | ||||
| 				 (int) MINOR(dev->dev)); | ||||
|  | ||||
| 		/* Remove the incorrect hash entry */ | ||||
| 		dm_hash_remove(_cache.names, name); | ||||
|  | ||||
| 		/* Leave list alone if there isn't an alternative name */ | ||||
| 		/* so dev_name will always find something to return. */ | ||||
| 		/* Otherwise add the name to the correct device. */ | ||||
| 		if (dm_list_size(&dev->aliases) > 1) { | ||||
| 			dm_list_del(dev->aliases.n); | ||||
| 			if (!r) | ||||
| 				_insert(name, &buf, 0, obtain_device_list_from_udev()); | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		/* Scanning issues this inappropriately sometimes. */ | ||||
| 		log_debug_devs("Aborting - please provide new pathname for what " | ||||
| 			       "used to be %s", name); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	return dev_name(dev); | ||||
| } | ||||
|  | ||||
| struct device *dev_hash_get(const char *name) | ||||
| { | ||||
| 	return (struct device *) dm_hash_lookup(_cache.names, name); | ||||
| @@ -1452,26 +1410,23 @@ static void _remove_alias(struct device *dev, const char *name) | ||||
|  * deactivated LV.  Those old paths are all invalid and are dropped here. | ||||
|  */ | ||||
|  | ||||
| static void _verify_aliases(struct device *dev, const char *newname) | ||||
| static void _verify_aliases(struct device *dev) | ||||
| { | ||||
| 	struct dm_str_list *strl, *strl2; | ||||
| 	struct stat st; | ||||
|  | ||||
| 	dm_list_iterate_items_safe(strl, strl2, &dev->aliases) { | ||||
| 		/* newname was just stat'd and added by caller */ | ||||
| 		if (newname && !strcmp(strl->str, newname)) | ||||
| 			continue; | ||||
|  | ||||
| 		if (stat(strl->str, &st) || (st.st_rdev != dev->dev)) { | ||||
| 			log_debug("Drop invalid path %s for %d:%d (new path %s).", | ||||
| 				  strl->str, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), newname ?: ""); | ||||
| 			log_debug("Drop alias for %d:%d invalid path %s %d:%d.", | ||||
| 				  (int)MAJOR(dev->dev), (int)MINOR(dev->dev), strl->str, | ||||
| 				  (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev)); | ||||
| 			dm_hash_remove(_cache.names, strl->str); | ||||
| 			dm_list_del(&strl->list); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f) | ||||
| static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f, int existing) | ||||
| { | ||||
| 	struct device *dev = (struct device *) dm_hash_lookup(_cache.names, name); | ||||
| 	struct stat st; | ||||
| @@ -1485,13 +1440,18 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d | ||||
| 	if (dev && (dev->flags & DEV_REGULAR)) | ||||
| 		return dev; | ||||
|  | ||||
| 	if (dev && dm_list_empty(&dev->aliases)) { | ||||
| 		/* shouldn't happen */ | ||||
| 		log_warn("Ignoring dev with no valid paths for %s.", name); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * The requested path is invalid, remove any dev-cache | ||||
| 	 * info for it. | ||||
| 	 * The requested path is invalid, remove any dev-cache info for it. | ||||
| 	 */ | ||||
| 	if (stat(name, &st)) { | ||||
| 		if (dev) { | ||||
| 			log_print("Device path %s is invalid for %d:%d %s.", | ||||
| 			log_debug("Device path %s is invalid for %d:%d %s.", | ||||
| 				  name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev)); | ||||
|  | ||||
| 			dm_hash_remove(_cache.names, name); | ||||
| @@ -1499,11 +1459,17 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d | ||||
| 			_remove_alias(dev, name); | ||||
|  | ||||
| 			/* Remove any other names in dev->aliases that are incorrect. */ | ||||
| 			_verify_aliases(dev, NULL); | ||||
| 			_verify_aliases(dev); | ||||
| 		} | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (dev && dm_list_empty(&dev->aliases)) { | ||||
| 		/* shouldn't happen */ | ||||
| 		log_warn("Ignoring dev with no valid paths for %s.", name); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!S_ISBLK(st.st_mode)) { | ||||
| 		log_debug("Not a block device %s.", name); | ||||
| 		return NULL; | ||||
| @@ -1514,26 +1480,41 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d | ||||
| 	 * Remove incorrect info and then add new dev-cache entry. | ||||
| 	 */ | ||||
| 	if (dev && (st.st_rdev != dev->dev)) { | ||||
| 		log_debug("Device path %s does not match %d:%d %s.", | ||||
| 			  name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev)); | ||||
| 		struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev); | ||||
|  | ||||
| 		dm_hash_remove(_cache.names, name); | ||||
| 		/* | ||||
| 		 * lvm commands create this condition when they | ||||
| 		 * activate/deactivate LVs combined with creating new LVs. | ||||
| 		 * The command does not purge dev structs when deactivating | ||||
| 		 * an LV (which it probably should do), but the better | ||||
| 		 * approach would be not using dev-cache at all for LVs. | ||||
| 		 */ | ||||
|  | ||||
| 		_remove_alias(dev, name); | ||||
| 		log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.", | ||||
| 			  (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev_name(dev), | ||||
| 			  (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name); | ||||
|  | ||||
| 		/* Remove any other names in dev->aliases that are incorrect. */ | ||||
| 		_verify_aliases(dev, NULL); | ||||
| 		_drop_all_aliases(dev); | ||||
|  | ||||
| 		/* Add new dev-cache entry next. */ | ||||
| 		dev = NULL; | ||||
| 	} | ||||
| 		if (dev_by_devt) { | ||||
| 			log_debug("Dropping aliases for device entry %d:%d %s for new device %d:%d %s.", | ||||
| 				   (int)MAJOR(dev_by_devt->dev), (int)MINOR(dev_by_devt->dev), dev_name(dev_by_devt), | ||||
| 				   (int)MAJOR(st.st_rdev), (int)MINOR(st.st_rdev), name); | ||||
|  | ||||
| 			_drop_all_aliases(dev_by_devt); | ||||
| 		} | ||||
|  | ||||
| #if 0 | ||||
| 		/* | ||||
| 		 * I think only lvm's own dm devs should be added here, so use | ||||
| 		 * a warning to look for any other unknown cases. | ||||
| 		 */ | ||||
| 		if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) { | ||||
| 			log_warn("WARNING: new device appeared %d:%d %s", | ||||
| 				  (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name); | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| 	/* | ||||
| 	 * Either add a new struct dev for st_rdev and name, | ||||
| 	 * or add name as a new alias for an existing struct dev | ||||
| 	 * for st_rdev. | ||||
| 	 */ | ||||
| 	if (!dev) { | ||||
| 		if (!_insert_dev(name, st.st_rdev)) | ||||
| 			return_NULL; | ||||
|  | ||||
| @@ -1545,9 +1526,77 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d | ||||
| 			return NULL; | ||||
| 		} | ||||
|  | ||||
| 		_verify_aliases(dev, name); | ||||
| 		goto out; | ||||
| 	} | ||||
|  | ||||
| 	if (dev && dm_list_empty(&dev->aliases)) { | ||||
| 		/* shouldn't happen */ | ||||
| 		log_warn("Ignoring dev with no valid paths for %s.", name); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!dev && existing) | ||||
| 		return_NULL; | ||||
|  | ||||
| 	/* | ||||
| 	 * This case should never be hit for a PV. It should only | ||||
| 	 * happen when the command is opening a new LV it has created. | ||||
| 	 * Add an arg to all callers indicating when the arg should be | ||||
| 	 * new (for an LV) and not existing. | ||||
| 	 * FIXME: fix this further by not using dev-cache struct devs | ||||
| 	 * at all for new dm devs (LVs) that lvm uses.  Make the | ||||
| 	 * dev-cache contain only devs for PVs. | ||||
| 	 * Places to fix that use a dev for LVs include: | ||||
| 	 * . lv_resize opening lv to discard | ||||
| 	 * . wipe_lv opening lv to zero it | ||||
| 	 * . _extend_sanlock_lv opening lv to extend it | ||||
| 	 * . _write_log_header opening lv to write header | ||||
| 	 * Also, io to LVs should not go through bcache. | ||||
| 	 * bcache should contain only labels and metadata | ||||
| 	 * scanned from PVs. | ||||
| 	 */ | ||||
| 	if (!dev) { | ||||
| 		/* | ||||
| 		 * This case should only be used for new devices created by this | ||||
| 		 * command (opening LVs it's created), so if a dev exists for the | ||||
| 		 * dev_t referenced by the name, then drop all aliases for before | ||||
| 		 * _insert_dev adds the new name.  lvm commands actually hit this | ||||
| 		 * fairly often when it uses some LV, deactivates the LV, then | ||||
| 		 * creates some new LV which ends up with the same major:minor. | ||||
| 		 * Without dropping the aliases, it's plausible that lvm commands | ||||
| 		 * could end up using the wrong dm device. | ||||
| 		 */ | ||||
| 		struct device *dev_by_devt = (struct device *) btree_lookup(_cache.devices, (uint32_t) st.st_rdev); | ||||
| 		if (dev_by_devt) { | ||||
| 			log_debug("Dropping aliases for %d:%d before adding new path %s.", | ||||
| 				  (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name); | ||||
| 			_drop_all_aliases(dev_by_devt); | ||||
| 		} | ||||
|  | ||||
| #if 0 | ||||
| 		/* | ||||
| 		 * I think only lvm's own dm devs should be added here, so use | ||||
| 		 * a warning to look for any other unknown cases. | ||||
| 		 */ | ||||
| 		if (MAJOR(st.st_rdev) != cmd->dev_types->device_mapper_major) { | ||||
| 			log_warn("WARNING: new device appeared %d:%d %s", | ||||
| 				  (int)MAJOR(st.st_rdev), (int)(MINOR(st.st_rdev)), name); | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| 		if (!_insert_dev(name, st.st_rdev)) | ||||
| 			return_NULL; | ||||
|  | ||||
| 		/* Get the struct dev that was just added. */ | ||||
| 		dev = (struct device *) dm_hash_lookup(_cache.names, name); | ||||
|  | ||||
| 		if (!dev) { | ||||
| 			log_error("Failed to get device %s", name); | ||||
| 			return NULL; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  out: | ||||
| 	/* | ||||
| 	 * The caller passed a filter if they only want the dev if it | ||||
| 	 * passes filters. | ||||
| @@ -1577,63 +1626,23 @@ struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct d | ||||
| 	return dev; | ||||
| } | ||||
|  | ||||
| struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t dev, struct dev_filter *f, int *filtered) | ||||
| struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f) | ||||
| { | ||||
| 	char path[PATH_MAX]; | ||||
| 	const char *sysfs_dir; | ||||
| 	struct stat info; | ||||
| 	struct device *d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev); | ||||
| 	int ret; | ||||
| 	return _dev_cache_get(cmd, name, f, 1); | ||||
| } | ||||
|  | ||||
| 	if (filtered) | ||||
| 		*filtered = 0; | ||||
| struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f) | ||||
| { | ||||
| 	return _dev_cache_get(cmd, name, f, 0); | ||||
| } | ||||
|  | ||||
| 	if (!d) { | ||||
| 		sysfs_dir = dm_sysfs_dir(); | ||||
| 		if (sysfs_dir && *sysfs_dir) { | ||||
| 			/* First check if dev is sysfs to avoid useless scan */ | ||||
| 			if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", | ||||
| 					sysfs_dir, (int)MAJOR(dev), (int)MINOR(dev)) < 0) { | ||||
| 				log_error("dm_snprintf partition failed."); | ||||
| 				return NULL; | ||||
| 			} | ||||
|  | ||||
| 			if (lstat(path, &info)) { | ||||
| 				log_debug("No sysfs entry for %d:%d errno %d at %s.", | ||||
| 					  (int)MAJOR(dev), (int)MINOR(dev), errno, path); | ||||
| 				return NULL; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		log_debug_devs("Device num not found in dev_cache repeat dev_cache_scan for %d:%d", | ||||
| 				(int)MAJOR(dev), (int)MINOR(dev)); | ||||
| 		dev_cache_scan(cmd); | ||||
| 		d = (struct device *) btree_lookup(_cache.devices, (uint32_t) dev); | ||||
|  | ||||
| 		if (!d) | ||||
| 			return NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (d->flags & DEV_REGULAR) | ||||
| 		return d; | ||||
|  | ||||
| 	if (!f) | ||||
| 		return d; | ||||
|  | ||||
| 	ret = f->passes_filter(cmd, f, d, NULL); | ||||
|  | ||||
| 	if (ret == -EAGAIN) { | ||||
| 		log_debug_devs("get device by number defer filter %s", dev_name(d)); | ||||
| 		d->flags |= DEV_FILTER_AFTER_SCAN; | ||||
| 		ret = 1; | ||||
| 	} | ||||
|  | ||||
| 	if (ret) | ||||
| 		return d; | ||||
|  | ||||
| 	if (filtered) | ||||
| 		*filtered = 1; | ||||
| struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt) | ||||
| { | ||||
| 	struct device *dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devt); | ||||
|  | ||||
| 	if (dev) | ||||
| 		return dev; | ||||
| 	log_debug_devs("No devno %d:%d in dev cache.", (int)MAJOR(devt), (int)MINOR(devt)); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| @@ -1703,8 +1712,10 @@ int dev_fd(struct device *dev) | ||||
|  | ||||
| const char *dev_name(const struct device *dev) | ||||
| { | ||||
| 	return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str : | ||||
| 	    unknown_device_name(); | ||||
| 	if (dev && dev->aliases.n && !dm_list_empty(&dev->aliases)) | ||||
| 		return dm_list_item(dev->aliases.n, struct dm_str_list)->str; | ||||
| 	else | ||||
| 		return unknown_device_name(); | ||||
| } | ||||
|  | ||||
| bool dev_cache_has_md_with_end_superblock(struct dev_types *dt) | ||||
|   | ||||
| @@ -53,8 +53,8 @@ int dev_cache_has_scanned(void); | ||||
|  | ||||
| int dev_cache_add_dir(const char *path); | ||||
| struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f); | ||||
|  | ||||
| struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t device, struct dev_filter *f, int *filtered); | ||||
| struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f); | ||||
| struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt); | ||||
|  | ||||
| struct device *dev_hash_get(const char *name); | ||||
|  | ||||
|   | ||||
| @@ -58,6 +58,9 @@ static int _dev_get_size_file(struct device *dev, uint64_t *size) | ||||
| 	const char *name = dev_name(dev); | ||||
| 	struct stat info; | ||||
|  | ||||
| 	if (dm_list_empty(&dev->aliases)) | ||||
| 		return_0; | ||||
|  | ||||
| 	if (dev->size_seqno == _dev_size_seqno) { | ||||
| 		log_very_verbose("%s: using cached size %" PRIu64 " sectors", | ||||
| 				 name, dev->size); | ||||
| @@ -87,7 +90,7 @@ static int _dev_get_size_dev(struct device *dev, uint64_t *size) | ||||
| 	int do_close = 0; | ||||
|  | ||||
| 	if (dm_list_empty(&dev->aliases)) | ||||
| 		return 0; | ||||
| 		return_0; | ||||
|  | ||||
| 	if (dev->size_seqno == _dev_size_seqno) { | ||||
| 		log_very_verbose("%s: using cached size %" PRIu64 " sectors", | ||||
| @@ -305,6 +308,13 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) | ||||
| 	if ((flags & O_EXCL)) | ||||
| 		need_excl = 1; | ||||
|  | ||||
| 	if (dm_list_empty(&dev->aliases)) { | ||||
| 		/* shouldn't happen */ | ||||
| 		log_print("Cannot open device %d:%d with no valid paths.", (int)MAJOR(dev->dev), (int)MINOR(dev->dev)); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	name = dev_name(dev); | ||||
|  | ||||
| 	if (dev->fd >= 0) { | ||||
| 		if (((dev->flags & DEV_OPENED_RW) || !need_rw) && | ||||
| 		    ((dev->flags & DEV_OPENED_EXCL) || !need_excl)) { | ||||
| @@ -314,7 +324,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) | ||||
|  | ||||
| 		if (dev->open_count && !need_excl) | ||||
| 			log_debug_devs("%s: Already opened read-only. Upgrading " | ||||
| 				       "to read-write.", dev_name(dev)); | ||||
| 				       "to read-write.", name); | ||||
|  | ||||
| 		/* dev_close_immediate will decrement this */ | ||||
| 		dev->open_count++; | ||||
| @@ -327,11 +337,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) | ||||
|  | ||||
| 	if (critical_section()) | ||||
| 		/* FIXME Make this log_error */ | ||||
| 		log_verbose("dev_open(%s) called while suspended", | ||||
| 			    dev_name(dev)); | ||||
|  | ||||
| 	if (!(name = dev_name_confirmed(dev, quiet))) | ||||
| 		return_0; | ||||
| 		log_verbose("dev_open(%s) called while suspended", name); | ||||
|  | ||||
| #ifdef O_DIRECT_SUPPORT | ||||
| 	if (direct) { | ||||
| @@ -372,9 +378,9 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) | ||||
| 		} | ||||
| #endif | ||||
| 		if (quiet) | ||||
| 			log_sys_debug("open", name); | ||||
| 			log_debug("Failed to open device path %s (%d).", name, errno); | ||||
| 		else | ||||
| 			log_sys_error("open", name); | ||||
| 			log_error("Failed to open device path %s (%d).", name, errno); | ||||
|  | ||||
| 		dev->flags |= DEV_OPEN_FAILURE; | ||||
| 		return 0; | ||||
| @@ -415,10 +421,12 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet) | ||||
| 	if ((flags & O_CREAT) && !(flags & O_TRUNC)) | ||||
| 		dev->end = lseek(dev->fd, (off_t) 0, SEEK_END); | ||||
|  | ||||
| 	log_debug_devs("Opened %s %s%s%s", dev_name(dev), | ||||
| 		       dev->flags & DEV_OPENED_RW ? "RW" : "RO", | ||||
| 		       dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "", | ||||
| 		       dev->flags & DEV_O_DIRECT ? " O_DIRECT" : ""); | ||||
| 	if (!quiet) { | ||||
| 		log_debug_devs("Opened %s %s%s%s", name, | ||||
| 				dev->flags & DEV_OPENED_RW ? "RW" : "RO", | ||||
| 				dev->flags & DEV_OPENED_EXCL ? " O_EXCL" : "", | ||||
| 				dev->flags & DEV_O_DIRECT ? " O_DIRECT" : ""); | ||||
| 	} | ||||
|  | ||||
| 	dev->flags &= ~DEV_OPEN_FAILURE; | ||||
| 	return 1; | ||||
|   | ||||
| @@ -966,6 +966,9 @@ static int _wipe_known_signatures_with_blkid(struct device *dev, const char *nam | ||||
|  | ||||
| 	/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */ | ||||
|  | ||||
| 	if (dm_list_empty(&dev->aliases)) | ||||
| 		goto_out; | ||||
|  | ||||
| 	if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) { | ||||
| 		log_error("Failed to create a new blkid probe for device %s.", dev_name(dev)); | ||||
| 		goto out; | ||||
|   | ||||
| @@ -204,9 +204,6 @@ struct device *dev_create_file(const char *filename, struct device *dev, | ||||
| 			       struct dm_str_list *alias, int use_malloc); | ||||
| void dev_destroy_file(struct device *dev); | ||||
|  | ||||
| /* Return a valid device name from the alias list; NULL otherwise */ | ||||
| const char *dev_name_confirmed(struct device *dev, int quiet); | ||||
|  | ||||
| int dev_mpath_init(const char *config_wwids_file); | ||||
| void dev_mpath_exit(void); | ||||
|  | ||||
|   | ||||
| @@ -347,6 +347,8 @@ const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, u | ||||
| 	} | ||||
|  | ||||
| 	else if (idtype == DEV_ID_TYPE_DEVNAME) { | ||||
| 		if (dm_list_empty(&dev->aliases)) | ||||
| 			goto_bad; | ||||
| 		if (!(idname = strdup(dev_name(dev)))) | ||||
| 			goto_bad; | ||||
| 		return idname; | ||||
| @@ -955,6 +957,10 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid_ | ||||
| 	if (!dev_get_partition_number(dev, &part)) | ||||
| 		return_0; | ||||
|  | ||||
| 	/* Ensure valid dev_name(dev) below. */ | ||||
| 	if (dm_list_empty(&dev->aliases)) | ||||
| 		return_0; | ||||
|  | ||||
| 	/* | ||||
| 	 * When enable_devices_file=0 and pending_devices_file=1 we let | ||||
| 	 * pvcreate/vgcreate add new du's to cmd->use_devices.  These du's may | ||||
| @@ -1577,7 +1583,7 @@ void device_ids_match_device_list(struct cmd_context *cmd) | ||||
| 	dm_list_iterate_items(du, &cmd->use_devices) { | ||||
| 		if (du->dev) | ||||
| 			continue; | ||||
| 		if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) { | ||||
| 		if (!(du->dev = dev_cache_get_existing(cmd, du->devname, NULL))) { | ||||
| 			log_warn("Device not found for %s.", du->devname); | ||||
| 		} else { | ||||
| 			/* Should we set dev->id?  Which idtype?  Use --deviceidtype? */ | ||||
| @@ -1625,7 +1631,7 @@ void device_ids_match(struct cmd_context *cmd) | ||||
| 		 * the du/dev pairs in preparation for using the filters. | ||||
| 		 */ | ||||
| 		if (du->devname && | ||||
| 		    (dev = dev_cache_get(cmd, du->devname, NULL))) { | ||||
| 		    (dev = dev_cache_get_existing(cmd, du->devname, NULL))) { | ||||
| 			/* On successful match, du, dev, and id are linked. */ | ||||
| 			if (_match_du_to_dev(cmd, du, dev)) | ||||
| 				continue; | ||||
| @@ -1842,6 +1848,9 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, | ||||
| 		if (dev->flags & DEV_SCAN_NOT_READ) | ||||
| 			continue; | ||||
|  | ||||
| 		if (dm_list_empty(&dev->aliases)) | ||||
| 			continue; | ||||
|  | ||||
| 		if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) { | ||||
| 			log_warn("Devices file %s is excluded by filter: %s.", | ||||
| 				 dev_name(dev), dev_filtered_reason(dev)); | ||||
| @@ -2225,14 +2234,14 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l | ||||
| 	dm_list_iterate_items(dil, &search_pvids) { | ||||
| 		char *dup_devname1, *dup_devname2, *dup_devname3; | ||||
|  | ||||
| 		if (!dil->dev) { | ||||
| 		if (!dil->dev || dm_list_empty(&dil->dev->aliases)) { | ||||
| 			not_found++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		found++; | ||||
|  | ||||
| 		dev = dil->dev; | ||||
| 		devname = dev_name(dev); | ||||
| 		found++; | ||||
|  | ||||
| 		if (!(du = get_du_for_pvid(cmd, dil->pvid))) { | ||||
| 			/* shouldn't happen */ | ||||
|   | ||||
| @@ -500,6 +500,8 @@ int validate_hints(struct cmd_context *cmd, struct dm_list *hints) | ||||
| 	if (!(iter = dev_iter_create(NULL, 0))) | ||||
| 		return 0; | ||||
| 	while ((dev = dev_iter_get(cmd, iter))) { | ||||
| 		if (dm_list_empty(&dev->aliases)) | ||||
| 			continue; | ||||
| 		if (!(hint = _find_hint_name(hints, dev_name(dev)))) | ||||
| 			continue; | ||||
|  | ||||
|   | ||||
| @@ -1130,11 +1130,12 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname, | ||||
| 	 * sure to find the device. | ||||
| 	 */ | ||||
| 	if (try_dev_scan) { | ||||
| 		log_debug("Repeat dev cache scan to translate devnos."); | ||||
| 		dev_cache_scan(cmd); | ||||
| 		dm_list_iterate_items(po, &pvs_online) { | ||||
| 			if (po->dev) | ||||
| 				continue; | ||||
| 			if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno, NULL, NULL))) { | ||||
| 			if (!(po->dev = dev_cache_get_by_devt(cmd, po->devno))) { | ||||
| 				log_error("No device found for %d:%d PVID %s", | ||||
| 					  (int)MAJOR(po->devno), (int)MINOR(po->devno), po->pvid); | ||||
| 				goto bad; | ||||
| @@ -1722,7 +1723,7 @@ void label_scan_invalidate_lv(struct cmd_context *cmd, struct logical_volume *lv | ||||
| 	if (lv_info(cmd, lv, 0, &lvinfo, 0, 0) && lvinfo.exists) { | ||||
| 		/* FIXME: Still unclear what is it supposed to find */ | ||||
| 		devt = MKDEV(lvinfo.major, lvinfo.minor); | ||||
| 		if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL))) | ||||
| 		if ((dev = dev_cache_get_by_devt(cmd, devt))) | ||||
| 			label_scan_invalidate(dev); | ||||
| 	} | ||||
| } | ||||
| @@ -1736,13 +1737,19 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs) | ||||
| 	struct lv_list *lvl; | ||||
| 	dev_t devt; | ||||
|  | ||||
| 	/* | ||||
| 	 * FIXME: this is all unnecessary unless there are PVs stacked on LVs, | ||||
| 	 * so we can skip all of this if scan_lvs=0. | ||||
| 	 */ | ||||
| 	log_debug("invalidating devs for any pvs on lvs"); | ||||
|  | ||||
| 	if (get_device_list(NULL, &devs, &devs_features)) { | ||||
| 		if (devs_features & DM_DEVICE_LIST_HAS_UUID) { | ||||
| 			dm_list_iterate_items(dm_dev, devs) | ||||
| 				if (dm_dev->uuid && | ||||
| 				    strncmp(dm_dev->uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1) == 0) { | ||||
| 					devt = MKDEV(dm_dev->major, dm_dev->minor); | ||||
| 					if ((dev = dev_cache_get_by_devt(cmd, devt, NULL, NULL))) | ||||
| 					if ((dev = dev_cache_get_by_devt(cmd, devt))) | ||||
| 						label_scan_invalidate(dev); | ||||
| 				} | ||||
| 			/* ATM no further caching for any lvconvert command | ||||
| @@ -1879,10 +1886,24 @@ int label_scan_open_rw(struct device *dev) | ||||
|  | ||||
| int label_scan_reopen_rw(struct device *dev) | ||||
| { | ||||
| 	const char *name; | ||||
| 	int flags = 0; | ||||
| 	int prev_fd = dev->bcache_fd; | ||||
| 	int fd; | ||||
|  | ||||
| 	if (dm_list_empty(&dev->aliases)) { | ||||
| 		log_error("Cannot reopen rw device %d:%d with no valid paths di %d fd %d.", | ||||
| 			  (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	name = dev_name(dev); | ||||
| 	if (!name || name[0] != '/') { | ||||
| 		log_error("Cannot reopen rw device %d:%d with no valid name di %d fd %d.", | ||||
| 			  (int)MAJOR(dev->dev), (int)MINOR(dev->dev), dev->bcache_di, dev->bcache_fd); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!(dev->flags & DEV_IN_BCACHE)) { | ||||
| 		if ((dev->bcache_fd != -1) || (dev->bcache_di != -1)) { | ||||
| 			/* shouldn't happen */ | ||||
| @@ -1912,7 +1933,7 @@ int label_scan_reopen_rw(struct device *dev) | ||||
| 	flags |= O_NOATIME; | ||||
| 	flags |= O_RDWR; | ||||
|  | ||||
| 	fd = open(dev_name(dev), flags, 0777); | ||||
| 	fd = open(name, flags, 0777); | ||||
| 	if (fd < 0) { | ||||
| 		log_error("Failed to open rw %s errno %d di %d fd %d.", | ||||
| 			  dev_name(dev), errno, dev->bcache_di, dev->bcache_fd); | ||||
|   | ||||
| @@ -272,6 +272,8 @@ static void _lockd_retrive_vg_pv_list(struct volume_group *vg, | ||||
|  | ||||
| 	i = 0; | ||||
| 	dm_list_iterate_items(pvl, &vg->pvs) { | ||||
| 		if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) | ||||
| 			continue; | ||||
| 		lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv)); | ||||
| 		if (!lock_pvs->path[i]) { | ||||
| 			log_error("Fail to allocate PV path for VG %s", vg->name); | ||||
| @@ -341,6 +343,8 @@ static void _lockd_retrive_lv_pv_list(struct volume_group *vg, | ||||
|  | ||||
| 	dm_list_iterate_items(pvl, &vg->pvs) { | ||||
| 		if (lv_is_on_pv(lv, pvl->pv)) { | ||||
| 			if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) | ||||
| 				continue; | ||||
| 			lock_pvs->path[i] = strdup(pv_dev_name(pvl->pv)); | ||||
| 			if (!lock_pvs->path[i]) { | ||||
| 				log_error("Fail to allocate PV path for LV %s/%s", | ||||
|   | ||||
| @@ -1231,14 +1231,23 @@ int remove_mirrors_from_segments(struct logical_volume *lv, | ||||
| const char *get_pvmove_pvname_from_lv_mirr(const struct logical_volume *lv_mirr) | ||||
| { | ||||
| 	struct lv_segment *seg; | ||||
| 	struct device *dev; | ||||
|  | ||||
| 	dm_list_iterate_items(seg, &lv_mirr->segments) { | ||||
| 		if (!seg_is_mirrored(seg)) | ||||
| 			continue; | ||||
| 		if (seg_type(seg, 0) == AREA_PV) | ||||
| 			return dev_name(seg_dev(seg, 0)); | ||||
| 		if (seg_type(seg, 0) == AREA_LV) | ||||
| 			return dev_name(seg_dev(first_seg(seg_lv(seg, 0)), 0)); | ||||
| 		if (seg_type(seg, 0) == AREA_PV) { | ||||
| 			dev = seg_dev(seg, 0); | ||||
| 			if (!dev || dm_list_empty(&dev->aliases)) | ||||
| 				return NULL; | ||||
| 			return dev_name(dev); | ||||
| 		} | ||||
| 		if (seg_type(seg, 0) == AREA_LV) { | ||||
| 			dev = seg_dev(first_seg(seg_lv(seg, 0)), 0); | ||||
| 			if (!dev || dm_list_empty(&dev->aliases)) | ||||
| 				return NULL; | ||||
| 			return dev_name(dev); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return NULL; | ||||
|   | ||||
| @@ -152,6 +152,11 @@ static int _create_pv_entry(struct dm_pool *mem, struct pv_list *pvl, | ||||
| 	struct pv_list *new_pvl = NULL, *pvl2; | ||||
| 	struct dm_list *pe_ranges; | ||||
|  | ||||
| 	if (!pvl->pv->dev || dm_list_empty(&pvl->pv->dev->aliases)) { | ||||
| 		log_error("Failed to create PV entry for missing device."); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	pvname = pv_dev_name(pvl->pv); | ||||
| 	if (allocatable_only && !(pvl->pv->status & ALLOCATABLE_PV)) { | ||||
| 		log_warn("WARNING: Physical volume %s not allocatable.", pvname); | ||||
|   | ||||
| @@ -679,6 +679,11 @@ int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg, | ||||
| 		return r; | ||||
| 	} | ||||
|  | ||||
| 	if (!pv->dev || dm_list_empty(&pv->dev->aliases)) { | ||||
| 		log_error("No device found for PV."); | ||||
| 		return r; | ||||
| 	} | ||||
|  | ||||
| 	log_debug("vgreduce_single VG %s PV %s", vg->name, pv_dev_name(pv)); | ||||
|  | ||||
| 	if (pv_pe_alloc_count(pv)) { | ||||
|   | ||||
| @@ -33,6 +33,8 @@ aux udev_wait | ||||
| ls -la "${LOOP}"* | ||||
| test -e "${LOOP}p1" | ||||
|  | ||||
| aux lvmconf 'devices/scan = "/dev"' | ||||
|  | ||||
| aux extend_filter "a|$LOOP|" | ||||
| aux extend_devices "$LOOP" | ||||
|  | ||||
|   | ||||
| @@ -1488,7 +1488,7 @@ int process_each_label(struct cmd_context *cmd, int argc, char **argv, | ||||
| 				goto out; | ||||
| 			} | ||||
|  | ||||
| 			if (!(dev = dev_cache_get(cmd, argv[opt], cmd->filter))) { | ||||
| 			if (!(dev = dev_cache_get_existing(cmd, argv[opt], cmd->filter))) { | ||||
| 				log_error("Failed to find device " | ||||
| 					  "\"%s\".", argv[opt]); | ||||
| 				ret_max = ECMD_FAILED; | ||||
| @@ -3925,7 +3925,7 @@ static int _get_arg_devices(struct cmd_context *cmd, | ||||
| 			return ECMD_FAILED; | ||||
| 		} | ||||
|  | ||||
| 		if (!(dil->dev = dev_cache_get(cmd, sl->str, cmd->filter))) { | ||||
| 		if (!(dil->dev = dev_cache_get_existing(cmd, sl->str, cmd->filter))) { | ||||
| 			log_error("Cannot use %s: %s", sl->str, devname_error_reason(sl->str)); | ||||
| 			ret_max = EINIT_FAILED; | ||||
| 		} else { | ||||
| @@ -5261,7 +5261,7 @@ int pvcreate_each_device(struct cmd_context *cmd, | ||||
| 		struct device *dev; | ||||
|  | ||||
| 		/* No filter used here */ | ||||
| 		if (!(dev = dev_cache_get(cmd, pd->name, NULL))) { | ||||
| 		if (!(dev = dev_cache_get_existing(cmd, pd->name, NULL))) { | ||||
| 			log_error("No device found for %s.", pd->name); | ||||
| 			dm_list_del(&pd->list); | ||||
| 			dm_list_add(&pp->arg_fail, &pd->list); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user