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