Check-in [7324be78ca]
Overview
Comment:Moved option parsing to a separate function and added help, set default directory time to start time
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:7324be78caf6356e2131ac0fbdf154b84d3e9045
User & Date: rkeene on 2014-11-18 01:06:59
Other Links: manifest | tags
Context
2014-11-18
01:13
Prettied up Makefile check-in: 48dd71800a user: rkeene tags: trunk
01:06
Moved option parsing to a separate function and added help, set default directory time to start time check-in: 7324be78ca user: rkeene tags: trunk
00:06
Added comment a distclean target for archive check-in: 1beb5adeec user: rkeene tags: trunk
Changes

Modified appfsd.c from [276d2f6247] to [dafdf12fdd].

    61     61   /*
    62     62    * Global variables, needed for all threads but only initialized before any
    63     63    * FUSE threads are created
    64     64    */
    65     65   const char *appfs_cachedir;
    66     66   time_t appfs_boottime;
    67     67   int appfs_fuse_started = 0;
           68  +int appfs_threaded_tcl;
    68     69   
    69     70   /*
    70     71    * Global variables for AppFS caching
    71     72    */
    72     73   pthread_mutex_t appfs_path_info_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
    73     74   int appfs_path_info_cache_size = 8209;
    74     75   struct appfs_pathinfo *appfs_path_info_cache = NULL;
