From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35570) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VhMTO-0005n4-Oh for qemu-devel@nongnu.org; Fri, 15 Nov 2013 11:42:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VhMTH-0000l1-4a for qemu-devel@nongnu.org; Fri, 15 Nov 2013 11:42:22 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38486) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VhMTG-0000kh-N8 for qemu-devel@nongnu.org; Fri, 15 Nov 2013 11:42:15 -0500 Message-ID: <52864EEE.3000900@redhat.com> Date: Fri, 15 Nov 2013 17:42:22 +0100 From: Max Reitz MIME-Version: 1.0 References: <52864C79.20800@gmail.com> In-Reply-To: <52864C79.20800@gmail.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH] HMP: snapshot_blkdev can not consider //root/sn1 and /root/sn1 as the same file List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: lijun , qemu-devel@nongnu.org Cc: lcapitulino@redhat.com On 15.11.2013 17:31, lijun wrote: > From: Jun Li > > 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 =93.=94 and =93..=94 in it =96 or even just a hardlink. Thus, t= o 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 > > --- 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 =3D qdict_get_str(qdict, "device"); > const char *filename =3D qdict_get_try_str(qdict, "snapshot-file"); > + const char *p =3D filename; > const char *format =3D qdict_get_try_str(qdict, "format"); > int reuse =3D qdict_get_try_bool(qdict, "reuse", 0); > enum NewImageMode mode; > Error *errp =3D NULL; > + int count =3D 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 !=3D '\0') { > + if (*p =3D=3D '/') { > + while (*(p + count++) =3D=3D '/') { > + /* 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 =3D 1; > + } > + p++; > + } > + > mode =3D reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATH= S; > qmp_blockdev_snapshot_sync(device, filename, !!format, format, > true, mode, &errp); >