Tlock* tlocked(Iobuf *p, Dentry *d) { Tlock *t, *t1; long qpath, tim; Device dev; tim = time(0); qpath = d->qid.path; dev = p->dev; t1 = 0; for(t=tlocks+NTLOCK-1; t>=tlocks; t--) { if(t->qpath == qpath) if(t->time >= tim) if(devcmp(t->dev, dev) == 0) return 0; /* its locked */ if(!t1 && t->time < tim) t1 = t; /* steal first lock */ } if(t1) { t1->dev = dev; t1->qpath = qpath; t1->time = tim + TLOCK; } /* botch * out of tlock nodes simulates * a locked file */ return t1; }
/* invite each device referenced in the expression to report its properties. */ static void getProps(FILE *fp) { char **ops; int nops; int i, j; /* get each operand used in the expression */ nops = getAllOperands (&ops); /* send getProperties for each unique device referenced */ for (i = 0; i < nops; i++) { for (j = 0; j < i; j++) if (devcmp (ops[i], ops[j]) == 0) break; if (j < i) continue; if (verbose) fprintf (stderr, "sending getProperties for %.*s\n", strchr (ops[i],'.')-ops[i], ops[i]); fprintf (fp, "<getProperties version='%g' device='%.*s'/>\n", INDIV, strchr (ops[i],'.')-ops[i], ops[i]); } }
int generic_get_mntinfo(char *devname, int *readwrite, char *mntbuf, int maxmntbuf, char *optbuf, int maxoptbuf, char *fsbuf, int maxfsbuf) { char col_fs[FSA_MAX_FSNAMELEN]; int devisroot=false; struct stat64 devstat; struct stat64 rootstat; long major, minor; char delims[]=" \t\n:"; struct utsname suname; char col_dev[128]; char col_mnt[128]; char col_opt[128]; char line[1024]; char temp[2048]; char *saveptr; char *result; FILE *f; int sep; int i; // init uname(&suname); *readwrite=-1; // unknown memset(mntbuf, 0, maxmntbuf); memset(optbuf, 0, maxoptbuf); // ---- 1. attempt to find device in "/proc/self/mountinfo" if ((stat64(devname, &devstat)==0) && ((f=fopen("/proc/self/mountinfo","rb"))!=NULL)) { msgprintf(MSG_DEBUG1, "device=[%s] has major=[%ld] and minor=[%ld]\n", devname, (long)major(devstat.st_rdev), (long)minor(devstat.st_rdev)); while(!feof(f)) { if (stream_readline(f, line, 1024)>1) { result=strtok_r(line, delims, &saveptr); major = -1; minor = -1; sep = -1; col_dev[0]=col_mnt[0]=col_fs[0]=col_opt[0]=0; for(i=0; result != NULL; i++) { if (strcmp(result, "-") == 0) // found separator sep = i; switch (i) { case 2: major = atol(result); break; case 3: minor = atol(result); break; case 5: snprintf(col_mnt, sizeof(col_mnt), "%s", result); break; } if ((sep != -1) && (i == sep + 1)) snprintf(col_fs, sizeof(col_fs), "%s", result); if ((sep != -1) && (i == sep + 3)) snprintf(col_opt, sizeof(col_opt), "%s", result); result = strtok_r(NULL, delims, &saveptr); } msgprintf(MSG_DEBUG1, "mountinfo entry: major=[%ld] minor=[%ld] filesys=[%s] col_opt=[%s] col_mnt=[%s]\n", major, minor, col_fs, col_opt, col_mnt); if ((major==major(devstat.st_rdev)) && (minor==minor(devstat.st_rdev))) { if (generic_get_spacestats(devname, col_mnt, temp, sizeof(temp))==0) { msgprintf(MSG_DEBUG1, "found mountinfo entry for device=[%s]: mnt=[%s] fs=[%s] opt=[%s]\n", devname, col_mnt, col_fs, col_opt); *readwrite=generic_get_fsrwstatus(col_opt); snprintf(mntbuf, maxmntbuf, "%s", col_mnt); snprintf(optbuf, maxoptbuf, "%s", col_opt); snprintf(fsbuf, maxfsbuf, "%s", col_fs); fclose(f); return 0; } } } } fclose(f); } // ---- 2. if there is no /proc/self/mountinfo then use "/proc/mounts" instead // workaround for systems not having the "/dev/root" node entry. // There are systems showing "/dev/root" in "/proc/mounts" instead // of the actual root partition such as "/dev/sda1". // The consequence is that fsarchiver won't be able to realize // that the device it is archiving (such as "/dev/sda1") is the // same as "/dev/root" and that it is actually mounted. This // function would then say that the "/dev/sda1" device is not mounted // and fsarchiver would try to mount it and mount() fails with EBUSY if (stat64(devname, &devstat)==0 && stat64("/", &rootstat)==0 && (devstat.st_rdev==rootstat.st_dev)) { devisroot=true; msgprintf(MSG_VERB1, "device [%s] is the root device\n", devname); } // 2. check device in "/proc/mounts" (typical case) if ((f=fopen("/proc/mounts","rb"))==NULL) { sysprintf("Cannot open /proc/mounts\n"); return 1; } while(!feof(f)) { if (stream_readline(f, line, 1024)>1) { result=strtok_r(line, delims, &saveptr); col_dev[0]=col_mnt[0]=col_fs[0]=col_opt[0]=0; for(i=0; result != NULL && i<=3; i++) { switch (i) // only the second word is a mount-point { case 0: snprintf(col_dev, sizeof(col_dev), "%s", result); break; case 1: snprintf(col_mnt, sizeof(col_mnt), "%s", result); break; case 2: snprintf(col_fs, sizeof(col_fs), "%s", result); break; case 3: snprintf(col_opt, sizeof(col_opt), "%s", result); break; } result = strtok_r(NULL, delims, &saveptr); } if ((devisroot==true) && (strcmp(col_mnt, "/")==0) && (strcmp(col_fs, "rootfs")!=0)) snprintf(col_dev, sizeof(col_dev), "%s", devname); msgprintf(MSG_DEBUG1, "mount entry: col_dev=[%s] col_mnt=[%s] col_fs=[%s] col_opt=[%s]\n", col_dev, col_mnt, col_fs, col_opt); if (devcmp(col_dev, devname)==0) { if (generic_get_spacestats(col_dev, col_mnt, temp, sizeof(temp))==0) { msgprintf(MSG_DEBUG1, "found mount entry for device=[%s]: mnt=[%s] fs=[%s] opt=[%s]\n", devname, col_mnt, col_fs, col_opt); *readwrite=generic_get_fsrwstatus(col_opt); snprintf(mntbuf, maxmntbuf, "%s", col_mnt); snprintf(optbuf, maxoptbuf, "%s", col_opt); snprintf(fsbuf, maxfsbuf, "%s", col_fs); fclose(f); return 0; } } } } fclose(f); return -1; }