................................................................................
    77     78   /*
    78     79    * Handle unthreaded Tcl
    79     80    */
    80     81   pthread_mutex_t appfs_tcl_big_global_lock = PTHREAD_MUTEX_INITIALIZER;
    81     82   #define appfs_call_libtcl_enter pthread_mutex_lock(&appfs_tcl_big_global_lock);
    82     83   #define appfs_call_libtcl_exit pthread_mutex_unlock(&appfs_tcl_big_global_lock);
    83     84   #else
    84         -#warning Using a Threaded Tcl interpreter may cause memory leaks
    85     85   #define appfs_call_libtcl_enter /**/
    86     86   #define appfs_call_libtcl_exit /**/
    87     87   #endif
    88     88   #define appfs_call_libtcl(x...) appfs_call_libtcl_enter x appfs_call_libtcl_exit
    89     89   
    90     90   /*
    91     91    * Global variables for AppFS Tcl Interpreter restarting
................................................................................
   965    965   		Tcl_DictObjGet(interp, attrs_dict, attr_key_time, &attr_value);
   966    966   		if (attr_value != NULL) {
   967    967   			tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
   968    968   			if (tcl_ret == TCL_OK) {
   969    969   				pathinfo->time = attr_value_wide;
   970    970   			}
   971    971   		} else {
   972         -			pathinfo->time = 0;
          972  +			pathinfo->time = appfs_boottime;
   973    973   		}
   974    974   
   975    975   		Tcl_Release(interp);
   976    976   	)
   977    977   
   978    978   	if (retval == 0) {
   979    979   		appfs_get_path_info_cache_add(path, fsuid, pathinfo);
................................................................................
  1866   1866    * Hot-restart support
  1867   1867    */
  1868   1868   /* Initiate a hot-restart */
  1869   1869   static void appfs_hot_restart(void) {
  1870   1870   	APPFS_DEBUG("Asked to initiate hot restart");
  1871   1871   
  1872   1872   	appfs_tcl_ResetInterps();
         1873  +
  1873   1874   	appfs_get_path_info_cache_flush(-1, -1);
  1874   1875   
  1875   1876   	return;
  1876   1877   }
  1877   1878   
  1878   1879   /*
  1879   1880    * Signal handler
................................................................................
  1911   1912   
  1912   1913   	APPFS_DEBUG("Terminating interpreter due to thread termination");
  1913   1914   
  1914   1915   	appfs_call_libtcl(
  1915   1916   		Tcl_DeleteInterp(interp);
  1916   1917   	)
  1917   1918   
  1918         -	Tcl_FinalizeThread();
         1919  +	appfs_call_libtcl(
         1920  +		Tcl_FinalizeThread();
         1921  +	)
         1922  +
         1923  +	return;
         1924  +}
         1925  +
         1926  +/*
         1927  + * Command-line parsing tools
         1928  + */
         1929  +static void appfs_print_help(FILE *channel) {
         1930  +	fprintf(channel, "Usage: {appfsd|mount.appfs} [-o <option>] [-dfsh] <cachedir> <mountpoint>\n");
         1931  +	fprintf(channel, "\n");
         1932  +	fprintf(channel, "Options:\n");
         1933  +	fprintf(channel, "  -d              Enable FUSE debug mode.\n");
         1934  +	fprintf(channel, "  -f              Run in foreground.\n");
         1935  +	fprintf(channel, "  -s              Enable single threaded mode.\n");
         1936  +	fprintf(channel, "  -h              Give this help.\n");
         1937  +	fprintf(channel, "  -o nothreads    Enable single threaded mode.\n");
         1938  +	fprintf(channel, "  -o allow_other  Allow other users to access this mountpoint (default\n");
         1939  +	fprintf(channel, "                  if root).\n");
  1919   1940   
  1920   1941   	return;
  1921   1942   }
         1943  +
         1944  +static int appfs_opt_parse(int argc, char **argv,  struct fuse_args *args) {
         1945  +	int ch;
         1946  +	char *optstr, *optstr_next, *optstr_s;
         1947  +	char fake_arg[3] = {'-', 0, 0};
         1948  +
         1949  +	/*
         1950  +	 * Default values
         1951  +	 */
         1952  +#ifdef TCL_THREADS
         1953  +	appfs_threaded_tcl = 1;
         1954  +#else
         1955  +	appfs_threaded_tcl = 0;
         1956  +#endif
         1957  +
         1958  +	/**
         1959  +	 ** Add FUSE arguments which we always supply
         1960  +	 **/
         1961  +	fuse_opt_add_arg(args, "-odefault_permissions,fsname=appfs,subtype=appfsd,use_ino,kernel_cache,entry_timeout=0,attr_timeout=0,big_writes,intr,hard_remove");
         1962  +
         1963  +	if (getuid() == 0) {
         1964  +		fuse_opt_parse(args, NULL, NULL, NULL);
         1965  +		fuse_opt_add_arg(args, "-oallow_other");
         1966  +	}
         1967  +
         1968  +	while ((ch = getopt(argc, argv, "dfsho:")) != -1) {
         1969  +		switch (ch) {
         1970  +			case 'o':
         1971  +				optstr_next = optstr = optstr_s = strdup(optarg);
         1972  +
         1973  +				while (1) {
         1974  +					optstr = optstr_next;
         1975  +
         1976  +					if (!optstr) {
         1977  +						break;
         1978  +					}
         1979  +
         1980  +					optstr_next = strchr(optstr, ',');
         1981  +					if (optstr_next) {
         1982  +						*optstr_next = '\0';
         1983  +						optstr_next++;
         1984  +					}
         1985  +
         1986  +					if (strcmp(optstr, "nothreads") == 0) {
         1987  +						fuse_opt_parse(args, NULL, NULL, NULL);
         1988  +						fuse_opt_add_arg(args, "-s");
         1989  +
         1990  +						appfs_threaded_tcl = 0;
         1991  +					} else if (strcmp(optstr, "allow_other") == 0) {
         1992  +						fuse_opt_parse(args, NULL, NULL, NULL);
         1993  +						fuse_opt_add_arg(args, "-oallow_other");
         1994  +					} else {
         1995  +						fprintf(stderr, "appfsd: invalid option: \"-o %s\"\n", optstr);
         1996  +
         1997  +						free(optstr_s);
         1998  +
         1999  +						return(1);
         2000  +					}
         2001  +				}
         2002  +
         2003  +				free(optstr_s);
         2004  +
         2005  +				break;
         2006  +			case 'd':
         2007  +			case 'f':
         2008  +			case 's':
         2009  +				if (ch == 's') {
         2010  +					appfs_threaded_tcl = 0;
         2011  +				}
         2012  +
         2013  +				fake_arg[1] = ch;
         2014  +
         2015  +				APPFS_DEBUG("Passing option to FUSE: %s", fake_arg);
         2016  +
         2017  +				fuse_opt_parse(args, NULL, NULL, NULL);
         2018  +				fuse_opt_add_arg(args, fake_arg);
         2019  +				break;
         2020  +			case 'h':
         2021  +				appfs_print_help(stdout);
         2022  +
         2023  +				return(0);
         2024  +			case ':':
         2025  +			case '?':
         2026  +			default:
         2027  +				appfs_print_help(stderr);
         2028  +
         2029  +				return(1);
         2030  +		}
         2031  +	}
         2032  +
         2033  +	if ((optind + 2) != argc) {
         2034  +		if ((optind + 2) < argc) {
         2035  +			fprintf(stderr, "Too many arguments\n");
         2036  +		} else {
         2037  +			fprintf(stderr, "Missing cachedir or mountpoint\n");
         2038  +		}
         2039  +
         2040  +		appfs_print_help(stderr);
         2041  +
         2042  +		return(1);
         2043  +	}
         2044  +
         2045  +	/*
         2046  +	 * Set cache dir as first argument (the "device", essentially)
         2047  +	 */
         2048  +	appfs_cachedir = argv[optind];
         2049  +
         2050  +	/*
         2051  +	 * Pass the remaining argument to FUSE as the directory
         2052  +	 */
         2053  +	fuse_opt_parse(args, NULL, NULL, NULL);
         2054  +	fuse_opt_add_arg(args, argv[optind + 1]);
         2055  +
         2056  +	return(0);
         2057  +}
         2058  +
  1922   2059   
  1923   2060   /*
  1924   2061    * FUSE operations structure
  1925   2062    */
  1926   2063   static struct fuse_operations appfs_operations = {
  1927   2064   	.getattr   = appfs_fuse_getattr,
  1928   2065   	.readdir   = appfs_fuse_readdir,
................................................................................
  1937   2074   	.unlink    = appfs_fuse_unlink_rmdir,
  1938   2075   	.rmdir     = appfs_fuse_unlink_rmdir,
  1939   2076   	.mkdir     = appfs_fuse_mkdir,
  1940   2077   	.chmod     = appfs_fuse_chmod,
  1941   2078   	.symlink   = appfs_fuse_symlink,
  1942   2079   };
  1943   2080   
  1944         -/*
  1945         - * FUSE option parsing callback
  1946         - */
  1947         -static int appfs_fuse_opt_cb(void *data, const char *arg, int key, struct fuse_args *outargs) {
  1948         -	static int seen_cachedir = 0;
  1949         -
  1950         -	if (key == FUSE_OPT_KEY_NONOPT && seen_cachedir == 0) {
  1951         -		seen_cachedir = 1;
  1952         -
  1953         -		appfs_cachedir = strdup(arg);
  1954         -
  1955         -		return(0);
  1956         -	}
  1957         -
  1958         -	return(1);
  1959         -}
  1960         -
  1961   2081   /*
  1962   2082    * Entry point into this program.
  1963   2083    */
  1964   2084   int main(int argc, char **argv) {
  1965   2085   	Tcl_Interp *test_interp;
  1966   2086   	char *test_interp_error;
  1967         -	struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
  1968         -	int pthread_ret;
         2087  +	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
         2088  +	int pthread_ret, aop_ret;
  1969   2089   	void *signal_ret;
         2090  +	char *argv0;
  1970   2091   
  1971   2092   	/*
  1972   2093   	 * Skip passed program name
  1973   2094   	 */
  1974   2095   	if (argc == 0 || argv == NULL) {
  1975   2096   		return(1);
  1976   2097   	}
         2098  +
         2099  +	argv0 = argv[0];
         2100  +
  1977   2101   	argc--;
  1978   2102   	argv++;
  1979   2103   
  1980   2104   	/*
  1981   2105   	 * Set global variables, these should be configuration options.
  1982   2106   	 */
  1983   2107   	appfs_cachedir = APPFS_CACHEDIR;
................................................................................
  2032   2156   	/*
  2033   2157   	 * Tcl mode, for running raw Tcl in the same environment AppFSd would
  2034   2158   	 * run code.
  2035   2159   	 */
  2036   2160   	if (argc == 2 && strcmp(argv[0], "--tcl") == 0) {
  2037   2161   		return(appfs_tcl(argv[1]));
  2038   2162   	}
         2163  +
         2164  +	/*
         2165  +	 * Register a signal handler for hot-restart requests
         2166  +	 */
         2167  +	signal_ret = signal(SIGHUP, appfs_signal_handler);
         2168  +	if (signal_ret == SIG_ERR) {
         2169  +		fprintf(stderr, "Unable to install signal handler for hot-restart\n");
         2170  +		fprintf(stderr, "Hot-restart will not be available.\n");
         2171  +	}
         2172  +
         2173  +	/*
         2174  +	 * Parse command line arguments
         2175  +	 */
         2176  +	/**
         2177  +	 ** Restore argc/argv to original values, replacing argv[0] in case
         2178  +	 ** it was moified by --cachedir option.
         2179  +	 **/
         2180  +	argc++;
         2181  +	argv--;
         2182  +	argv[0] = argv0;
         2183  +
         2184  +	/**
         2185  +	 ** Perform the argument parsing
         2186  +	 **/
         2187  +	aop_ret = appfs_opt_parse(argc, argv, &args);
         2188  +	if (aop_ret != 0) {
         2189  +		return(aop_ret);
         2190  +	}
  2039   2191   
  2040   2192   	/*
  2041   2193   	 * Create a Tcl interpreter just to verify that things are in working 
  2042   2194   	 * order before we become a daemon.
  2043   2195   	 */
  2044   2196   	test_interp = appfs_create_TclInterp(&test_interp_error);
  2045   2197   	if (test_interp == NULL) {
................................................................................
  2051   2203   		fprintf(stderr, "%s\n", test_interp_error);
  2052   2204   
  2053   2205   		return(1);
  2054   2206   	}
  2055   2207   
  2056   2208   	Tcl_DeleteInterp(test_interp);
  2057   2209   
  2058         -	Tcl_FinalizeNotifier(NULL);
  2059         -
  2060         -	/*
  2061         -	 * Register a signal handler for hot-restart requests
  2062         -	 */
  2063         -	signal_ret = signal(SIGHUP, appfs_signal_handler);
  2064         -	if (signal_ret == SIG_ERR) {
  2065         -		fprintf(stderr, "Unable to install signal handler for hot-restart\n");
  2066         -		fprintf(stderr, "Hot-restart will not be available.\n");
  2067         -	}
  2068         -
  2069         -	/*
  2070         -	 * Add FUSE arguments which we always supply
  2071         -	 */
  2072         -	fuse_opt_parse(&args, NULL, NULL, appfs_fuse_opt_cb);
  2073         -	fuse_opt_add_arg(&args, "-odefault_permissions,fsname=appfs,subtype=appfsd,use_ino,kernel_cache,entry_timeout=0,attr_timeout=0,big_writes,intr,hard_remove");
  2074         -
  2075         -	if (getuid() == 0) {
  2076         -		fuse_opt_parse(&args, NULL, NULL, NULL);
  2077         -		fuse_opt_add_arg(&args, "-oallow_other");
         2210  +	if (appfs_threaded_tcl) {
         2211  +		Tcl_FinalizeNotifier(NULL);
  2078   2212   	}
  2079   2213   
  2080   2214   	/*
  2081   2215   	 * Enter the FUSE main loop -- this will process any arguments
  2082   2216   	 * and start servicing requests.
  2083   2217   	 */
  2084   2218   	appfs_fuse_started = 1;
  2085   2219   	return(fuse_main(args.argc, args.argv, &appfs_operations, NULL));
  2086   2220   }
  2087         -