strcpy(mdi->sys_name, devnm);
}
-
struct mdinfo *sysfs_read(int fd, char *devnm, unsigned long options)
{
char fname[PATH_MAX];
n = write(fd, val, strlen(val));
close(fd);
if (n != strlen(val)) {
- dprintf(Name ": failed to write '%s' to '%s' (%s)\n",
- val, fname, strerror(errno));
+ dprintf("%s: failed to write '%s' to '%s' (%s)\n",
+ Name, val, fname, strerror(errno));
return -1;
}
return 0;
n = write(fd, event, strlen(event));
close(fd);
if (n != (int)strlen(event)) {
- dprintf(Name ": failed to write '%s' to '%s' (%s)\n",
- event, fname, strerror(errno));
+ dprintf("%s: failed to write '%s' to '%s' (%s)\n",
+ Name, event, fname, strerror(errno));
return -1;
}
return 0;
-}
+}
int sysfs_attribute_available(struct mdinfo *sra, struct mdinfo *dev, char *name)
{
return n;
}
+int sysfs_fd_get_two(int fd, unsigned long long *v1, unsigned long long *v2)
+{
+ /* two numbers in this sysfs file, either
+ * NNN (NNN)
+ * or
+ * NNN / NNN
+ */
+ char buf[80];
+ int n;
+ char *ep, *ep2;
+
+ lseek(fd, 0, 0);
+ n = read(fd, buf, sizeof(buf));
+ if (n <= 0)
+ return -2;
+ buf[n] = 0;
+ *v1 = strtoull(buf, &ep, 0);
+ if (ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' '))
+ return -1;
+ while (*ep == ' ' || *ep == '/' || *ep == '(')
+ ep++;
+ *v2 = strtoull(ep, &ep2, 0);
+ if (ep2 == ep || (*ep2 != 0 && *ep2 != '\n' && *ep2 != ' ' && *ep2 != ')')) {
+ *v2 = *v1;
+ return 1;
+ }
+ return 2;
+}
+
+int sysfs_get_two(struct mdinfo *sra, struct mdinfo *dev,
+ char *name, unsigned long long *v1, unsigned long long *v2)
+{
+ int n;
+ int fd;
+
+ fd = sysfs_get_fd(sra, dev, name);
+ if (fd < 0)
+ return -1;
+ n = sysfs_fd_get_two(fd, v1, v2);
+ close(fd);
+ return n;
+}
+
int sysfs_fd_get_str(int fd, char *val, int size)
{
int n;
return rv;
memset(nm, 0, sizeof(nm));
- dname = devid2devnm(makedev(sd->disk.major, sd->disk.minor));
+ dname = devid2kname(makedev(sd->disk.major, sd->disk.minor));
strcpy(sd->sys_name, "dev-");
strcpy(sd->sys_name+4, dname);
return 0;
}
-
int sysfs_unique_holder(char *devnm, long rdev)
{
/* Check that devnm is a holder of rdev,
if (strcmp(buf, "frozen\n") == 0)
/* Already frozen */
return 0;
- if (strcmp(buf, "idle\n") != 0)
+ if (strcmp(buf, "idle\n") != 0 && strcmp(buf, "recover\n") != 0)
return -1;
if (sysfs_set_str(sra, NULL, "sync_action", "frozen") < 0)
return 0;
return 1;
}
+
+int sysfs_wait(int fd, int *msec)
+{
+ /* Wait up to '*msec' for fd to have an exception condition.
+ * if msec == NULL, wait indefinitely.
+ */
+ fd_set fds;
+ int n;
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ if (msec == NULL)
+ n = select(fd+1, NULL, NULL, &fds, NULL);
+ else if (*msec < 0)
+ n = 0;
+ else {
+ struct timeval start, end, tv;
+ gettimeofday(&start, NULL);
+ if (*msec < 1000) {
+ tv.tv_sec = 0;
+ tv.tv_usec = (*msec)*1000;
+ } else {
+ tv.tv_sec = (*msec)/1000;
+ tv.tv_usec = 0;
+ }
+ n = select(fd+1, NULL, NULL, &fds, &tv);
+ gettimeofday(&end, NULL);
+ end.tv_sec -= start.tv_sec;
+ *msec -= (end.tv_sec * 1000 + end.tv_usec/1000
+ - start.tv_usec/1000) + 1;
+ }
+ return n;
+}