Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a fault-injection with fs freeze #110

Open
ligurio opened this issue Apr 22, 2022 · 0 comments
Open

Add a fault-injection with fs freeze #110

ligurio opened this issue Apr 22, 2022 · 0 comments

Comments

@ligurio
Copy link
Owner

ligurio commented Apr 22, 2022

fsfreeze(8):

fsfreeze suspends or resumes access to a filesystem.

fsfreeze halts any new access to the filesystem and creates a
stable image on disk. fsfreeze is intended to be used with
hardware RAID devices that support the creation of snapshots.

Filesystem freeze and unfreeze allows backup systems to snapshot a consistent state.

Behavior:

  • Suspend writes
    • Including all vfs I/O submission APIs and mmap I/O (the latter only since Linux 3.0)
    • We need to get the metadata and journal out, so there are several special cases for them
  • Sync filesystem
  • Call filesystem specific freeze function
  • Used to be a xfs specific ioctl but is now a VFS interface

VFS API

  • Freeze: ioctl(fd, FIFREEZE, 0)
  • Thaw: ioctl(fd, FITHAW, 0)

New filesystem freeze API

  • FIISFROZEN: vfs ioctl to check freeze state
  • BLKISFROZEN: add block device ioctl to check freeze state
  • Useful to thaw unmounted frozen filesystems
  • Might get rid of this if returning EBUSY when trying to unmount a frozen filesystem is acceptable
  • FIGETFREEZEFD: freezes the indicated filesystem and returns a file descriptor; as long as that file descriptor is held open, the filesystem remains open
  • Since the filesytem is automatically thawed when the file descriptor is closed, if the agent goes away the filesystem will be automagically thawed by kernel
  • Filesystem freeze fs ioctls: FS_FREEZE_FD, FS_THAW_FD, FS_ISFROZEN_FD
  • Added new parameter to FIGETFREEZEFD ioctl to indicate whether the filesystem should be frozen on fd open
  • Useful when you are trying to restart the agent

See New Filesystem Freeze API (PDF)

https://github.com/util-linux/util-linux/blob/ef7d50a0cc59d3b55587c8ea5fa45db45b888aee/sys-utils/fsfreeze.c#L118-L140

	if (fstat(fd, &sb) == -1) {
		warn(_("stat of %s failed"), path);
		goto done;
	}

	if (!S_ISDIR(sb.st_mode)) {
		warnx(_("%s: is not a directory"), path);
		goto done;
	}

	switch (action) {
	case FREEZE:
		if (ioctl(fd, FIFREEZE, 0)) {
			warn(_("%s: freeze failed"), path);
			goto done;
		}
		break;
	case UNFREEZE:
		if (ioctl(fd, FITHAW, 0)) {
			warn(_("%s: unfreeze failed"), path);
			goto done;
		}
		break;

https://github.com/qemu/qemu/blob/master/qga/commands-posix.c

        /* we try to cull filesystems we know won't work in advance, but other
         * filesystems may not implement fsfreeze for less obvious reasons.
         * these will report EOPNOTSUPP. we simply ignore these when tallying
         * the number of frozen filesystems.
         * if a filesystem is mounted more than once (aka bind mount) a
         * consecutive attempt to freeze an already frozen filesystem will
         * return EBUSY.
         *
         * any other error means a failure to freeze a filesystem we
         * expect to be freezable, so return an error in those cases
         * and return system to thawed state.
         */
        ret = ioctl(fd, FIFREEZE);
        if (ret == -1) {
            if (errno != EOPNOTSUPP && errno != EBUSY) {
                error_setg_errno(errp, errno, "failed to freeze %s",
                                 mount->dirname);
                close(fd);
                goto error;
            }
        } else {
            i++;
        }
        close(fd);

...

        /* we have no way of knowing whether a filesystem was actually unfrozen
         * as a result of a successful call to FITHAW, only that if an error
         * was returned the filesystem was *not* unfrozen by that particular
         * call.
         *
         * since multiple preceding FIFREEZEs require multiple calls to FITHAW
         * to unfreeze, continuing issuing FITHAW until an error is returned,
         * in which case either the filesystem is in an unfreezable state, or,
         * more likely, it was thawed previously (and remains so afterward).
         *
         * also, since the most recent successful call is the one that did
         * the actual unfreeze, we can use this to provide an accurate count
         * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which
         * may * be useful for determining whether a filesystem was unfrozen
         * during the freeze/thaw phase by a process other than qemu-ga.
         */
        do {
            ret = ioctl(fd, FITHAW);
            if (ret == 0 && !logged) {
                i++;
                logged = true;
            }
        } while (ret == 0);
        close(fd);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant