예제 #1
0
파일: BNotifier.c 프로젝트: brianhlin/BLAH
int
PollDB()
{
        FILE *fd;
        job_registry_entry *en;
	job_registry_handle *rha;
	job_registry_handle *rhc;
	char *buffer=NULL;
        char *cdate=NULL;
	time_t now;
        int  maxtok,i,maxtokl,j;
        char **tbuf;
        char **lbuf;
	int len=0,flen=0;
        struct stat sbuf;
        int rc;
	char *regfile;
        char *cp=NULL;
	int to_sleep=FALSE;
	int skip_reg_open=FALSE;
	int ret;

	rha=job_registry_init(registry_file, BY_BATCH_ID);
	if (rha == NULL){
		do_log(debuglogfile, debug, 1, "%s: Error initialising job registry %s\n",argv0,registry_file);
		fprintf(stderr,"%s: Error initialising job registry %s :",argv0,registry_file);
		perror("");
	}
	
	for(;;){
	
		now=time(NULL);
	
		to_sleep=TRUE;
		/* cycle over connections: sleep if startnotify, startnotifyjob and sentendonce are not set.
		   If startnotifyjob is set the conn is served.
		*/ 
		for(i=0; i<MAX_CONNECTIONS; i++){
		
			if(!connections[i].startnotify && !connections[i].startnotifyjob && !(connections[i].firstnotify && connections[i].sentendonce)) continue;
			if(connections[i].startnotify) to_sleep=FALSE;
			
			if(connections[i].startnotifyjob){
				to_sleep=FALSE;
				rhc=job_registry_init(registry_file, BY_USER_PREFIX);
				if (rhc == NULL){
					do_log(debuglogfile, debug, 1, "%s: Error initialising job registry %s\n",argv0,registry_file);
					fprintf(stderr,"%s: Error initialising job registry %s :",argv0,registry_file);
		 	   	  	perror("");
		 	   	}
		 	   	do_log(debuglogfile, debug, 2, "%s:Job list for notification:%s\n",argv0,connections[i].joblist_string);
		 	   	maxtok=strtoken(connections[i].joblist_string,',',&tbuf);
   		 	   	for(j=0;j<maxtok;j++){
        	 	   	  	if ((en=job_registry_get(rhc, tbuf[j])) != NULL){
						buffer=ComposeClassad(en);
		 	   	  	}else{
						if(remupd_conf == NULL){
		 	   	  			cdate=iepoch2str(now);
		 	   	  			maxtokl=strtoken(tbuf[j],'_',&lbuf);
		 	   	  			if(lbuf[1]){
		 	   	  				if ((cp = strrchr (lbuf[1], '\n')) != NULL){
		 	   	  					*cp = '\0';
		 	   	  				}
		 	   	  				if ((cp = strrchr (lbuf[1], '\r')) != NULL){
		 	   	  					*cp = '\0';
		 	   	  				}
		 	   	  				buffer=make_message("[BlahJobName=\"%s\"; ClientJobId=\"%s\"; JobStatus=4; JwExitCode=999; ExitReason=\"BUpdater is not able to find the job anymore\"; Reason=\"BUpdater is not able to find the job anymore\"; ChangeTime=\"%s\"; ]\n",tbuf[j],lbuf[1],cdate);
		 	   	  			}
		 	   	  			freetoken(&lbuf,maxtokl);
		 	   	  			free(cdate);
						}else{
		 	   	  			maxtokl=strtoken(tbuf[j],':',&lbuf);
							JOB_REGISTRY_ASSIGN_ENTRY(en->batch_id,lbuf[0]);
							JOB_REGISTRY_ASSIGN_ENTRY(en->blah_id,lbuf[1]);
		 	   	  			freetoken(&lbuf,maxtokl);
							en->status = 0;
							if ((ret=job_registry_append(rhc, en))<0){
								if(ret != JOB_REGISTRY_NOT_FOUND){
									fprintf(stderr,"Update of record returns %d: ",ret);
									perror("");
								}
							}else{
								if(ret==JOB_REGISTRY_SUCCESS){
									do_log(debuglogfile, debug, 2, "%s: registry append in PollDB for: jobid=%s blahjobid=%s\n",argv0,en->batch_id,en->blah_id);
								}
							}
						}
		 	   	  	}
		 	   	  	free(en);
		 	   	  	len=strlen(buffer);
		 	   	  	if(connections[i].finalbuffer != NULL){
		 	   	  		flen=strlen(connections[i].finalbuffer);
		 	   	  	}else{
		 	   	  		flen=0;
		 	   	  	}
		 	   	  	connections[i].finalbuffer = realloc(connections[i].finalbuffer,flen+len+2);
		 	   	  	if (connections[i].finalbuffer == NULL){
		 	   	  		sysfatal("can't realloc finalbuffer in PollDB: %r");
		 	   	  	}
		 	   	  	if(flen==0){
		 	   	  		connections[i].finalbuffer[0]='\000';
					}
		 	   	  	strcat(connections[i].finalbuffer,buffer);
		 	   	  	free(buffer);
		 	   	}
		 	   	freetoken(&tbuf,maxtok);
		 	   
		 	   	if(connections[i].finalbuffer != NULL){
		 	   	  	if(NotifyCream(connections[i].finalbuffer,&connections[i])!=-1){
	         	   	  		/* change last notification time */
		 	   	  		connections[i].lastnotiftime=now;
		 	   	  		connections[i].startnotifyjob=FALSE;
		 	   	  	}
		 	   	  	free(connections[i].finalbuffer);
		 	   	  	connections[i].finalbuffer=NULL;
		 	   	}
		 	   	job_registry_destroy(rhc);
			}
			if(connections[i].firstnotify && connections[i].sentendonce){
				to_sleep=FALSE;
				if(NotifyCream("NTFDATE/END\n",&connections[i])!=-1){
					connections[i].startnotify=TRUE;
					connections[i].sentendonce=FALSE;
		 	   	  	connections[i].firstnotify=FALSE;
		 	   	  	connections[i].startnotifyjob=FALSE;
				}
			}
			
		}
		
		if(to_sleep){
			sleep(loop_interval);
			continue;
		}

                regfile=make_message("%s/registry",registry_file);
        	rc=stat(regfile,&sbuf);
		free(regfile);
		
		skip_reg_open=TRUE;
		for(i=0; i<MAX_CONNECTIONS; i++){
			if(sbuf.st_mtime>=connections[i].lastnotiftime){
				skip_reg_open=FALSE;
				break;
			}
		}
		if(skip_reg_open){
			do_log(debuglogfile, debug, 3, "Skip registry opening: mtime:%d lastn:%d\n",sbuf.st_mtime,connections[i].lastnotiftime);
			sleep(loop_interval);
			continue;
		}
		
		do_log(debuglogfile, debug, 3, "Normal registry opening\n");

		fd = job_registry_open(rha, "r");
		if (fd == NULL)
		{
			do_log(debuglogfile, debug, 1, "%s: Error opening job registry %s\n",argv0,registry_file);
			fprintf(stderr,"%s: Error opening job registry %s :",argv0,registry_file);
			perror("");
			sleep(loop_interval);
			continue;
		}
		if (job_registry_rdlock(rha, fd) < 0)
		{
			do_log(debuglogfile, debug, 1, "%s: Error read locking registry %s\n",argv0,registry_file);
			fprintf(stderr,"%s: Error read locking registry %s :",argv0,registry_file);
			perror("");
			sleep(loop_interval);
			continue;
		}
		while ((en = job_registry_get_next(rha, fd)) != NULL)
		{
		
			for(i=0; i<MAX_CONNECTIONS; i++){
				if(connections[i].creamfilter==NULL) continue;
				if(en->mdate >= connections[i].lastnotiftime && en->mdate < now && en->user_prefix && strstr(en->user_prefix,connections[i].creamfilter)!=NULL && strlen(en->updater_info)>0)
				{
					buffer=ComposeClassad(en);
					len=strlen(buffer);
					if(connections[i].finalbuffer != NULL){
						flen=strlen(connections[i].finalbuffer);
					}else{
						flen=0;
					}
					connections[i].finalbuffer = realloc(connections[i].finalbuffer,flen+len+2);
					if (connections[i].finalbuffer == NULL){
						sysfatal("can't realloc finalbuffer in PollDB: %r");
					}
					if(flen==0){
						connections[i].finalbuffer[0]='\000';
					}
					strcat(connections[i].finalbuffer,buffer);
					free(buffer);
				}
			}
			free(en);
		}

		for(i=0; i<MAX_CONNECTIONS; i++){
			if(connections[i].finalbuffer != NULL){
				if(NotifyCream(connections[i].finalbuffer,&connections[i])!=-1){
	        			/* change last notification time */
					connections[i].lastnotiftime=now;
				}
				free(connections[i].finalbuffer);
				connections[i].finalbuffer=NULL;
			}
		}
		
		fclose(fd);
		
		sleep(loop_interval);
	}
                
	job_registry_destroy(rha);
	
	return 0;
}
예제 #2
0
int 
ReceiveUpdateFromNetwork()
{
	char *proxy_path, *proxy_subject;
	int timeout_ms = 0;
	int ent, ret, prret, rhret;
	job_registry_entry *nen;
	job_registry_entry *ren;
  
	proxy_path = NULL;
	proxy_subject = NULL;
	
	while (nen = job_registry_receive_update(remupd_pollset, remupd_nfds,timeout_ms, &proxy_subject, &proxy_path)){
	
		JOB_REGISTRY_ASSIGN_ENTRY(nen->subject_hash,"\0");
		JOB_REGISTRY_ASSIGN_ENTRY(nen->proxy_link,"\0");
		
		if ((ren=job_registry_get(rha, nen->batch_id)) == NULL){
			if ((ret=job_registry_append(rha, nen)) < 0){
				fprintf(stderr,"%s: Warning: job_registry_append returns %d: ",argv0,ret);
				perror("");
			} 
		}else{
		
			if(ren->subject_hash!=NULL && strlen(ren->subject_hash) && ren->proxy_link!=NULL && strlen(ren->proxy_link)){
				JOB_REGISTRY_ASSIGN_ENTRY(nen->subject_hash,ren->subject_hash);
				JOB_REGISTRY_ASSIGN_ENTRY(nen->proxy_link,ren->proxy_link);
			}else{
				if (proxy_path != NULL && strlen(proxy_path) > 0){
					prret = job_registry_set_proxy(rha, nen, proxy_path);
     			 		if (prret < 0){
						do_log(debuglogfile, debug, 1, "%s: warning: setting proxy to %s\n",argv0,proxy_path);
        					fprintf(stderr,"%s: warning: setting proxy to %s: ",argv0,proxy_path);
        					perror("");
        					/* Make sure we don't renew non-existing proxies */
						nen->renew_proxy = 0;  		
					}
					free(proxy_path);
  
					nen->subject_hash[0] = '\000';
					if (proxy_subject != NULL && strlen(proxy_subject) > 0){
						job_registry_compute_subject_hash(nen, proxy_subject);
						rhret = job_registry_record_subject_hash(rha, nen->subject_hash, proxy_subject, TRUE);  
						if (rhret < 0){
							do_log(debuglogfile, debug, 1, "%s: warning: recording proxy subject %s (hash %s)\n",argv0, proxy_subject, nen->subject_hash);
							fprintf(stderr,"%s: warning: recording proxy subject %s (hash %s): ",argv0, proxy_subject, nen->subject_hash);
							perror("");
						}
					}
					free(proxy_subject);
  
				}
			}
			if(job_registry_need_update(ren,nen,JOB_REGISTRY_UPDATE_ALL)){
				if ((ret=job_registry_update(rha, nen)) < 0){
					fprintf(stderr,"%s: Warning: job_registry_update returns %d: ",argv0,ret);
					perror("");
				}
			} 
		}
		free(nen);
	}
  
	return 0;
}
예제 #3
0
int
main(int argc, char *argv[])
{
  char *registry_file = NULL, *registry_file_env = NULL;
  int need_to_free_registry_file = FALSE;
  const char *default_registry_file = "blah_job_registry.bjr";
  char *my_home;
  job_registry_entry en;
  job_status_t status=IDLE;
  int exitcode = -1; 
  char *exitreason = "";
  char *user_prefix = "";
  char *user_proxy = "";
  char *proxy_subject = "";
  int  renew_proxy = 0;
  char *wn_addr = "";
  time_t udate=0;
  char *blah_id, *batch_id;
  int ent, ret, prret, rhret;
  config_handle *cha;
  config_entry *rge, *remupd_conf;
  job_registry_handle *rha, *rhano;
  job_registry_index_mode rgin_mode = NO_INDEX;
  job_registry_updater_endpoint *remupd_head = NULL;

  if (argc > 1 && (strcmp(argv[1], "-u") == 0))
   {
    /* Obtain an index to the registry so that we can */
    /* check that the record is unique. */
    rgin_mode = BY_BLAH_ID;
    argv[1] = argv[0];
    argc--;
    argv++;
   }

  if (argc < 3)
   {
    fprintf(stderr,"Usage: %s [-u] <BLAH id> <batch id> [job status] [udate] [user prefix] [user proxy] [renew proxy] [proxy subject] [worker node] [exit code] [exit reason]\n",argv[0]);
    return 1;
   }

  blah_id  = argv[1]; 
  batch_id = argv[2]; 

  if (argc > 3) status = atoi(argv[3]);
  if (argc > 4) udate = atol(argv[4]);
  if (argc > 5) user_prefix = argv[5];
  if (argc > 6) user_proxy = argv[6];
  if (argc > 7) renew_proxy = atoi(argv[7]);
  if (argc > 8) proxy_subject = argv[8];
  if (argc > 9) wn_addr = argv[9];
  if (argc > 10) exitcode = atoi(argv[10]);
  if (argc > 11) exitreason = argv[11];
   
  cha = config_read(NULL); /* Read config from default locations. */
  if (cha != NULL)
   {
    rge = config_get("job_registry", cha);
    remupd_conf = config_get("job_registry_add_remote", cha);
    if (remupd_conf != NULL)
     {
      if (job_registry_updater_setup_sender(remupd_conf->values,
                                            remupd_conf->n_values, 2,
                                           &remupd_head) < 0)
       {
         fprintf(stderr,"%s: warning: cannot set network sender(s) up for remote update to:\n",argv[0]);
         for (ent = 0; ent < remupd_conf->n_values; ent++)
          {
           fprintf(stderr," - %s\n", remupd_conf->values[ent]);
          }
       }
     }
    if (rge != NULL) registry_file = rge->value;
   }

  /* Env variable takes precedence */
  registry_file_env = getenv("BLAH_JOB_REGISTRY_FILE");
  if (registry_file_env != NULL) registry_file = registry_file_env;

  if (registry_file == NULL)
   {
    my_home = getenv("HOME");
    if (my_home == NULL) my_home = ".";
    registry_file = (char *)malloc(strlen(default_registry_file)+strlen(my_home)+2);
    if (registry_file != NULL)
     {
      sprintf(registry_file,"%s/%s",my_home,default_registry_file);
      need_to_free_registry_file = TRUE;
     }
    else 
     {
      if (cha != NULL) config_free(cha);
      if (remupd_head != NULL) job_registry_updater_free_endpoints(remupd_head);
      return 1;
     }
   }

  JOB_REGISTRY_ASSIGN_ENTRY(en.blah_id,blah_id); 
  JOB_REGISTRY_ASSIGN_ENTRY(en.batch_id,batch_id); 
  en.status = status;
  en.exitcode = exitcode;
  JOB_REGISTRY_ASSIGN_ENTRY(en.wn_addr,wn_addr); 
  en.udate = udate;
  JOB_REGISTRY_ASSIGN_ENTRY(en.exitreason,exitreason); 
  en.submitter = geteuid();
  JOB_REGISTRY_ASSIGN_ENTRY(en.user_prefix,user_prefix); 
  en.proxy_link[0] = '\000'; /* Start with a valid string */
  en.updater_info[0] = '\000'; 
  en.renew_proxy = 0; /* Enable renewal only if a proxy is found */

  rha=job_registry_init(registry_file, rgin_mode);

  if (rha == NULL)
   {
    if (errno == EACCES)
     {
      /* Try nonpriv update. It may work. */
      rhano = job_registry_init(registry_file, NAMES_ONLY);
      if (cha != NULL) config_free(cha);
      if (need_to_free_registry_file) free(registry_file);
      if (rhano != NULL)
       {
        if (strlen(user_proxy) > 0)
         {
          prret = job_registry_set_proxy(rhano, &en, user_proxy);
          if (prret < 0)
           {
            fprintf(stderr,"%s: warning: setting proxy to %s: ",argv[0],user_proxy);
            perror("");
           }
          else en.renew_proxy = renew_proxy;
         }
        ret=job_registry_append_nonpriv(rhano, &en);
        job_registry_destroy(rhano);
        if (ret < 0)
         {
          fprintf(stderr,"%s: job_registry_append_nonpriv returns %d: ",argv[0],ret);
          perror("");
          if (remupd_head != NULL) job_registry_updater_free_endpoints(remupd_head);
          return 4;
         } 
        else goto happy_ending;
       }
     }
    else
     {
      fprintf(stderr,"%s: error initialising job registry: ",argv[0]);
      perror("");
     }
    if (remupd_head != NULL) job_registry_updater_free_endpoints(remupd_head);
    return 2;
   }

  /* Filename is stored in job registry handle. - Don't need these anymore */
  if (cha != NULL) config_free(cha);
  if (need_to_free_registry_file) free(registry_file);

  if (strlen(user_proxy) > 0)
   {
    prret = job_registry_set_proxy(rha, &en, user_proxy);
    if (prret < 0)
     {
      fprintf(stderr,"%s: warning: setting proxy to %s: ",argv[0],user_proxy);
      perror("");
     }
    else en.renew_proxy = renew_proxy;
   }

  en.subject_hash[0] = '\000';
  if (strlen(proxy_subject) > 0)
   {
    job_registry_compute_subject_hash(&en, proxy_subject);
    rhret = job_registry_record_subject_hash(rha, en.subject_hash, 
                                             proxy_subject, TRUE);  
    if (rhret < 0)
     {
      fprintf(stderr,"%s: warning: recording proxy subject %s (hash %s): ", argv[0], proxy_subject, en.subject_hash);
      perror("");
     }
   }

  if ((ret=job_registry_append(rha, &en)) < 0)
   {
    if (errno == EACCES)
     {
      /* Try nonpriv update. It may work. */
      ret=job_registry_append_nonpriv(rha, &en);
      job_registry_destroy(rha);
      if (ret < 0)
       {
        fprintf(stderr,"%s: job_registry_append_nonpriv returns %d: ",argv[0],ret);
        perror("");
        if (remupd_head != NULL) job_registry_updater_free_endpoints(remupd_head);
        return 5;
       } 
      else goto happy_ending;
     }

    fprintf(stderr,"%s: job_registry_append returns %d: ",argv[0],ret);
    perror("");
    job_registry_destroy(rha);
    if (remupd_head != NULL) job_registry_updater_free_endpoints(remupd_head);
    return 3;
   } 

  job_registry_destroy(rha);

 happy_ending:
  if (remupd_head != NULL)
   {
    if (job_registry_send_update(remupd_head, &en,
              (strlen(proxy_subject) > 0 ? proxy_subject : NULL),
              (strlen(user_proxy) > 0 ? user_proxy : NULL)) < 0)
     {
      fprintf(stderr,"%s: warning: sending network update: ",argv[0]);
      perror("");
     }
    job_registry_updater_free_endpoints(remupd_head);
   }
  return 0;
}