(root)/
util-linux-2.39/
sys-utils/
fsfreeze.c
       1  /*
       2   * fsfreeze.c -- Filesystem freeze/unfreeze IO for Linux
       3   *
       4   * Copyright (C) 2010 Hajime Taira <htaira@redhat.com>
       5   *                    Masatake Yamato <yamato@redhat.com>
       6   *
       7   * This program is free software.  You can redistribute it and/or
       8   * modify it under the terms of the GNU General Public License as
       9   * published by the Free Software Foundation: either version 1 or
      10   * (at your option) any later version.
      11   */
      12  
      13  #include <stdio.h>
      14  #include <stdlib.h>
      15  #include <errno.h>
      16  #include <string.h>
      17  #include <fcntl.h>
      18  #include <linux/fs.h>
      19  #include <sys/ioctl.h>
      20  #include <sys/types.h>
      21  #include <sys/stat.h>
      22  #include <getopt.h>
      23  
      24  #include "c.h"
      25  #include "blkdev.h"
      26  #include "nls.h"
      27  #include "closestream.h"
      28  #include "optutils.h"
      29  
      30  enum fs_operation {
      31  	NOOP,
      32  	FREEZE,
      33  	UNFREEZE
      34  };
      35  
      36  static void __attribute__((__noreturn__)) usage(void)
      37  {
      38  	FILE *out = stdout;
      39  	fputs(USAGE_HEADER, out);
      40  	fprintf(out,
      41  	      _(" %s [options] <mountpoint>\n"), program_invocation_short_name);
      42  
      43  	fputs(USAGE_SEPARATOR, out);
      44  	fputs(_("Suspend access to a filesystem.\n"), out);
      45  
      46  	fputs(USAGE_OPTIONS, out);
      47  	fputs(_(" -f, --freeze      freeze the filesystem\n"), out);
      48  	fputs(_(" -u, --unfreeze    unfreeze the filesystem\n"), out);
      49  	fputs(USAGE_SEPARATOR, out);
      50  	printf(USAGE_HELP_OPTIONS(19));
      51  	printf(USAGE_MAN_TAIL("fsfreeze(8)"));
      52  
      53  	exit(EXIT_SUCCESS);
      54  }
      55  
      56  int main(int argc, char **argv)
      57  {
      58  	int fd = -1, c;
      59  	int action = NOOP, rc = EXIT_FAILURE;
      60  	char *path;
      61  	struct stat sb;
      62  
      63  	static const struct option longopts[] = {
      64  	    { "help",      no_argument, NULL, 'h' },
      65  	    { "freeze",    no_argument, NULL, 'f' },
      66  	    { "unfreeze",  no_argument, NULL, 'u' },
      67  	    { "version",   no_argument, NULL, 'V' },
      68  	    { NULL, 0, NULL, 0 }
      69  	};
      70  
      71  	static const ul_excl_t excl[] = {       /* rows and cols in ASCII order */
      72  		{ 'f','u' },			/* freeze, unfreeze */
      73  		{ 0 }
      74  	};
      75  	int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
      76  
      77  	setlocale(LC_ALL, "");
      78  	bindtextdomain(PACKAGE, LOCALEDIR);
      79  	textdomain(PACKAGE);
      80  	close_stdout_atexit();
      81  
      82  	while ((c = getopt_long(argc, argv, "hfuV", longopts, NULL)) != -1) {
      83  
      84  		err_exclusive_options(c, longopts, excl, excl_st);
      85  
      86  		switch(c) {
      87  		case 'f':
      88  			action = FREEZE;
      89  			break;
      90  		case 'u':
      91  			action = UNFREEZE;
      92  			break;
      93  
      94  		case 'h':
      95  			usage();
      96  		case 'V':
      97  			print_version(EXIT_SUCCESS);
      98  		default:
      99  			errtryhelp(EXIT_FAILURE);
     100  		}
     101  	}
     102  
     103  	if (action == NOOP)
     104  		errx(EXIT_FAILURE, _("neither --freeze or --unfreeze specified"));
     105  	if (optind == argc)
     106  		errx(EXIT_FAILURE, _("no filename specified"));
     107  	path = argv[optind++];
     108  
     109  	if (optind != argc) {
     110  		warnx(_("unexpected number of arguments"));
     111  		errtryhelp(EXIT_FAILURE);
     112  	}
     113  
     114  	fd = open(path, O_RDONLY);
     115  	if (fd < 0)
     116  		err(EXIT_FAILURE, _("cannot open %s"), path);
     117  
     118  	if (fstat(fd, &sb) == -1) {
     119  		warn(_("stat of %s failed"), path);
     120  		goto done;
     121  	}
     122  
     123  	if (!S_ISDIR(sb.st_mode)) {
     124  		warnx(_("%s: is not a directory"), path);
     125  		goto done;
     126  	}
     127  
     128  	switch (action) {
     129  	case FREEZE:
     130  		if (ioctl(fd, FIFREEZE, 0)) {
     131  			warn(_("%s: freeze failed"), path);
     132  			goto done;
     133  		}
     134  		break;
     135  	case UNFREEZE:
     136  		if (ioctl(fd, FITHAW, 0)) {
     137  			warn(_("%s: unfreeze failed"), path);
     138  			goto done;
     139  		}
     140  		break;
     141  	default:
     142  		abort();
     143  	}
     144  
     145  	rc = EXIT_SUCCESS;
     146  done:
     147  	close(fd);
     148  	return rc;
     149  }
     150