diff options
author | Karel Zak | 2016-05-26 12:02:12 +0200 |
---|---|---|
committer | Karel Zak | 2016-05-26 12:15:26 +0200 |
commit | 924c93d9df118338fd54cd73b4a45ccddc4ac103 (patch) | |
tree | 2538ad30217f7771cd76a59f19e649a78de6c1ee | |
parent | lsblk: use ID_WWN_WITH_EXTENSION is possible (diff) | |
download | kernel-qcow2-util-linux-924c93d9df118338fd54cd73b4a45ccddc4ac103.tar.gz kernel-qcow2-util-linux-924c93d9df118338fd54cd73b4a45ccddc4ac103.tar.xz kernel-qcow2-util-linux-924c93d9df118338fd54cd73b4a45ccddc4ac103.zip |
libblkid: store only canonical devnames to the cache
Let's try to use symlink:
# ls -la /dev/block/8\:1
# lrwxrwxrwx 1 root root 7 May 25 16:42 /dev/block/8:1 -> ../sda1
# blkid /dev/block/8:1
/dev/block/8:3: LABEL="HOME" UUID="196972ad-3b13-4bba-ac54-4cb3f7b409a4" TYPE="ext4" PARTUUID="6073277f-87bc-43ff-bcfd-724c4484a63a"
unfortunately the symlink is stored to the cache:
<device DEVNO="0x0803" TIME="1464253300.715279" LABEL="HOME" UUID="196972ad-3b13-4bba-ac54-4cb3f7b409a4" TYPE="ext4" PARTUUID="6073277f-87bc-43ff-bcfd-724c4484a63a">/dev/block/8:3</device>
next time if you ask for LABEL=HOME the answer will be /dev/block/8:3
rather than /dev/sda3.
It seems better to canonicalize the paths we store to the cache.
Unfortunately if you ask for /dev/block/8:3 then you probably expect
that blkid_dev_devname() returns the same path. This patch introduces
dev->bid_xname, this is the path used by application (and never stored
in the cache).
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1332779
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | libblkid/src/blkidP.h | 3 | ||||
-rw-r--r-- | libblkid/src/dev.c | 11 | ||||
-rw-r--r-- | libblkid/src/devname.c | 43 |
3 files changed, 48 insertions, 9 deletions
diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h index e298b41dd..68204233d 100644 --- a/libblkid/src/blkidP.h +++ b/libblkid/src/blkidP.h @@ -42,7 +42,8 @@ struct blkid_struct_dev struct list_head bid_devs; /* All devices in the cache */ struct list_head bid_tags; /* All tags for this device */ blkid_cache bid_cache; /* Dev belongs to this cache */ - char *bid_name; /* Device inode pathname */ + char *bid_name; /* Device real pathn (as used in cache) */ + char *bid_xname; /* Device path as used by application (maybe symlink..) */ char *bid_type; /* Preferred device TYPE */ int bid_pri; /* Device priority */ dev_t bid_devno; /* Device major/minor number */ diff --git a/libblkid/src/dev.c b/libblkid/src/dev.c index f35895da9..b5ad0f115 100644 --- a/libblkid/src/dev.c +++ b/libblkid/src/dev.c @@ -58,16 +58,23 @@ void blkid_free_dev(blkid_dev dev) bit_tags); blkid_free_tag(tag); } + free(dev->bid_xname); free(dev->bid_name); free(dev); } /* - * Given a blkid device, return its name + * Given a blkid device, return its name. The function returns the name + * previously used for blkid_get_dev(). This name does not have to be canonical + * (real path) name, but for example symlink. */ const char *blkid_dev_devname(blkid_dev dev) { - return dev ? dev->bid_name : NULL; + if (!dev) + return NULL; + if (dev->bid_xname) + return dev->bid_xname; + return dev->bid_name; } void blkid_debug_dump_dev(blkid_dev dev) diff --git a/libblkid/src/devname.c b/libblkid/src/devname.c index dbbe5b54d..2e5f4f151 100644 --- a/libblkid/src/devname.c +++ b/libblkid/src/devname.c @@ -50,28 +50,55 @@ blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags) { blkid_dev dev = NULL, tmp; struct list_head *p, *pnext; + char *cn = NULL; if (!cache || !devname) return NULL; + /* search by name */ list_for_each(p, &cache->bic_devs) { tmp = list_entry(p, struct blkid_struct_dev, bid_devs); if (strcmp(tmp->bid_name, devname)) continue; - - DBG(DEVNAME, ul_debug("found devname %s in cache", tmp->bid_name)); dev = tmp; break; } + /* try canonicalize the name */ + if (!dev && (cn = canonicalize_path(devname))) { + if (strcmp(cn, devname) != 0) { + DBG(DEVNAME, ul_debug("search cannonical %s", cn)); + list_for_each(p, &cache->bic_devs) { + tmp = list_entry(p, struct blkid_struct_dev, bid_devs); + if (strcmp(tmp->bid_name, cn)) + continue; + dev = tmp; + + /* update name returned by blkid_dev_devname() */ + free(dev->bid_xname); + dev->bid_xname = strdup(devname); + break; + } + } else { + free(cn); + cn = NULL; + } + } + if (!dev && (flags & BLKID_DEV_CREATE)) { if (access(devname, F_OK) < 0) - return NULL; + goto done; dev = blkid_new_dev(); if (!dev) - return NULL; + goto done; dev->bid_time = INT_MIN; - dev->bid_name = strdup(devname); + if (cn) { + dev->bid_name = cn; + dev->bid_xname = strdup(devname); + cn = NULL; /* see free() below */ + } else + dev->bid_name = strdup(devname); + dev->bid_cache = cache; list_add_tail(&dev->bid_devs, &cache->bic_devs); cache->bic_flags |= BLKID_BIC_FL_CHANGED; @@ -80,7 +107,7 @@ blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags) if (flags & BLKID_DEV_VERIFY) { dev = blkid_verify(cache, dev); if (!dev || !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) - return dev; + goto done; /* * If the device is verified, then search the blkid * cache for any entries that match on the type, uuid, @@ -111,6 +138,10 @@ blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags) blkid_free_dev(dev2); } } +done: + if (dev) + DBG(DEVNAME, ul_debug("%s requested, found %s in cache", devname, dev->bid_name)); + free(cn); return dev; } |