示例#1
0
svn_error_t *
svn_stream_readline(svn_stream_t *stream,
                    svn_stringbuf_t **stringbuf,
                    const char *eol,
                    svn_boolean_t *eof,
                    apr_pool_t *pool)
{
  return svn_error_trace(stream_readline(stringbuf, eof, eol, stream,
                                         pool));
}
int get_partlist(struct s_devinfo *blkdev, int maxblkdev, int *diskcount, int *partcount)
{
    struct s_devinfo blkdev1[FSA_MAX_BLKDEVICES];
    struct s_devinfo tmpdev;
    int best; // index of the best item found in old array
    int pos=0; // pos of latest item in new array
    char devname[1024];
    char longname[1024];
    char delims[]=" \t\n";
    char line[1024];
    char *saveptr;
    char *result;
    char major[256];
    char minor[256];
    FILE *fpart;
    int count=0;
    int i, j;
    
    // init
    *diskcount=0;
    *partcount=0;
    
    // browse list in "/proc/partitions"
    if ((fpart=fopen("/proc/partitions","rb"))==NULL)
        return -1;
    while(!feof(fpart) && (count < FSA_MAX_BLKDEVICES) && (count < maxblkdev))
    {
        if (stream_readline(fpart, line, sizeof(line))>1)
        {
            minor[0]=major[0]=0;
            devname[0]=0;
            result=strtok_r(line, delims, &saveptr);
            
            for(i=0; result != NULL && i<=4; i++)
            {
                switch(i)
                {
                    case 0: // col0 = major
                        snprintf(major, sizeof(major), "%s", result);
                        break;
                    case 1: // col1 = minor
                        snprintf(minor, sizeof(minor), "%s", result);
                        break;
                    case 3: // col3 = devname
                        snprintf(devname, sizeof(devname), "%s", result);
                        break;
                }
                result = strtok_r(NULL, delims, &saveptr);
            }
            
            // ignore invalid entries
            if ((strlen(devname)==0) || (atoi(major)==0 && atoi(minor)==0))
                continue;
            snprintf(longname, sizeof(longname), "/dev/%s", devname);
            if (get_devinfo(&tmpdev, longname, atoi(minor), atoi(major))!=0)
               continue; // to to the next part
            
            // check that this device is not already in the list
            for (i=0; i < count; i++)
                if (blkdev1[i].rdev==tmpdev.rdev)
                    continue; // to to the next part
            
            // add the device to list if it is a real device and it's not already in the list
            blkdev1[count++]=tmpdev;
        }
    }
    
    fclose(fpart);
    
    // ---- 2. sort the devices
    for (pos=0, i=0; i<count; i++)
    {
        // set best to the first available item in the old array
        for (j=0, best=-1; (j<count) && (best==-1); j++)
            if (blkdev1[j].rdev!=0)
                best=j;
        // find the index of the best item in the old array
        for (j=0; j<count; j++)
            if ((blkdev1[j].rdev > 0) && (blkdev1[j].rdev < blkdev1[best].rdev))
                best=j;
        // update counters
        switch (blkdev1[best].devtype)
        {
            case BLKDEV_FILESYSDEV:
                (*partcount)++;
                break;
            case BLKDEV_PHYSDISK:
                (*diskcount)++;
                break;                
        }
        // move item to the new array
        blkdev[pos++]=blkdev1[best];
        blkdev1[best].rdev=0;
    }

    return count;
}
示例#3
0
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;
}