tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

st_dev and st_ino addition to mtree(8) spec



Hi list,

The attached small patch implements two new keywords within mtree(8): "devid" and "inode".

"devid" allows to log the device on which the entry is found (it corresponds
to the st_dev from stat(2)), while "inode" is, well, the inode number.

"devid" is somehow problematic as we have a clash with another keyword,
"device". So if you are not really fond of the name, I would be happy
to change it to whatever you like provided it reduces confusion.

The purpose is to store an identifier for an entry that can uniquely
identify a resource on the system. In my case, when combined with "nlink",
I can use a mtree spec to resolve hardlinks, while this was rather
tedious before. You could enumerate them through "nlink", but without knowing
the inode it points to from the spec it was barely useful.

As mtree(8) is now a binary shared between FreeBSD and NetBSD, I prefer
to submit this small patch for review first before committing. There are maybe issues I have not taken care of. Without further remarks on it after a a few
days (say 3), I will commit it.

Disclaimer: This patch is contributed by the French Network and Information Security Agency under the BSD 2-clause license approved by The NetBSD Foundation.

Cheers,

--
Jean-Yves Migeon
diff --git a/usr.sbin/mtree/compare.c b/usr.sbin/mtree/compare.c
index d2389e6..a8c2cb5 100644
--- a/usr.sbin/mtree/compare.c
+++ b/usr.sbin/mtree/compare.c
@@ -274,6 +274,19 @@ typeerr:           LABEL;
                tab = "\t";
        skip:   ;
        }
+       if (s->flags & F_STDEV && s->st_dev != p->fts_statp->st_dev) {
+               LABEL;
+               printf("%sdevice ID (%#llu, %#llu)\n",
+                   tab, (long long)s->st_dev,
+                   (long long)p->fts_statp->st_dev);
+               tab = "\t";
+       }
+       if (s->flags & F_STINO && s->st_ino != p->fts_statp->st_ino) {
+               LABEL;
+               printf("%sinode number (%llu, %llu)\n",
+                   tab, s->st_ino, p->fts_statp->st_ino);
+               tab = "\t";
+       }
        if (s->flags & F_NLINK && s->type != F_DIR &&
            s->st_nlink != p->fts_statp->st_nlink) {
                LABEL;
diff --git a/usr.sbin/mtree/create.c b/usr.sbin/mtree/create.c
index 10306f9..9398da6 100644
--- a/usr.sbin/mtree/create.c
+++ b/usr.sbin/mtree/create.c
@@ -218,6 +218,12 @@ statf(int indent, FTSENT *p)
            (S_ISBLK(p->fts_statp->st_mode) || S_ISCHR(p->fts_statp->st_mode)))
                output(indent, &offset, "device=%#llx",
                    (long long)p->fts_statp->st_rdev);
