1*8a272653SPeter Holm#!/bin/sh 2*8a272653SPeter Holm 3*8a272653SPeter Holm# ioctl(g_ufs_suspend_handle, UFSSUSPEND, &statfsp->f_fsid) test scenario. 4*8a272653SPeter Holm 5*8a272653SPeter Holm# Bug 230220 - UFS: the freezing ioctl (i.e.UFSSUSPEND) causes panic or EBUSY 6*8a272653SPeter Holm# "panic: devfs_set_cdevpriv failed" seen. 7*8a272653SPeter Holm# Test scenario by Dexuan Cui <decui microsoft com> 8*8a272653SPeter Holm# Fixed by r337055. 9*8a272653SPeter Holm 10*8a272653SPeter Holm[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 11*8a272653SPeter Holm. ../default.cfg 12*8a272653SPeter Holm 13*8a272653SPeter Holmcat > /tmp/ufssuspend.c <<EOF 14*8a272653SPeter Holm 15*8a272653SPeter Holm#include <sys/types.h> 16*8a272653SPeter Holm#include <sys/ioctl.h> 17*8a272653SPeter Holm#include <sys/param.h> 18*8a272653SPeter Holm#include <sys/ucred.h> 19*8a272653SPeter Holm#include <sys/mount.h> 20*8a272653SPeter Holm 21*8a272653SPeter Holm#include <ufs/ffs/fs.h> 22*8a272653SPeter Holm 23*8a272653SPeter Holm#include <err.h> 24*8a272653SPeter Holm#include <errno.h> 25*8a272653SPeter Holm#include <fcntl.h> 26*8a272653SPeter Holm#include <paths.h> 27*8a272653SPeter Holm#include <poll.h> 28*8a272653SPeter Holm#include <stdint.h> 29*8a272653SPeter Holm#include <stdio.h> 30*8a272653SPeter Holm#include <stdlib.h> 31*8a272653SPeter Holm#include <string.h> 32*8a272653SPeter Holm#include <sysexits.h> 33*8a272653SPeter Holm#include <syslog.h> 34*8a272653SPeter Holm#include <unistd.h> 35*8a272653SPeter Holm 36*8a272653SPeter Holmstatic int g_ufs_suspend_handle = -1; 37*8a272653SPeter Holmstatic const char *dev = "/dev"; 38*8a272653SPeter Holm 39*8a272653SPeter Holmstatic int 40*8a272653SPeter Holmfreeze(void) 41*8a272653SPeter Holm{ 42*8a272653SPeter Holm struct statfs *mntbuf, *statfsp; 43*8a272653SPeter Holm int mntsize; 44*8a272653SPeter Holm int error = 0; 45*8a272653SPeter Holm int i; 46*8a272653SPeter Holm 47*8a272653SPeter Holm g_ufs_suspend_handle = open(_PATH_UFSSUSPEND, O_RDWR); 48*8a272653SPeter Holm if (g_ufs_suspend_handle == -1) { 49*8a272653SPeter Holm printf("unable to open %s", _PATH_UFSSUSPEND); 50*8a272653SPeter Holm return (errno); 51*8a272653SPeter Holm } 52*8a272653SPeter Holm 53*8a272653SPeter Holm mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 54*8a272653SPeter Holm if (mntsize == 0) { 55*8a272653SPeter Holm printf("There is no mount information\n"); 56*8a272653SPeter Holm return (EINVAL); 57*8a272653SPeter Holm } 58*8a272653SPeter Holm 59*8a272653SPeter Holm for (i = mntsize - 1; i >= 0; --i) { 60*8a272653SPeter Holm statfsp = &mntbuf[i]; 61*8a272653SPeter Holm 62*8a272653SPeter Holm if (strncmp(statfsp->f_mntonname, dev, strlen(dev)) == 0) 63*8a272653SPeter Holm continue; /* skip to freeze '/dev' */ 64*8a272653SPeter Holm 65*8a272653SPeter Holm if (statfsp->f_flags & MNT_RDONLY) 66*8a272653SPeter Holm continue; /* skip to freeze RDONLY partition */ 67*8a272653SPeter Holm 68*8a272653SPeter Holm if (strncmp(statfsp->f_fstypename, "ufs", 3) != 0) 69*8a272653SPeter Holm continue; /* so far, only UFS can be frozen */ 70*8a272653SPeter Holm 71*8a272653SPeter Holm printf("suspending fs: %s\n", statfsp->f_mntonname); 72*8a272653SPeter Holm error = ioctl(g_ufs_suspend_handle, UFSSUSPEND, &statfsp->f_fsid); 73*8a272653SPeter Holm if (error != 0) { 74*8a272653SPeter Holm printf("error: %d\n", errno); 75*8a272653SPeter Holm error = errno; 76*8a272653SPeter Holm } else { 77*8a272653SPeter Holm printf("Successfully suspend fs: %s\n", statfsp->f_mntonname); 78*8a272653SPeter Holm } 79*8a272653SPeter Holm } 80*8a272653SPeter Holm 81*8a272653SPeter Holm return (error); 82*8a272653SPeter Holm} 83*8a272653SPeter Holm 84*8a272653SPeter Holm/** 85*8a272653SPeter Holm * closing the opened handle will thaw the FS. 86*8a272653SPeter Holm */ 87*8a272653SPeter Holmstatic int 88*8a272653SPeter Holmthaw(void) 89*8a272653SPeter Holm{ 90*8a272653SPeter Holm int error = 0; 91*8a272653SPeter Holm 92*8a272653SPeter Holm if (g_ufs_suspend_handle != -1) { 93*8a272653SPeter Holm error = close(g_ufs_suspend_handle); 94*8a272653SPeter Holm if (!error) { 95*8a272653SPeter Holm g_ufs_suspend_handle = -1; 96*8a272653SPeter Holm printf("Successfully thaw the fs\n"); 97*8a272653SPeter Holm } else { 98*8a272653SPeter Holm error = errno; 99*8a272653SPeter Holm printf("Fail to thaw the fs: " 100*8a272653SPeter Holm "%d %s\n", errno, strerror(errno)); 101*8a272653SPeter Holm } 102*8a272653SPeter Holm } else { 103*8a272653SPeter Holm printf("The fs has already been thawed\n\n"); 104*8a272653SPeter Holm } 105*8a272653SPeter Holm 106*8a272653SPeter Holm return (error); 107*8a272653SPeter Holm} 108*8a272653SPeter Holm 109*8a272653SPeter Holmint 110*8a272653SPeter Holmmain(void) 111*8a272653SPeter Holm{ 112*8a272653SPeter Holm int error; 113*8a272653SPeter Holm 114*8a272653SPeter Holm error = freeze(); 115*8a272653SPeter Holm printf("freeze: err=%d\n", error); 116*8a272653SPeter Holm 117*8a272653SPeter Holm error = thaw(); 118*8a272653SPeter Holm printf("thaw: err=%d\n", error); 119*8a272653SPeter Holm 120*8a272653SPeter Holm return 0; 121*8a272653SPeter Holm} 122*8a272653SPeter HolmEOF 123*8a272653SPeter Holm 124*8a272653SPeter Holmmycc -o /tmp/ufssuspend -Wall -Wextra -O2 -g /tmp/ufssuspend.c || exit 1 125*8a272653SPeter Holmrm /tmp/ufssuspend.c 126*8a272653SPeter Holm 127*8a272653SPeter Holmcd /tmp 128*8a272653SPeter Holm./ufssuspend > /dev/null 129*8a272653SPeter Holms=$? 130*8a272653SPeter Holmrm /tmp/ufssuspend 131*8a272653SPeter Holmexit $s 132