这是一个问题,我一直在与之斗争很长一段时间没有进展。希望你能帮助我!
我在一个目录('home / fsc')中安装FUSE没有问题,甚至按以下方式列出它的父目录(/ home):
on / home .. ls -l </ p>
操作getattr工作正常。
当我打开目录('cd fsc')时出现问题,它打开正确,并调试操作我可以看到保险丝如何询问'/'文件属性,但当我尝试列出该目录中的文件时,保险丝在无限循环中询问'/ tls'的属性,一直收到错误'2','没有这样的文件或目录',直到它断开连接。
我发现更奇怪的是它永远不会像我预期的那样进入readdir操作。
有关为什么会发生这种情况的任何想法?为什么fuse要求'/ tls'属性而不是执行'/'的readdir?
非常感谢你们的帮助,我需要一个大学项目的解决方案,我需要尽快开展工作,所以非常感谢帮助!
此致
编辑:
我刚注意到它在此循环期间还要求'/ i686','/ sse2','/ cmov','/ librt.so.1'的文件attirbutes然后再返回'/ TLS'
2.-EDIT:
GETATTR OPERATION
int client_getattr(const char* c_ruta, struct stat* ptr_est_salida) {
int error = 0;
size_t size_structStat = sizeof(struct stat);
t_conexion* ptr_conexionLibre = poolConexion_obtenerConexion();
char out_key[50];
char s_stat[sizeof(struct stat)];
_ArmaKeyRC_fsc(c_ruta,GET_ATTR,out_key);
if (!strcmp((char*) configuracion_estadoRC(),"ON")){
if (rc_get_static(out_key, s_stat, &size_structStat) != 0) {
logger_info("Acierto en RC (Getattr) Se omite comunicacion con RFS...");
// TODO
return error;
} else {
logger_info("No hubo acierto en RC (Getattr) Inicia comunicacion con RFS...");
}
}
error = nipc_invocar_getattr(ptr_conexionLibre, c_ruta, ptr_est_salida);
if (!error){
logger_info("La operacion getattr fue realizada con éxito");
if (!strcmp((char*) configuracion_estadoRC(),"ON")){
logger_info("Almacenando getattr en RC...");
_serializaStructStat(*ptr_est_salida,s_stat);
rc_store(out_key, s_stat, sizeof(struct stat));
}
}
poolConexion_conexionDisponible(ptr_conexionLibre);
return error;
READDIR OPERATION
int client_readdir(const char* c_ruta, void* ptr_salida,
fuse_fill_dir_t fn_llenadorDeElementosEnBuffer, off_t offset,
struct fuse_file_info* ptr_est_infoArchivo) {
int error = 0;
t_conexion* ptr_conexionLibre = poolConexion_obtenerConexion();
if (!strcmp((char*) configuracion_estadoRC(),"ON")){
if (rc_get(c_ruta) != 0) {
logger_info("Acierto en RC (Readdir) Se omite comunicacion con RFS...");
return error;
} else {
logger_info("No hubo acierto en RC (Readdir) Inicia comunicacion con RFS...");
}
}
char** ptr_datos=NULL;
size_t cantidadLeida = 0;
error = nipc_invocar_readDir(ptr_conexionLibre, c_ruta,
ptr_est_infoArchivo->fh, &ptr_datos, &cantidadLeida);
off_t filler_offset;
while (strcmp( ptr_datos[filler_offset],"")==0){
fn_llenadorDeElementosEnBuffer(ptr_salida,(const char*) ptr_datos[filler_offset],NULL,0);
filler_offset = filler_offset + 256;
}
if (!error){
logger_info("La operacion readdir fue realizada con éxito");
if (!strcmp((char*) configuracion_estadoRC(),"ON")){
logger_info("Almacenando readdir en RC...");
//char out_key[50];
//_ArmaKeyRC_fsc(c_ruta, GET_ATTR, out_key);
//rc_store(out_key, (char*) ptr_est_salida, sizeof(struct stat));
}
}
poolConexion_conexionDisponible(ptr_conexionLibre);
return error;
FUSE MAIN
#include "fuse_interface.h"
#include <stddef.h>
#include <stdlib.h>
#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include "cliente.h"
// Estructura auxiliar que se usa para pasarle parámetros
// por línea de comando a la función principal de FUSE
struct t_runtime_options {
char* welcome_msg;
} runtime_options;
// Esta macro sirve para definir nuestros propios parámetros
#define CUSTOM_FUSE_OPT_KEY(t, p, v) { t, offsetof(struct t_runtime_options, p), v }
// Estructura de operaciones de FUSE, contiene
// punteros a las funciones que debe ejecutar FUSE
// según se solicite.
static struct fuse_operations client_operations = { .getattr = client_getattr,
.readdir = client_readdir, .open = client_open, .read = client_read,
.unlink = client_unlink, .release = client_release, .rmdir =
client_rmdir, .truncate = client_truncate,
.write = client_write, .create = client_create, .mkdir = client_mkdir, };
/** keys for FUSE_OPT_ options */
enum {
KEY_VERSION, KEY_HELP,
};
//Esta estructura es utilizada para decirle a la biblioteca de FUSE que
// parametro puede recibir y donde tiene que guardar el valor de estos
static struct fuse_opt fuse_options[] = {
// Este es un parámetro definido por la cátedra de SISOP
CUSTOM_FUSE_OPT_KEY("--welcome-msg %s", welcome_msg, 0),
// Estos son parametros por defecto que ya tiene FUSE
FUSE_OPT_KEY("-V", KEY_VERSION), FUSE_OPT_KEY("--version", KEY_VERSION),
FUSE_OPT_KEY("-h", KEY_HELP), FUSE_OPT_KEY("--help", KEY_HELP),
FUSE_OPT_END, };
int main(int argc, char *argv[]) {
if (argc < 2) {
perror("FSC:falta indicar la ruta del archivo de configuracion");
exit(-1);
}
char c_config[256];
strcpy(c_config, argv[1]);
cliente_iniciar(c_config);
int fuse_argc = 3;
char nombrePrograma[256];
strcpy(nombrePrograma, argv[0]);
char puntoMontaje[256];
strcpy(puntoMontaje, configuracion_pathMontajeFS());
char parametro[256];
strcpy(parametro, "-f");
char* fuse_argv[3];
fuse_argv[0]=nombrePrograma;
fuse_argv[1]=puntoMontaje;
fuse_argv[2]=parametro;
printf("Iniciando Fuse: Mount Point: %s", configuracion_pathMontajeFS());
// Inicializo la estructura de argumentos de FUSE
struct fuse_args args = FUSE_ARGS_INIT(fuse_argc, fuse_argv);
// Limpio la estructura que va a contener los parametros
memset(&runtime_options, 0, sizeof(struct t_runtime_options));
// Esta funcion de FUSE lee los parametros recibidos y los intepreta
if (fuse_opt_parse(&args, &runtime_options, fuse_options, NULL) == -1) {
perror("Fuse dice: Argumentos Invalidos");
return EXIT_FAILURE;
}
// Si se paso el parametro --welcome-msg
// el campo welcome_msg deberia tener el
// valor pasado
if (runtime_options.welcome_msg != NULL) {
printf("%s\n", runtime_options.welcome_msg);
} else {
}
// Esta es la funcion principal de FUSE, es la que se encarga
// de realizar el montaje, comuniscarse con el kernel, delegar las cosas
// en varios threads
return fuse_main(args.argc, args.argv, &client_operations, NULL);
}