+       if (keys & F_STDEV)
+               output(indent, &offset, "devid=%#llu",
+                   (long long)p->fts_statp->st_dev);
+       if (keys & F_STINO)
+               output(indent, &offset, "inode=%llu",
+                   (long long)p->fts_statp->st_ino);
        if (keys & F_NLINK && p->fts_statp->st_nlink != 1)
                output(indent, &offset, "nlink=%u", p->fts_statp->st_nlink);
        if (keys & F_SIZE &&
diff --git a/usr.sbin/mtree/misc.c b/usr.sbin/mtree/misc.c
index b99f1ce..338a0f1 100644
--- a/usr.sbin/mtree/misc.c
+++ b/usr.sbin/mtree/misc.c
@@ -63,11 +63,13 @@ typedef struct _key {
 /* NB: the following tables must be sorted lexically. */
 static KEY keylist[] = {
        {"cksum",       F_CKSUM,        NEEDVALUE},
+       {"devid",       F_STDEV,        NEEDVALUE},
        {"device",      F_DEV,          NEEDVALUE},
        {"flags",       F_FLAGS,        NEEDVALUE},
        {"gid",         F_GID,          NEEDVALUE},
        {"gname",       F_GNAME,        NEEDVALUE},
        {"ignore",      F_IGN,          0},
+       {"inode",       F_STINO,        NEEDVALUE},
        {"link",        F_SLINK,        NEEDVALUE},
        {"md5",         F_MD5,          NEEDVALUE},
        {"md5digest",   F_MD5,          NEEDVALUE},
diff --git a/usr.sbin/mtree/mtree.h b/usr.sbin/mtree/mtree.h
index 93d6cdf..73563ca 100644
--- a/usr.sbin/mtree/mtree.h
+++ b/usr.sbin/mtree/mtree.h
@@ -51,6 +51,8 @@ typedef struct _node {
        mode_t  st_mode;                        /* mode */
        dev_t   st_rdev;                        /* device type */
        u_long  st_flags;                       /* flags */
+       dev_t   st_dev;                         /* device ID containing node */
+       ino_t   st_ino;                         /* inode number */
        nlink_t st_nlink;                       /* link count */
        u_long  cksum;                          /* check sum */
        char    *md5digest;                     /* MD5 digest */
@@ -92,6 +94,9 @@ typedef struct _node {
 #define        F_SHA384        0x01000000              /* SHA384 digest */
 #define        F_SHA512        0x02000000              /* SHA512 digest */
 
+#define        F_STINO         0x04000000              /* inode number */
+#define        F_STDEV         0x08000000              /* device ID containing 
node */
+
        int     flags;                          /* items set */
 
 #define        F_BLOCK 0x001                           /* block special */
diff --git a/usr.sbin/mtree/spec.c b/usr.sbin/mtree/spec.c
index 3500b2f..e748faf 100644
--- a/usr.sbin/mtree/spec.c
+++ b/usr.sbin/mtree/spec.c
@@ -351,6 +351,10 @@ dump_nodes(const char *dir, NODE *root, int pathlast)
                if (MATCHFLAG(F_DEV) &&
                    (cur->type == F_BLOCK || cur->type == F_CHAR))
                        appendfield(pathlast, "device=%#llx", (long 
long)cur->st_rdev);
+               if (MATCHFLAG(F_STDEV))
+                       appendfield(pathlast, "devid=%#llu", (long 
long)cur->st_dev);
+               if (MATCHFLAG(F_STINO))
+                       appendfield(pathlast, "inode=%llu", cur->st_ino);
                if (MATCHFLAG(F_NLINK))
                        appendfield(pathlast, "nlink=%d", cur->st_nlink);
                if (MATCHFLAG(F_SLINK))
@@ -586,6 +590,16 @@ set(char *t, NODE *ip)
                        ip->st_mode = getmode(m, 0);
                        free(m);
                        break;
+               case F_STDEV:
+                       ip->st_dev = (dev_t)strtoul(val, &ep, 0);
+                       if (*ep)
+                               mtree_err("invalid device ID `%s'", val);
+                       break;
+               case F_STINO:
+                       ip->st_ino = (ino_t)strtoull(val, &ep, 10);
+                       if (*ep)
+                               mtree_err("invalid inode number `%s'", val);
+                       break;
                case F_NLINK:
                        ip->st_nlink = (nlink_t)strtoul(val, &ep, 10);
                        if (*ep)
diff --git a/usr.sbin/mtree/specspec.c b/usr.sbin/mtree/specspec.c
index 2821fd1..011b2bc 100644
--- a/usr.sbin/mtree/specspec.c
+++ b/usr.sbin/mtree/specspec.c
@@ -72,6 +72,10 @@ shownode(NODE *n, int f, char const *path)
        }
        if (f & F_MODE)
                printf(" mode=%o", n->st_mode);
+       if (f & F_STDEV)
+               printf(" devid=%#llu", (long long)n->st_dev);
+       if (f & F_STINO)
+               printf(" inode=%llu", n->st_ino);
        if (f & F_NLINK)
                printf(" nlink=%d", n->st_nlink);
        if (f & F_SIZE)
@@ -128,7 +132,7 @@ static int
 compare_nodes(NODE *n1, NODE *n2, char const *path)
 {
        int differs;
-       
+
        if (n1 != NULL && n1->type == F_LINK)
                n1->flags &= ~F_MODE;
        if (n2 != NULL && n2->type == F_LINK)
@@ -157,6 +161,10 @@ compare_nodes(NODE *n1, NODE *n2, char const *path)
                differs |= F_GNAME;
        if (FF(n1, n2, F_MODE, st_mode))
                differs |= F_MODE;
+       if (FF(n1, n2, F_STDEV, st_dev))
+               differs |= F_STDEV;
+       if (FF(n1, n2, F_STINO, st_ino))
+               differs |= F_STINO;
        if (FF(n1, n2, F_NLINK, st_nlink))
                differs |= F_NLINK;
        if (FF(n1, n2, F_SIZE, st_size))


Home | Main Index | Thread Index | Old Index