On 15.11.2013 17:31, lijun wrote: > From: Jun Li <junm...@gmail.com> > > Hi all, > > snapshot_blkdev can not consider //root/sn1 and /root/sn1 as the same > file. when file /root/sn1 is the base file, do snapshot using file > //root/sn1, qemu consider it as a new file. So this will rewrite the > base file.
Actually, the same problem can occur anyway if you have a path with a couple of “.” and “..” in it – or even just a hardlink. Thus, to be completely safe, we'd have to check whether the snapshot file (if it already exists) has a different inode number and/or is located on a different filesystem. > Signed-off-by: Jun Li <junm...@gmail.com> > > --- a/hmp.c 2013-11-15 23:15:46.733361130 +0800 > +++ b/hmp.c 2013-11-16 00:20:23.972248509 +0800 > @@ -957,10 +957,12 @@ void hmp_snapshot_blkdev(Monitor *mon, c > { > const char *device = qdict_get_str(qdict, "device"); > const char *filename = qdict_get_try_str(qdict, "snapshot-file"); > + const char *p = filename; > const char *format = qdict_get_try_str(qdict, "format"); > int reuse = qdict_get_try_bool(qdict, "reuse", 0); > enum NewImageMode mode; > Error *errp = NULL; > + int count = 1; > > if (!filename) { > /* In the future, if 'snapshot-file' is not specified, the snapshot > @@ -970,6 +972,18 @@ void hmp_snapshot_blkdev(Monitor *mon, c > return; > } > > + /* Delete duplicate '/' in filename. */ > + while (*p != '\0') { > + if (*p == '/') { > + while (*(p + count++) == '/') { > + /* do null. */ > + } > + strcpy((char *)(p + 1), (char *)(p + count - 1)); Casting a const char * to a char * seems very bogus to me. Using g_strdup or something before is probably a better idea. Also, don't use strcpy but memmove (since both strings overlap). All in all, using realpath() is probably the better idea anyway (it'd also resolve the . and .. problem (and symlinks), though it still won't prevent hardlinks from messing things up). Max > + count = 1; > + } > + p++; > + } > + > mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS; > qmp_blockdev_snapshot_sync(device, filename, !!format, format, > true, mode, &errp); >